Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refatorado o código da home page #20

Merged
merged 11 commits into from
May 8, 2023
Merged
83 changes: 83 additions & 0 deletions src/ui/Pages/Home/AllAnimes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from "react";

import { Box, Grid, Pagination, Skeleton, Typography } from "@mui/material";
import { Card } from "../../../Components/Card";
import { AnimeModel } from "../../../../domain/useCases/AnimeUseCases/Models/AnimeModels";

interface IAllAnimesProps {
animes: AnimeModel[];
paginationData: {
page: number;
totalOfPages: number;
};
onPageChange: (event: React.ChangeEvent<unknown>, page: number) => void;
loading: boolean;
}
export function AllAnimes({
animes,
paginationData,
onPageChange,
loading
}: IAllAnimesProps) {
return (
<Box>
{loading ? (
<Skeleton
height={"1607px"}
variant="rectangular"
sx={{ borderRadius: "18px" }}
id="animes"
/>
) : (
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: "1rem",
marginTop: "18px",
}}
>
<Typography variant="h5" fontWeight={700}>
Animes
</Typography>
<Grid
container
spacing={4}
rowSpacing={8}
columnSpacing={20}
columns={32}
id="animes"
sx={{ scrollBehavior: "smooth", marginTop: "18px" }}
>
{animes.map(({ name, episodes, photo, descrition }, index) => (
<Grid item key={index} xs={8} sx={{ maxWidth: "255px" }}>
<Card
animeName={name}
animeEpisodesQtde={episodes}
animePhoto={photo}
/>
</Grid>
))}
</Grid>
</Box>
)}
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
marginTop: "3rem",
}}
>
<a href="#top" style={{ textDecoration: "none" }}>
<Pagination
page={paginationData.page}
count={paginationData.totalOfPages}
color="primary"
onChange={(e, page) => onPageChange(e, page)}
/>
</a>
</Box>
</Box>
);
}
133 changes: 133 additions & 0 deletions src/ui/Pages/Home/TrendingAnimes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import React from "react";

// Components

import { Box, Button, Skeleton, Typography } from "@mui/material";
import { Card } from "../../../Components/Card";

//

// icons

import { ArrowRight } from "@phosphor-icons/react";

//

// Hook

import { useTrendingAnimes } from "./useTrendingAnimes";

//

interface ITrendingAnimesProps {
onResetAction: () => void;
}
export function TrendingAnimes({ onResetAction }: ITrendingAnimesProps) {
const { actions, states, visualElements } = useTrendingAnimes();

return (
<Box sx={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
<Box
sx={{
display: "flex",
flexDirection: "row",
gap: "2rem",
alignItems: "center",
}}
>
<Typography variant="h1" color="#4361ee">
My Anime List
</Typography>
<Box
sx={{
height: "100px",
borderRadius: "55px",
}}
>
{!visualElements.characterPhoto.trim() ? (
<Skeleton
sx={{ borderRadius: "33px", width: "156px", height: "100px" }}
/>
) : (
<img
src={visualElements.characterPhoto}
style={{
objectFit: "fill",
width: "156px",
height: "100px",
borderRadius: "55px",
}}
/>
)}
</Box>
</Box>
<Box
sx={{
marginTop: "2rem",
display: "flex",
flexDirection: "column",
gap: "1rem",
}}
>
<Typography variant="h5" fontWeight={700}>
Trending
</Typography>
<Box
sx={{
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}}
>
{visualElements.trendingAnimes.map(
({ name, photo, episodes, descrition }, index) => (
<Card
animeName={name}
animeEpisodesQtde={episodes}
animePhoto={photo}
key={index}
/>
)
)}
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
marginTop: "2rem",
}}
>
<a href="#animes" style={{ textDecoration: "none", width: "15%" }}>
<Button
sx={{
height: "25px",
backgroundColor: "#d7d7d7",
padding: "1.8rem",
color: "black",
width: "100%",
display: "flex",
justifyContent: "space-between",
borderRadius: "55px",
textTransform: "none",
fontWeight: "700",
fontSize: "16px",
"&:hover": {
backgroundColor: "#4361ee",
color: "#ffff",
},
}}
onClick={() => {
onResetAction();
}}
>
View All Anime
<ArrowRight size={"16px"} />
</Button>
</a>
</Box>
</Box>
);
}
100 changes: 100 additions & 0 deletions src/ui/Pages/Home/TrendingAnimes/useTrendingAnimes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React, { useEffect, useState } from "react";

// service

import { RequestService } from "../../../../domain/services/requestService";

//

// repositories

import { AnimesRepository } from "../../../../data/AnimesRepository";
import { CharactersRepository } from "../../../../data/CharactersRepository";

//

// use cases

import { GetARandomCharacterUseCase } from "../../../../domain/useCases/CharacterUseCase/GetARandomCharacterUseCase";
import { GetTrendingAnimesUseCase } from "../../../../domain/useCases/AnimeUseCases/GetTrendingAnimesUseCase";

//

// Request params

import { IGetTrendingAnimeRequestParams } from "../../../../domain/useCases/AnimeUseCases/abstractions/IGetTrendingAnimesUseCase";
import { AnimeModel } from "../../../../domain/useCases/AnimeUseCases/Models/AnimeModels";

//

export function useTrendingAnimes() {
// ------------------------ Depencency injection ------------------------ //

// Http service

const httpService = new RequestService();

//

// Repositories

const charactersRepository = new CharactersRepository(httpService);
const animesRepository = new AnimesRepository(httpService);

//

// Use Cases

const getARandomCharacterUseCase = new GetARandomCharacterUseCase(
charactersRepository
);
const getTrendingAnimesUseCase = new GetTrendingAnimesUseCase(
animesRepository
);

//

// ------------------------ Depencency injection ------------------------ //

const [characterPhoto, setCharacterPhoto] = useState("");
const [trendingAnimes, setTrendingAnimes] = useState<AnimeModel[]>([]);

async function randomCharacterPhoto() {
const data = await getARandomCharacterUseCase.execute();

setCharacterPhoto(data.photo);
}

async function getTrendingAnimes() {
const params: IGetTrendingAnimeRequestParams = {
page: 1,
limit: 5,
type: "tv",
filterBy: "bypopularity",
};
const data = await getTrendingAnimesUseCase.execute(params);

setTrendingAnimes(data);
}

useEffect(() => {
if (!characterPhoto.trim()) {
randomCharacterPhoto();
}
}, []);

useEffect(() => {
if (!trendingAnimes.length || trendingAnimes === undefined) {
getTrendingAnimes();
}
}, []);

return {
states: {},
actions: {},
visualElements: {
characterPhoto,
trendingAnimes
},
};
}
Loading