diff --git a/src/app/page.tsx b/src/app/page.tsx index 563c598..0854ac9 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,7 +5,7 @@ import LandingMid from "@component/components/landing/carousel/LandingMid"; import ProjectList from "@component/components/landing/project/ProjectList"; import { Suspense, useEffect, useState } from "react"; import SignUpModal from "@component/components/signup/SignUpModal"; -import Image from "next/image"; +import useWindowSize from "@component/hooks/useWindowSize"; export default function Home() { const [isOpen, setIsOpen] = useState(false); @@ -17,33 +17,38 @@ export default function Home() { } }, []); + const { width } = useWindowSize(); + return ( // 전체 1440px -
- {/* 랜딩 문구 */} + <>
= 1460 ? "fixed left-[20%] transform-1/2-1/2" : "flex justify-center items-center min-w-[1460px] max-[1920px]"}`} > -
- -
+
+
+ {/* 랜딩 문구 */} +
- {/* 컨테이너 너비 */} -
- {/* 캐러셀 */} - - - {/* 프로젝트 */} - - -
+ {/* 컨테이너 너비 */} +
+ {/* 캐러셀 */} + + + {/* 프로젝트 */} + + +
- {isOpen && } -
+ {isOpen && } +
+ ); } diff --git a/src/components/landing/carousel/Carousel.tsx b/src/components/landing/carousel/Carousel.tsx index d7359cd..08bf901 100644 --- a/src/components/landing/carousel/Carousel.tsx +++ b/src/components/landing/carousel/Carousel.tsx @@ -1,11 +1,11 @@ "use client"; import RecommendItem from "./RecommendItem"; -import { useEffect, useState } from "react"; -import { TagProps } from "@component/components/common-components/tag"; +import { useMemo } from "react"; import Slider from "react-slick"; import "slick-carousel/slick/slick.css"; import "slick-carousel/slick/slick-theme.css"; import { useGetProjectRecommend } from "@component/hooks/useProject"; +import { RecommendDataType } from "./Carousel.types"; // 캐러셀 화살표 import ArrowBackIosNewRoundedIcon from "@mui/icons-material/ArrowBackIosNewRounded"; @@ -38,7 +38,7 @@ const settings = { slidesToShow: 3, // 화면에 한 번에 표시할 슬라이드 개수 설정 slidesToScroll: 3, // 다음 보여 줄 슬라이드의 개수 설정 speed: 2000, // 화면을 넘길 때 속도 - autoplay: false, // TODO: 자동 넘김 논의 + autoplay: false, autoplaySpeed: 5000, // 간격 nextArrow: , prevArrow: , @@ -46,32 +46,36 @@ const settings = { const Carousel = () => { const { data, error, isLoading } = useGetProjectRecommend(); - const [recommendData, setRecommendData] = useState(); - useEffect(() => { - if (data) { - setRecommendData(data.data.data) - } + const recommendData: RecommendDataType[] = useMemo(() => { + return data?.data.data ?? []; }, [data]); - if (error) { - console.log(error); + if (isLoading || error) { + return ( + + {[...Array(3)].map((_, index) => ( +
+
+
+ ))} +
+ ); } return ( <> - {recommendData?.map((item: any) => ( + {recommendData?.map((item: RecommendDataType) => ( ))} diff --git a/src/components/landing/carousel/Carousel.types.ts b/src/components/landing/carousel/Carousel.types.ts new file mode 100644 index 0000000..b4cd207 --- /dev/null +++ b/src/components/landing/carousel/Carousel.types.ts @@ -0,0 +1,13 @@ +import { TagProps } from "@component/components/common-components/tag"; + +export type RecommendDataType = { + createdAt: string; + createdBy: string; + field: TagProps["type"]; + profileImageUrl: string; + progress: TagProps["status"]; + projectId: number; + summary: string; + title: string; +} + diff --git a/src/components/landing/carousel/LandingTop.tsx b/src/components/landing/carousel/LandingTop.tsx index d9b7644..f4dfd33 100644 --- a/src/components/landing/carousel/LandingTop.tsx +++ b/src/components/landing/carousel/LandingTop.tsx @@ -40,7 +40,7 @@ const LandingTop = () => {
여러 분야의 서비스 유저로부터 유의미한 피드백을 받을 수 있어요.
- diff --git a/src/components/landing/carousel/RecommendItem.tsx b/src/components/landing/carousel/RecommendItem.tsx index 5b9cab7..15ef267 100644 --- a/src/components/landing/carousel/RecommendItem.tsx +++ b/src/components/landing/carousel/RecommendItem.tsx @@ -1,45 +1,50 @@ import Image from "next/image"; import Tag from "@component/components/common-components/tag/Tag"; import { useRouter } from "next/navigation"; +import { RecommendDataType } from "./Carousel.types"; const RecommendItem = ({ - projectId, - fields, - progress, - title, - content, - profileImg, - nickname, - createdAt, - isLoading -}: any) => { - const router = useRouter(); - return ( - <> - {isLoading ? ( -
-
- ) : ( -
{ - router.push(`/project/${projectId}`) - }} - > -
- -
{title}
-
{content}
-
- 임시 프로필 이미지 -
{nickname}
-
{createdAt}
-
-
-
- )} - - ); -} + projectId, + field, + progress, + title, + summary, + profileImageUrl, + createdBy, + createdAt, +}: RecommendDataType) => { + const router = useRouter(); + return ( + <> +
{ + router.push(`/project/${projectId}`); + }} + > +
+ +
{title}
+
{summary}
+
+ 임시 프로필 이미지 +
+ {createdBy} +
+
+ {createdAt} +
+
+
+
+ + ); +}; export default RecommendItem; diff --git a/src/hooks/useWindowSize.ts b/src/hooks/useWindowSize.ts new file mode 100644 index 0000000..f4df4d5 --- /dev/null +++ b/src/hooks/useWindowSize.ts @@ -0,0 +1,34 @@ +import { useState, useEffect } from "react"; + +interface Size { + width: number | undefined; + height: number | undefined; +} + +// Hook +function useWindowSize(): Size { + + const [windowSize, setWindowSize] = useState({ + width: undefined, + height: undefined, + }); + useEffect(() => { + + function handleResize() { + + setWindowSize({ + width: window.innerWidth, + height: window.innerHeight, + }); + } + + window.addEventListener("resize", handleResize); + + handleResize(); + + return () => window.removeEventListener("resize", handleResize); + }, []); + return windowSize; +} + +export default useWindowSize; \ No newline at end of file