Skip to content

Commit

Permalink
Feat : details 페이지 구현완료
Browse files Browse the repository at this point in the history
  • Loading branch information
yyj0917 committed Nov 13, 2024
1 parent 453fad9 commit d65d9aa
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 27 deletions.
9 changes: 8 additions & 1 deletion netflix-assignment/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', // 수정된 부분
},
];
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -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<string | null>(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 <p>Loading...</p>;
if (!contentDetails) return <div>Detail not found</div>;

return (
<div className="w-full h-full flex flex-col items-center">
<div
className="relative w-full h-[415px] bg-cover bg-center"
style={{
backgroundImage: `url(https://image.tmdb.org/t/p/original${contentDetails?.backdrop_path})`,
}}
>
{/* 그림자 그라데이션 추가 */}
<div className="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent"></div>
</div>
<button className="w-[303px] h-[45px] flex justify-center items-center gap-[15px] rounded-[5.63px] bg-[#C4C4C4] mt-[13px] text-black hover:bg-[#8C8787]">
<RightArrow className='stroke-current '/>
<p className='text-[20.46px] font-semibold'>Play</p>
</button>
<div className="w-[303px] flex flex-col gap-6 mt-[22px] text-white">
<h2 className="text-[26.75px] font-bold">
{type === 'movie' ? contentDetails.title : contentDetails.name}
</h2>
<p className="text-[11.14px] font-normal line-[14.17px]">
{contentDetails.overview}
</p>

</div>
</div>
);
}
Empty file.
27 changes: 13 additions & 14 deletions netflix-assignment/src/app/(route)/home/_components/ContentRow.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client"

import Link from 'next/link';
import { Movie } from '@/types/movie';
import { TvShow } from '@/types/tvshows';

Expand All @@ -12,33 +13,31 @@ 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 (
<section className='w-full h-[191px] mt-[22px]'>
<h2 className="text-[20.92px] font-bold mb-[14px]">{title}</h2>
<div className="flex overflow-x-scroll scrollbar-hide gap-[7px]">
{content.map((item) => (
<div key={`${getPrefix(item)}-${item.id}`} className="w-[103px] h-[161px] flex-shrink-0 rounded-[2px]">
<Link
key={`${getPrefix(item)}-${item.id}`}
href={`/content_details/${getPrefix(item)}/${item.id}`}
className="w-[103px] h-[161px] flex-shrink-0 rounded-[2px] cursor-pointer"
>
<img
src={`https://image.tmdb.org/t/p/w300${item.poster_path}`}
alt={getAltText(item)}
className="w-full h-full object-cover rounded-lg"
/>
</div>
</Link>
))}
</div>
</section>
Expand Down
14 changes: 8 additions & 6 deletions netflix-assignment/src/app/(route)/home/_components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -31,21 +32,22 @@ export default function Header() {


return (
<header
<Link
className="relative w-full h-[415px] bg-cover bg-center"
style={{
backgroundImage: `url(https://image.tmdb.org/t/p/original${randomMovie?.backdrop_path})`,
}}
href={`/content_details/movie/${randomMovie?.id}`}
>
{/* 그림자 그라데이션 추가 */}
<div className="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent"></div>

<div className="absolute bottom-0 left-1/2 transform -translate-x-1/2 flex justify-center items-center gap-[5px]">
<Top10/>
<span className="text-[13.72px] font-bold text-center">
#{randomIndex+1} in Korea Today
</span>
<Top10/>
<span className="text-[13.72px] font-bold text-center">
#{randomIndex+1} in Korea Today
</span>
</div>
</header>
</Link>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -31,8 +32,9 @@ export default function Preview() {
<h2 className="text-[26.75px] font-bold mb-[23px]">Previews</h2>
<article className="flex items-center overflow-x-scroll scrollbar-hide gap-[7px]">
{randomContent.map((item, index) => (
<div
<Link
key={index}
href={`/content_details/${item.media_type}/${item.id}`}
className="min-w-[102px] min-h-[102px] w-[102px] h-[102px] flex-shrink-0 overflow-hidden "
>
<img
Expand All @@ -44,7 +46,7 @@ export default function Preview() {
}
className="w-full h-full object-cover rounded-full"
/>
</div>
</Link>
))}
</article>
</section>
Expand Down
10 changes: 8 additions & 2 deletions netflix-assignment/src/hooks/useFetchContents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ import { TvShow } from '@/types/tvshows';

const fetchMoviesByCategory = async (category: string): Promise<Movie[]> => {
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<TvShow[]> => {
const response = await axios.get(`/tv/${category}`);
return response.data;
return response.data.map((tvShow: TvShow) => ({
...tvShow,
media_type: 'tv', // 수동으로 media_type 추가
}));
};

// 모든 카테고리의 영화를 가져오는 함수
Expand Down
4 changes: 2 additions & 2 deletions netflix-assignment/src/hooks/useFetchDetails.ts
Original file line number Diff line number Diff line change
@@ -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),
Expand Down
1 change: 1 addition & 0 deletions netflix-assignment/src/types/movie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export type Movie = {
vote_count: number;
adult: boolean;
video: boolean;
media_type: string;
};

1 change: 1 addition & 0 deletions netflix-assignment/src/types/tvshows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export type TvShow = {
vote_average: number;
vote_count: number;
adult: boolean;
media_type: string;
};

0 comments on commit d65d9aa

Please sign in to comment.