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