Skip to content
64 changes: 42 additions & 22 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ 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";

export default function Home() {
const [isOpen, setIsOpen] = useState<boolean>(false);
Expand All @@ -17,33 +16,54 @@ export default function Home() {
}
}, []);

const [windowWidth, setWindowWidth] = useState(
Copy link
Member

@chamny20 chamny20 Jun 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3: ์œˆ๋„์šฐ ๋„ˆ๋น„์ฒดํฌํ•˜๋Š” ์š” ๋ถ€๋ถ„์€ useWindowSize์™€ ๊ฐ™์ด ํ›…์œผ๋กœ ๋นผ๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™๋„ค์š”~
๊ทผ๋ฐ ์—ฌ๊ธฐ์„œ๋งŒ ์‚ฌ์šฉ๋  ๊ฒƒ ๊ฐ™๋‹ค๋ฉด ๊ตณ์ด ์•ˆํ•ด๋„ ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹น!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useWindowSize ๊ด€๋ จ ํ›…์œผ๋กœ ๋ถ„๋ฆฌํ•  ์ƒ๊ฐ์„ ๋ชปํ–ˆ๋„ค์š”..! ๐Ÿ‘

typeof window !== "undefined" ? window.innerWidth : 0
);

useEffect(() => {
const handleResize = () => {
setWindowWidth(window.innerWidth);
};

if (typeof window !== "undefined") {
window.addEventListener("resize", handleResize);

return () => {
window.removeEventListener("resize", handleResize);
};
}
}, []);

return (
// ์ „์ฒด 1440px
<main className="mx-auto w-full flex flex-col items-center">
{/* ๋žœ๋”ฉ ๋ฌธ๊ตฌ */}
<>
<section
className="w-full h-[620px] bg-purple-main4 flex justify-center"
style={{
backgroundImage: "url('/assets/main_background.png')",
backgroundSize: "cover",
}}
className={`absolute scale-75 ${windowWidth >= 1460 ? "fixed left-[20%] transform-1/2-1/2" : "flex justify-center items-center min-w-[1460px] max-[1920px]"}`}
>
<section className="w-[1080px] scale-75 mx-auto">
<LandingTop />
</section>
<LandingTop />
</section>
<main className="mx-auto w-full flex flex-col items-center mt-[70px]">
{/* ๋žœ๋”ฉ ๋ฌธ๊ตฌ */}
<section
className="w-full max-w-[1470px] h-[620px] flex justify-center items-center"
style={{
backgroundImage: "url('/assets/main_background.png')",
backgroundSize: "cover",
}}
></section>

{/* ์ปจํ…Œ์ด๋„ˆ ๋„ˆ๋น„ */}
<section className="max-w-[1080px] w-full mt-[100px] flex flex-col gap-[100px] mb-[100px]">
{/* ์บ๋Ÿฌ์…€ */}
<LandingMid />
<Suspense>
{/* ํ”„๋กœ์ ํŠธ */}
<ProjectList />
</Suspense>
</section>
{/* ์ปจํ…Œ์ด๋„ˆ ๋„ˆ๋น„ */}
<section className="max-w-[1080px] w-full mt-[100px] flex flex-col gap-[100px] mb-[100px]">
{/* ์บ๋Ÿฌ์…€ */}
<LandingMid />
<Suspense>
{/* ํ”„๋กœ์ ํŠธ */}
<ProjectList />
</Suspense>
</section>

{isOpen && <SignUpModal isOpen={isOpen} setIsOpen={setIsOpen} />}
</main>
{isOpen && <SignUpModal isOpen={isOpen} setIsOpen={setIsOpen} />}
</main>
</>
);
}
39 changes: 27 additions & 12 deletions src/components/landing/carousel/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
"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 { TagProps } from "@component/components/common-components/tag";

// ์บ๋Ÿฌ์…€ ํ™”์‚ดํ‘œ
import ArrowBackIosNewRoundedIcon from "@mui/icons-material/ArrowBackIosNewRounded";
import ArrowForwardIosRoundedIcon from "@mui/icons-material/ArrowForwardIosRounded";

export interface RecommendData {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p2: ์ด ๋ถ€๋ถ„์€ types์— ๋”ฐ๋กœ ๋นผ๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”!

createdAt: string;
createdBy: string;
field: TagProps["type"];
profileImageUrl: string;
progress: TagProps["status"];
projectId: number;
summary: string;
title: string;
}

