From d65d9aa2e514b633d9bed52002ccd25a8b03851c Mon Sep 17 00:00:00 2001 From: yyj0917 Date: Wed, 13 Nov 2024 20:17:29 +0900 Subject: [PATCH] =?UTF-8?q?Feat=20:=20details=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EA=B5=AC=ED=98=84=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- netflix-assignment/next.config.js | 9 +++- .../content_details/[type]/[id]/page.tsx | 54 +++++++++++++++++++ .../app/(route)/details/[movie_id]/page.tsx | 0 .../(route)/home/_components/ContentRow.tsx | 27 +++++----- .../app/(route)/home/_components/Header.tsx | 14 ++--- .../app/(route)/home/_components/Preview.tsx | 6 ++- .../src/hooks/useFetchContents.ts | 10 +++- .../src/hooks/useFetchDetails.ts | 4 +- netflix-assignment/src/types/movie.ts | 1 + netflix-assignment/src/types/tvshows.ts | 1 + 10 files changed, 99 insertions(+), 27 deletions(-) create mode 100644 netflix-assignment/src/app/(route)/content_details/[type]/[id]/page.tsx delete mode 100644 netflix-assignment/src/app/(route)/details/[movie_id]/page.tsx diff --git a/netflix-assignment/next.config.js b/netflix-assignment/next.config.js index ccf2fd4..2987951 100644 --- a/netflix-assignment/next.config.js +++ b/netflix-assignment/next.config.js @@ -9,14 +9,21 @@ const nextConfig = { }, async rewrites() { return [ + // 영화 카테고리 rewrite { source: '/movie/:category', - destination: '/api/movie?category=:category', // 수정된 부분 + destination: '/api/movie?category=:category', }, + // TV 카테고리 rewrite { source: '/tv/:category', destination: '/api/tv?category=:category', // 수정된 부분 }, + // 영화,상세정보 상세정보 rewrite + { + source: '/details/:type/:id', + destination: '/api/details/:type/:id', // 수정된 부분 + }, ]; }, }; diff --git a/netflix-assignment/src/app/(route)/content_details/[type]/[id]/page.tsx b/netflix-assignment/src/app/(route)/content_details/[type]/[id]/page.tsx new file mode 100644 index 0000000..7e0a86f --- /dev/null +++ b/netflix-assignment/src/app/(route)/content_details/[type]/[id]/page.tsx @@ -0,0 +1,54 @@ +"use client" + +import { useFetchDetails } from "@/hooks/useFetchDetails"; +import { useEffect, useState } from "react"; +import { usePathname } from "next/navigation"; +import RightArrow from '@/assets/svg/RightArrow.svg'; + + +export default function DetailPage() { + const pathname = usePathname(); + const [type, setType] = useState<'movie' | 'tv' | null>(null); + const [id, setId] = useState(null); + + useEffect(() => { + if (pathname) { + const pathParts = pathname.split('/'); + if (pathParts.length >= 4) { + setType(pathParts[2] as 'movie' | 'tv'); + setId(pathParts[3]); + } + } + }, [pathname]); + const { data: contentDetails, isLoading } = useFetchDetails(type, id); + + if (isLoading) return

Loading...

; + if (!contentDetails) return
Detail not found
; + + return ( +
+
+ {/* 그림자 그라데이션 추가 */} +
+
+ +
+

+ {type === 'movie' ? contentDetails.title : contentDetails.name} +

+

+ {contentDetails.overview} +

+ +
+
+ ); +} diff --git a/netflix-assignment/src/app/(route)/details/[movie_id]/page.tsx b/netflix-assignment/src/app/(route)/details/[movie_id]/page.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/netflix-assignment/src/app/(route)/home/_components/ContentRow.tsx b/netflix-assignment/src/app/(route)/home/_components/ContentRow.tsx index f4b557e..181d418 100644 --- a/netflix-assignment/src/app/(route)/home/_components/ContentRow.tsx +++ b/netflix-assignment/src/app/(route)/home/_components/ContentRow.tsx @@ -1,5 +1,6 @@ "use client" +import Link from 'next/link'; import { Movie } from '@/types/movie'; import { TvShow } from '@/types/tvshows'; @@ -12,19 +13,13 @@ type Props = { export default function ContentRow({ title, content }: Props) { - if (!content || content.length === 0) return null; - const getAltText = (item: Movie | TvShow) => { - if ('title' in item) return item.title; - if ('name' in item) return item.name; - return 'No Title'; - }; - const getPrefix = (item: Movie | TvShow) => { - if ('title' in item) return 'movie'; - if ('name' in item) return 'tv'; - return 'No'; - } - + const getAltText = (item: Movie | TvShow) => + 'title' in item ? item.title : 'name' in item ? item.name : 'No Title'; + + const getPrefix = (item: Movie | TvShow) => + 'title' in item ? 'movie' : 'name' in item ? 'tv' : 'No'; + return ( @@ -32,13 +27,17 @@ export default function ContentRow({ title, content }: Props) {

{title}

{content.map((item) => ( -
+ {getAltText(item)} -
+ ))}
diff --git a/netflix-assignment/src/app/(route)/home/_components/Header.tsx b/netflix-assignment/src/app/(route)/home/_components/Header.tsx index 63fee71..243cf64 100644 --- a/netflix-assignment/src/app/(route)/home/_components/Header.tsx +++ b/netflix-assignment/src/app/(route)/home/_components/Header.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from "react"; import { Movie } from "@/types/movie"; import Top10 from "../../../../assets/svg/Top10.svg"; import { useFetchAllMovies } from "@/hooks/useFetchContents"; +import Link from "next/link"; export default function Header() { const { data: movies, isLoading } = useFetchAllMovies(); @@ -31,21 +32,22 @@ export default function Header() { return ( -
{/* 그림자 그라데이션 추가 */}
- - - #{randomIndex+1} in Korea Today - + + + #{randomIndex+1} in Korea Today +
-
+ ); } diff --git a/netflix-assignment/src/app/(route)/home/_components/Preview.tsx b/netflix-assignment/src/app/(route)/home/_components/Preview.tsx index 7300ac6..de1d647 100644 --- a/netflix-assignment/src/app/(route)/home/_components/Preview.tsx +++ b/netflix-assignment/src/app/(route)/home/_components/Preview.tsx @@ -3,6 +3,7 @@ import { Movie } from '../../../../types/movie'; import { TvShow } from '@/types/tvshows'; import { useFetchAllMovies, useFetchAllTvShows } from '@/hooks/useFetchContents'; +import Link from 'next/link'; export default function Preview() { const { data: movies } = useFetchAllMovies(); @@ -31,8 +32,9 @@ export default function Preview() {

Previews

{randomContent.map((item, index) => ( -
-
+ ))}
diff --git a/netflix-assignment/src/hooks/useFetchContents.ts b/netflix-assignment/src/hooks/useFetchContents.ts index ec457d9..7500506 100644 --- a/netflix-assignment/src/hooks/useFetchContents.ts +++ b/netflix-assignment/src/hooks/useFetchContents.ts @@ -5,12 +5,18 @@ import { TvShow } from '@/types/tvshows'; const fetchMoviesByCategory = async (category: string): Promise => { const response = await axios.get(`/movie/${category}`); - return response.data; + return response.data.map((movie: Movie) => ({ + ...movie, + media_type: 'movie', // 수동으로 media_type 추가 + })); }; const fetchTvShowsByCategory = async (category: string): Promise => { const response = await axios.get(`/tv/${category}`); - return response.data; + return response.data.map((tvShow: TvShow) => ({ + ...tvShow, + media_type: 'tv', // 수동으로 media_type 추가 + })); }; // 모든 카테고리의 영화를 가져오는 함수 diff --git a/netflix-assignment/src/hooks/useFetchDetails.ts b/netflix-assignment/src/hooks/useFetchDetails.ts index 7eb24c7..10651f4 100644 --- a/netflix-assignment/src/hooks/useFetchDetails.ts +++ b/netflix-assignment/src/hooks/useFetchDetails.ts @@ -1,12 +1,12 @@ import { useQuery } from '@tanstack/react-query'; import axios from 'axios'; -const fetchDetails = async (type: string, id: string) => { +const fetchDetails = async (type: string | null, id: string | null) => { const response = await axios.get(`/details/${type}/${id}`); return response.data; }; -export const useFetchDetails = (type: 'movie' | 'tv', id: string) => { +export const useFetchDetails = (type: 'movie' | 'tv' | null, id: string | null) => { return useQuery({ queryKey: ['details', type, id], queryFn: () => fetchDetails(type, id), diff --git a/netflix-assignment/src/types/movie.ts b/netflix-assignment/src/types/movie.ts index 7de62b8..c0c1f10 100644 --- a/netflix-assignment/src/types/movie.ts +++ b/netflix-assignment/src/types/movie.ts @@ -13,5 +13,6 @@ export type Movie = { vote_count: number; adult: boolean; video: boolean; + media_type: string; }; \ No newline at end of file diff --git a/netflix-assignment/src/types/tvshows.ts b/netflix-assignment/src/types/tvshows.ts index ce500d5..1ac3d64 100644 --- a/netflix-assignment/src/types/tvshows.ts +++ b/netflix-assignment/src/types/tvshows.ts @@ -13,5 +13,6 @@ export type TvShow = { vote_average: number; vote_count: number; adult: boolean; + media_type: string; }; \ No newline at end of file