diff --git a/public/icons/home/icon-left-arrow.svg b/public/icons/home/icon-left-arrow.svg new file mode 100644 index 0000000..cac4411 --- /dev/null +++ b/public/icons/home/icon-left-arrow.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/app/home/page.tsx b/src/app/home/page.tsx index d2420cd..c2928ad 100644 --- a/src/app/home/page.tsx +++ b/src/app/home/page.tsx @@ -1,13 +1,22 @@ import MovieSection from "@/components/home/MovieSection"; -import { MovieCategory } from "@/types/home"; +import { getMovies } from "@/api/home"; +import { MovieCategory } from "@/types/common"; -const HomePage = () => { - const categories: MovieCategory[] = ["upcoming", "popular", "top_rated", "now_playing"]; +const HomePage = async () => { + const categories: MovieCategory[] = ["upcoming", "now_playing", "popular", "top_rated"]; + const fetchPromises = categories.map((category) => getMovies(category)); + + const moviesResults = await Promise.all(fetchPromises); + + const moviesData = categories.map((category, index) => ({ + category, + data: moviesResults[index], + })); return (
- {categories.map((category) => ( - + {moviesData.map(({ category, data }) => ( + ))}
); diff --git a/src/components/home/MovieSection.tsx b/src/components/home/MovieSection.tsx index b37327a..ce09fc2 100644 --- a/src/components/home/MovieSection.tsx +++ b/src/components/home/MovieSection.tsx @@ -1,36 +1,65 @@ -import { getMovies } from "@/api/home"; -import { movieSectionTitle } from "@/constants/movies"; +"use client"; import Image from "next/image"; import Link from "next/link"; +import { useRef } from "react"; +import { movieSectionTitle } from "@/constants/movies"; +import { MovieCategory } from "@/types/common"; +import { GetMoviesResponse } from "@/types/home"; +import ArrowIcon from "#/icons/home/icon-left-arrow.svg"; + +interface MovieSectionProps { + category: MovieCategory; + movieData: GetMoviesResponse; +} -const MovieSection = async ({ category }: { category: keyof typeof movieSectionTitle }) => { - const moviesData = await getMovies(category); - const posterBaseUrl = process.env.NEXT_POSTER_BASE_URL; +const MovieSection = ({ category, movieData }: MovieSectionProps) => { + const posterBaseUrl = process.env.NEXT_PUBLIC_POSTER_BASE_URL; - // 조건부 스타일 적용을 위한 변수 const isPreview = category === "upcoming"; - const titleStyle = isPreview ? "text-26pxr font-bold" : "text-21pxr font-bold"; // 글씨 크기 조정 - const imageWrapperStyle = isPreview ? "min-w-102pxr h-102pxr" : "min-w-103pxr h-161pxr"; // 이미지 스타일 조정 - const imageStyle = isPreview ? "rounded-full" : "rounded-sm"; // 이미지 스타일 조정 + const titleStyle = isPreview ? "text-26pxr font-bold" : "text-21pxr font-bold"; + const imageWrapperStyle = isPreview ? "min-w-102pxr h-102pxr" : "min-w-103pxr h-161pxr"; + const imageStyle = isPreview ? "rounded-full" : "rounded-sm"; + + // 스크롤을 위한 ref + const containerRef = useRef(null); + + // 슬라이더 버튼 클릭 이벤트 핸들러 + const handleScroll = (direction: "left" | "right") => { + if (containerRef.current) { + const { scrollLeft, clientWidth } = containerRef.current; + const scrollTo = direction === "left" ? scrollLeft - clientWidth : scrollLeft + clientWidth; + containerRef.current.scrollTo({ left: scrollTo, behavior: "smooth" }); + } + }; return ( -
-

{movieSectionTitle[category]}

-
- {moviesData.results.map((movie) => { - if (!movie.poster_path) return null; - return ( - - {`영화 - - ); - })} +
+ + +
+

{movieSectionTitle[category]}

+
+ {movieData.results.map((movie) => { + if (!movie.poster_path) return null; + return ( + + {`영화 + + ); + })} +
+
); }; diff --git a/src/types/svgr.d.ts b/src/types/svgr.d.ts index 3164624..3ad1ec2 100644 --- a/src/types/svgr.d.ts +++ b/src/types/svgr.d.ts @@ -1,5 +1,5 @@ -declare module '*.svg' { - import type { ReactElement, SVGProps } from 'react'; +declare module "*.svg" { + import type { ReactElement, SVGProps } from "react"; const content: (props: SVGProps & { alt: string }) => ReactElement; export default content;