From 5a3ce30811ac2a305c2c5de35298aaeec54de82f Mon Sep 17 00:00:00 2001 From: Lucas Teixeira Date: Thu, 3 Sep 2020 21:06:43 -0300 Subject: [PATCH 1/3] WJ-17 - New: Favorite list; WJ-17 - Update: Refactoring Movie container to component; --- .../Movie/dtos/index.ts | 0 .../Movie/index.tsx | 0 .../Movie/styles.ts | 0 src/containers/MovieList/index.tsx | 2 +- src/containers/index.ts | 2 +- src/domains/Favorites/api/List/RawResponse.ts | 7 ++++ src/domains/Favorites/api/List/Response.ts | 5 +++ src/domains/Favorites/api/List/index.ts | 34 +++++++++++++++ src/domains/Favorites/api/index.ts | 1 + src/domains/Favorites/dtos/ContextData.ts | 7 ++++ src/domains/Favorites/dtos/FavoritesState.ts | 4 ++ src/domains/Favorites/hooks/index.tsx | 42 +++++++++++++++++++ src/screens/Home/index.tsx | 7 ++++ 13 files changed, 109 insertions(+), 2 deletions(-) rename src/{containers => components}/Movie/dtos/index.ts (100%) rename src/{containers => components}/Movie/index.tsx (100%) rename src/{containers => components}/Movie/styles.ts (100%) create mode 100644 src/domains/Favorites/api/List/RawResponse.ts create mode 100644 src/domains/Favorites/api/List/Response.ts create mode 100644 src/domains/Favorites/api/List/index.ts create mode 100644 src/domains/Favorites/api/index.ts create mode 100644 src/domains/Favorites/dtos/ContextData.ts create mode 100644 src/domains/Favorites/dtos/FavoritesState.ts create mode 100644 src/domains/Favorites/hooks/index.tsx diff --git a/src/containers/Movie/dtos/index.ts b/src/components/Movie/dtos/index.ts similarity index 100% rename from src/containers/Movie/dtos/index.ts rename to src/components/Movie/dtos/index.ts diff --git a/src/containers/Movie/index.tsx b/src/components/Movie/index.tsx similarity index 100% rename from src/containers/Movie/index.tsx rename to src/components/Movie/index.tsx diff --git a/src/containers/Movie/styles.ts b/src/components/Movie/styles.ts similarity index 100% rename from src/containers/Movie/styles.ts rename to src/components/Movie/styles.ts diff --git a/src/containers/MovieList/index.tsx b/src/containers/MovieList/index.tsx index b354df4..f611ab0 100644 --- a/src/containers/MovieList/index.tsx +++ b/src/containers/MovieList/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Wrapper } from 'components/Layout'; -import Movie from 'containers/Movie'; +import Movie from 'components/Movie'; import { Container, Title, ListContainer, ListContent } from './styles'; import Props from './dtos'; diff --git a/src/containers/index.ts b/src/containers/index.ts index ad4923d..1f35ed1 100644 --- a/src/containers/index.ts +++ b/src/containers/index.ts @@ -1,5 +1,5 @@ export { default as Footer } from './Footer'; export { default as Header } from './Header'; export { default as Highlights } from './Highlights'; -export { default as Movie } from './Movie'; +export { default as Movie } from '../components/Movie'; export { default as MovieList } from './MovieList'; diff --git a/src/domains/Favorites/api/List/RawResponse.ts b/src/domains/Favorites/api/List/RawResponse.ts new file mode 100644 index 0000000..b82be9e --- /dev/null +++ b/src/domains/Favorites/api/List/RawResponse.ts @@ -0,0 +1,7 @@ +export default interface RawResponse { + id: string; + user_id: string; + movie_id: string; + created_at: string; + updated_at: string; +} diff --git a/src/domains/Favorites/api/List/Response.ts b/src/domains/Favorites/api/List/Response.ts new file mode 100644 index 0000000..e9a5bb8 --- /dev/null +++ b/src/domains/Favorites/api/List/Response.ts @@ -0,0 +1,5 @@ +export default interface Response { + id: string; + userId: string; + movieId: string; +} diff --git a/src/domains/Favorites/api/List/index.ts b/src/domains/Favorites/api/List/index.ts new file mode 100644 index 0000000..f56a44c --- /dev/null +++ b/src/domains/Favorites/api/List/index.ts @@ -0,0 +1,34 @@ +import api from 'services/api'; + +import RawResponse from 'domains/Favorites/api/List/RawResponse'; +import Response from 'domains/Favorites/api/List/Response'; + +const Favorites = async (): Promise => { + const response = await rawFavorites(); + + return parseResponse(response); +}; + +export const rawFavorites = async (): Promise => { + const response = await api.get('/favorites'); + + return response.data; +}; + +const parseResponse = (rawResponse: RawResponse[]): Response[] => { + let response = [] as Response[]; + + rawResponse.forEach(favorite => { + const parsedFavorite = { + id: favorite.id, + userId: favorite.user_id, + movieId: favorite.movie_id, + } as Response; + + response = [...response, parsedFavorite]; + }); + + return response; +}; + +export default Favorites; diff --git a/src/domains/Favorites/api/index.ts b/src/domains/Favorites/api/index.ts new file mode 100644 index 0000000..6a0f2da --- /dev/null +++ b/src/domains/Favorites/api/index.ts @@ -0,0 +1 @@ +export { default as Favorites } from './List'; diff --git a/src/domains/Favorites/dtos/ContextData.ts b/src/domains/Favorites/dtos/ContextData.ts new file mode 100644 index 0000000..318f645 --- /dev/null +++ b/src/domains/Favorites/dtos/ContextData.ts @@ -0,0 +1,7 @@ +// import LoginCredentials from './LoginCredentials'; + +export default interface ContextData { + user?: object; + // login(loginCredentials: LoginCredentials): Promise; + // logout(): void; +} diff --git a/src/domains/Favorites/dtos/FavoritesState.ts b/src/domains/Favorites/dtos/FavoritesState.ts new file mode 100644 index 0000000..a91157c --- /dev/null +++ b/src/domains/Favorites/dtos/FavoritesState.ts @@ -0,0 +1,4 @@ +export default interface FavoritesState { + token?: string; + user?: object; +} diff --git a/src/domains/Favorites/hooks/index.tsx b/src/domains/Favorites/hooks/index.tsx new file mode 100644 index 0000000..a2fc82d --- /dev/null +++ b/src/domains/Favorites/hooks/index.tsx @@ -0,0 +1,42 @@ +import React, { createContext, useCallback, useContext, useState } from 'react'; +import api from 'services/api'; + +// import { postRawFavorites } from 'domains/Favorites/api/PostFavorites'; +import ContextData from '../dtos/ContextData'; +import FavoritesState from '../dtos/FavoritesState'; + +const FavoritesContext = createContext({} as ContextData); + +const FavoritesProvider: React.FC = ({ children }) => { + const [data, setData] = useState(() => { + return {} as FavoritesState; + }); + + // const update = useCallback(async ({ movieId }): Promise => { + // const response = await updateFavorites({ movieId }); + + // if (response) { + // setData({ ...data, response }); + // return; + // } + + // const newData = data.filter(favorite => favorite) + + // }, []); + + return ( + {children} + ); +}; + +function useFavorites(): ContextData { + const context = useContext(FavoritesContext); + + if (!context) { + throw new Error('useFavorites must be used within an FavoritesProvider.'); + } + + return context; +} + +export { FavoritesProvider, useFavorites }; diff --git a/src/screens/Home/index.tsx b/src/screens/Home/index.tsx index 3ef1786..cc5f3cf 100644 --- a/src/screens/Home/index.tsx +++ b/src/screens/Home/index.tsx @@ -1,7 +1,9 @@ import React, { useEffect, useState } from 'react'; import { NowPlaying, Popular } from 'domains/Movie/api'; +import { Favorites } from 'domains/Favorites/api'; import MovieResponse from 'domains/Movie/api/Popular/Response'; +import FavoriteResponse from 'domains/Favorites/api/List/Response'; import { ColumnLayout } from 'components/Layout'; import { Footer, Header, Highlights, MovieList } from 'containers'; @@ -10,10 +12,15 @@ import { HeaderBackground, ContentContainer } from './styles'; const Home: React.FC = () => { const [popularList, setPopularList] = useState([] as MovieResponse[]); const [nowPlayingList, setNowPlayingList] = useState([] as MovieResponse[]); + const [favoriteList, setFavoriteList] = useState([] as FavoriteResponse[]); useEffect(() => { NowPlaying().then(response => setNowPlayingList(response)); Popular().then(response => setPopularList(response)); + Favorites().then(response => { + console.log('response', response); + setFavoriteList(response); + }); }, []); return ( From 1301f059db4d9e325cd14d22800e6ed3d0535b8a Mon Sep 17 00:00:00 2001 From: Lucas Teixeira Date: Fri, 4 Sep 2020 21:13:44 -0300 Subject: [PATCH 2/3] WJ-17 - New: Get favorite list; WJ-17 - New: Get movie details; WJ-17 - New: Merge favorite and details; --- src/domains/Favorites/api/List/RawResponse.ts | 2 +- src/domains/Favorites/api/List/Response.ts | 6 ++- src/domains/Favorites/api/List/index.ts | 21 ++++++++-- src/domains/Favorites/dtos/ContextData.ts | 7 ---- src/domains/Favorites/dtos/FavoritesState.ts | 4 -- src/domains/Favorites/hooks/index.tsx | 42 ------------------- src/domains/Movie/api/Details/RawResponse.ts | 21 ++++++++++ src/domains/Movie/api/Details/Response.ts | 19 +++++++++ src/domains/Movie/api/Details/index.ts | 40 ++++++++++++++++++ src/domains/Movie/api/index.ts | 1 + src/screens/Home/index.tsx | 1 + 11 files changed, 104 insertions(+), 60 deletions(-) delete mode 100644 src/domains/Favorites/dtos/ContextData.ts delete mode 100644 src/domains/Favorites/dtos/FavoritesState.ts delete mode 100644 src/domains/Favorites/hooks/index.tsx create mode 100644 src/domains/Movie/api/Details/RawResponse.ts create mode 100644 src/domains/Movie/api/Details/Response.ts create mode 100644 src/domains/Movie/api/Details/index.ts diff --git a/src/domains/Favorites/api/List/RawResponse.ts b/src/domains/Favorites/api/List/RawResponse.ts index b82be9e..adb1f95 100644 --- a/src/domains/Favorites/api/List/RawResponse.ts +++ b/src/domains/Favorites/api/List/RawResponse.ts @@ -1,7 +1,7 @@ export default interface RawResponse { id: string; user_id: string; - movie_id: string; + movie_id: number; created_at: string; updated_at: string; } diff --git a/src/domains/Favorites/api/List/Response.ts b/src/domains/Favorites/api/List/Response.ts index e9a5bb8..b7a4954 100644 --- a/src/domains/Favorites/api/List/Response.ts +++ b/src/domains/Favorites/api/List/Response.ts @@ -1,5 +1,7 @@ -export default interface Response { +import DetailsResponse from 'domains/Movie/api/Details/Response'; + +export default interface Response extends Omit { id: string; userId: string; - movieId: string; + movieId: number; } diff --git a/src/domains/Favorites/api/List/index.ts b/src/domains/Favorites/api/List/index.ts index f56a44c..0152d8f 100644 --- a/src/domains/Favorites/api/List/index.ts +++ b/src/domains/Favorites/api/List/index.ts @@ -2,6 +2,7 @@ import api from 'services/api'; import RawResponse from 'domains/Favorites/api/List/RawResponse'; import Response from 'domains/Favorites/api/List/Response'; +import { Details } from 'domains/Movie/api'; const Favorites = async (): Promise => { const response = await rawFavorites(); @@ -15,20 +16,32 @@ export const rawFavorites = async (): Promise => { return response.data; }; -const parseResponse = (rawResponse: RawResponse[]): Response[] => { - let response = [] as Response[]; +const parseResponse = async ( + rawResponse: RawResponse[], +): Promise => { + let response = [] as any[]; + // Parse API user favorites rawResponse.forEach(favorite => { const parsedFavorite = { id: favorite.id, userId: favorite.user_id, movieId: favorite.movie_id, - } as Response; + }; response = [...response, parsedFavorite]; }); - return response; + // Get favorites details from TMDB API and merge + const parsedResponse = response.map(async (favorite: Response) => { + const details = await Details(favorite.movieId); + + return { ...details, ...favorite, id: favorite.id }; + }); + + const resolvedResponse = await Promise.all(parsedResponse); + + return resolvedResponse; }; export default Favorites; diff --git a/src/domains/Favorites/dtos/ContextData.ts b/src/domains/Favorites/dtos/ContextData.ts deleted file mode 100644 index 318f645..0000000 --- a/src/domains/Favorites/dtos/ContextData.ts +++ /dev/null @@ -1,7 +0,0 @@ -// import LoginCredentials from './LoginCredentials'; - -export default interface ContextData { - user?: object; - // login(loginCredentials: LoginCredentials): Promise; - // logout(): void; -} diff --git a/src/domains/Favorites/dtos/FavoritesState.ts b/src/domains/Favorites/dtos/FavoritesState.ts deleted file mode 100644 index a91157c..0000000 --- a/src/domains/Favorites/dtos/FavoritesState.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default interface FavoritesState { - token?: string; - user?: object; -} diff --git a/src/domains/Favorites/hooks/index.tsx b/src/domains/Favorites/hooks/index.tsx deleted file mode 100644 index a2fc82d..0000000 --- a/src/domains/Favorites/hooks/index.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React, { createContext, useCallback, useContext, useState } from 'react'; -import api from 'services/api'; - -// import { postRawFavorites } from 'domains/Favorites/api/PostFavorites'; -import ContextData from '../dtos/ContextData'; -import FavoritesState from '../dtos/FavoritesState'; - -const FavoritesContext = createContext({} as ContextData); - -const FavoritesProvider: React.FC = ({ children }) => { - const [data, setData] = useState(() => { - return {} as FavoritesState; - }); - - // const update = useCallback(async ({ movieId }): Promise => { - // const response = await updateFavorites({ movieId }); - - // if (response) { - // setData({ ...data, response }); - // return; - // } - - // const newData = data.filter(favorite => favorite) - - // }, []); - - return ( - {children} - ); -}; - -function useFavorites(): ContextData { - const context = useContext(FavoritesContext); - - if (!context) { - throw new Error('useFavorites must be used within an FavoritesProvider.'); - } - - return context; -} - -export { FavoritesProvider, useFavorites }; diff --git a/src/domains/Movie/api/Details/RawResponse.ts b/src/domains/Movie/api/Details/RawResponse.ts new file mode 100644 index 0000000..91f6e41 --- /dev/null +++ b/src/domains/Movie/api/Details/RawResponse.ts @@ -0,0 +1,21 @@ +export default interface RawResponse { + poster_path?: string; + budget: number; + overview: string; + release_date: string; + genres: [ + { + id: number; + name: string; + }, + ]; + id: number; + original_title: string; + original_language: string; + title: string; + backdrop_path?: string; + popularity: number; + vote_count: number; + video: boolean; + vote_average: number; +} diff --git a/src/domains/Movie/api/Details/Response.ts b/src/domains/Movie/api/Details/Response.ts new file mode 100644 index 0000000..7f186ac --- /dev/null +++ b/src/domains/Movie/api/Details/Response.ts @@ -0,0 +1,19 @@ +export default interface Response { + poster?: string; + backdrop?: string; + budget: number; + overview: string; + releaseDate: string; + genres: [ + { + id: number; + name: string; + }, + ]; + id: number; + originalTitle: string; + title: string; + popularity: number; + voteCount: number; + voteAverage: number; +} diff --git a/src/domains/Movie/api/Details/index.ts b/src/domains/Movie/api/Details/index.ts new file mode 100644 index 0000000..b1b092a --- /dev/null +++ b/src/domains/Movie/api/Details/index.ts @@ -0,0 +1,40 @@ +import tmdb from 'services/api/tmdb'; + +import RawResponse from 'domains/Movie/api/Details/RawResponse'; +import Response from 'domains/Movie/api/Details/Response'; +import formatDate from 'shared/utils/formatDate'; +import formatTmdbImage from 'shared/utils/formatTmdbImage'; + +const Details = async (movieId: number): Promise => { + const response = await rawPopular(movieId); + + return parseResponse(response); +}; + +export const rawPopular = async (movieId: number): Promise => { + const response = await tmdb.get(`/movie/${movieId}`); + + return response.data; +}; + +const parseResponse = (movie: RawResponse): Response => { + const parsedMovie = { + overview: movie.overview, + budget: movie.budget, + genres: movie.genres, + id: movie.id, + originalTitle: movie.original_title, + title: movie.title, + popularity: movie.popularity, + voteCount: movie.vote_count, + voteAverage: movie.vote_average, + + releaseDate: formatDate({ value: movie.release_date }), + poster: formatTmdbImage({ value: movie.poster_path }), + backdrop: formatTmdbImage({ value: movie.backdrop_path }), + } as Response; + + return parsedMovie; +}; + +export default Details; diff --git a/src/domains/Movie/api/index.ts b/src/domains/Movie/api/index.ts index 76a96a2..aeebfaa 100644 --- a/src/domains/Movie/api/index.ts +++ b/src/domains/Movie/api/index.ts @@ -1,2 +1,3 @@ +export { default as Details } from './Details'; export { default as NowPlaying } from './NowPlaying'; export { default as Popular } from './Popular'; diff --git a/src/screens/Home/index.tsx b/src/screens/Home/index.tsx index cc5f3cf..05dd9a6 100644 --- a/src/screens/Home/index.tsx +++ b/src/screens/Home/index.tsx @@ -30,6 +30,7 @@ const Home: React.FC = () => { +