const PrevArrow = ({ onClick }: any) => {
return (
<ArrowBackIosNewRoundedIcon
Expand Down Expand Up @@ -38,29 +49,34 @@ const settings = {
slidesToShow: 3, // ํ™”๋ฉด์— ํ•œ ๋ฒˆ์— ํ‘œ์‹œํ•  ์Šฌ๋ผ์ด๋“œ ๊ฐœ์ˆ˜ ์„ค์ •
slidesToScroll: 3, // ๋‹ค์Œ ๋ณด์—ฌ ์ค„ ์Šฌ๋ผ์ด๋“œ์˜ ๊ฐœ์ˆ˜ ์„ค์ •
speed: 2000, // ํ™”๋ฉด์„ ๋„˜๊ธธ ๋•Œ ์†๋„
autoplay: false, // TODO: ์ž๋™ ๋„˜๊น€ ๋…ผ์˜
autoplay: false,
autoplaySpeed: 5000, // ๊ฐ„๊ฒฉ
nextArrow: <NextArrow />,
prevArrow: <PrevArrow />,
};

const Carousel = () => {
const { data, error, isLoading } = useGetProjectRecommend();
const [recommendData, setRecommendData] = useState<any>();

useEffect(() => {
if (data) {
setRecommendData(data.data.data)
}
const recommendData: RecommendData[] = useMemo(() => {
return data?.data.data ?? [];
}, [data]);

if (error) {
console.log(error);
if (isLoading || error) {
return (
<Slider {...settings} className="mt-[32.5px]">
{[...Array(3)].map((_, index) => (
<div>
<div className="w-[344px] h-[340px] rounded-[10px] border border-[1.5px] border-purple-main1 bg-purple-main5 flex justify-center items-center"></div>
</div>
))}
</Slider>
);
}
return (
<>
<Slider {...settings} className="mt-[32.5px]">
{recommendData?.map((item: any) => (
{recommendData?.map((item: RecommendData) => (
<RecommendItem
key={item.projectId}
projectId={item.projectId}
Expand All @@ -71,7 +87,6 @@ const Carousel = () => {
profileImg={item.profileImageUrl}
nickname={item.createdBy}
createdAt={item.createdAt}
isLoading={isLoading}
/>
))}
</Slider>
Expand Down
2 changes: 1 addition & 1 deletion src/components/landing/carousel/LandingTop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const LandingTop = () => {
<div className="text-title mt-[32px] text-white">
์—ฌ๋Ÿฌ ๋ถ„์•ผ์˜ ์„œ๋น„์Šค ์œ ์ €๋กœ๋ถ€ํ„ฐ ์œ ์˜๋ฏธํ•œ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด์š”.
</div>
<Button size="lg" className="mt-[100px] min-w-[246px]" onClick={onClickProject}>
<Button size="lg" className="mt-[100px] min-w-[246px] text-h1" onClick={onClickProject}>
ํ”„๋กœ์ ํŠธ ๋“ฑ๋กํ•˜๊ธฐ
</Button>
<Toaster />
Expand Down
92 changes: 54 additions & 38 deletions src/components/landing/carousel/RecommendItem.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,61 @@
import Image from "next/image";
import Tag from "@component/components/common-components/tag/Tag";
import { useRouter } from "next/navigation";
import { TagProps } from "@component/components/common-components/tag";

const RecommendItem = ({
projectId,
fields,
progress,
title,
content,
profileImg,
nickname,
createdAt,
isLoading
}: any) => {
const router = useRouter();
return (
<>
{isLoading ? (
<div className="w-[344px] h-[340px] rounded-[10px] border border-[1.5px] border-purple-main1 bg-purple-main5 flex justify-center items-center cursor-pointer">
</div>
) : (
<div
className="w-[344px] h-[340px] rounded-[10px] border border-[1.5px] border-purple-main1 bg-purple-main5 flex justify-center items-center cursor-pointer"
onClick={() => {
router.push(`/project/${projectId}`)
}}
>
<div className="w-[261px] h-[296.93px] relative">
<Tag type={fields} status={progress} />
<div className="text-title mt-[12px] mb-[24px]">{title}</div>
<div className="text-body1 text-gray-60 font-medium">{content}</div>
<div className="absolute bottom-0 flex items-center">
<Image src={profileImg} alt="์ž„์‹œ ํ”„๋กœํ•„ ์ด๋ฏธ์ง€" width={20} height={20} className="w-[20px] h-[20px] rounded-full me-[10px]" />
<div className="text-body1 text-gray-60 me-[24px] font-medium">{nickname}</div>
<div className="text-body1 text-gray-60 font-medium">{createdAt}</div>
</div>
</div>
</div>
)}
</>
);
interface RecommendItemData {
projectId: number;
fields: TagProps["type"];
progress: TagProps["status"];
title: string;
content: string;
profileImg: string;
nickname: string;
createdAt: string;
}

const RecommendItem = ({
projectId,
fields,
progress,
title,
content,
profileImg,
nickname,
createdAt,
}: RecommendItemData) => {
const router = useRouter();
return (
<>
<div
className="w-[344px] h-[340px] rounded-[10px] border border-[1.5px] border-purple-main1 bg-purple-main5 flex justify-center items-center cursor-pointer"
onClick={() => {
router.push(`/project/${projectId}`);
}}
>
<div className="w-[261px] h-[296.93px] relative">
<Tag type={fields} status={progress} />
<div className="text-title mt-[12px] mb-[24px]">{title}</div>
<div className="text-body1 text-gray-60 font-medium">{content}</div>
<div className="absolute bottom-0 flex items-center">
<Image
src={profileImg}
alt="์ž„์‹œ ํ”„๋กœํ•„ ์ด๋ฏธ์ง€"
width={20}
height={20}
className="w-[20px] h-[20px] rounded-full me-[10px]"
/>
<div className="text-body1 text-gray-60 me-[24px] font-medium">
{nickname}
</div>
<div className="text-body1 text-gray-60 font-medium">
{createdAt}
</div>
</div>
</div>
</div>
</>
);
};

export default RecommendItem;