Skip to content

Commit

Permalink
✨ feat: 추천 축제 컴포넌트 구현 #34
Browse files Browse the repository at this point in the history
  • Loading branch information
froggy1014 committed Aug 31, 2024
1 parent 6f483bd commit 3454c0c
Show file tree
Hide file tree
Showing 7 changed files with 286 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { getServerSideSession } from "@/apis/auth/auth";
import { FloatingButton } from "@/components/core/Button";
import RecommendFestival from "@/components/Swiper/RecommendFestival";
import { HomeHeader } from "@/layout/Mobile/MobileHeader";
import NavigationBar from "@/layout/Mobile/NavigationBar";

import { FestivalHot, FestivalThisWeek, TopReviews } from "./_components";

export default async function Home() {
const session = await getServerSideSession();
return (
<div className="mb-[60px] mt-[44px]">
<HomeHeader />
<main className="flex flex-col gap-[40px] bg-gray-scale-100 px-[16px] pb-[36px] pt-[16px]">
<RecommendFestival />
<main className="flex flex-col gap-[40px] rounded-t-[20px] bg-gray-scale-100 px-[16px] pb-[36px] pt-[16px]">
<FestivalHot />
<FestivalThisWeek />
<TopReviews />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import type { Meta, StoryObj } from "@storybook/react";

import RecommendFestivalFallbackUI from "./RecommendFestivalFallbackUI";
import RecoomendFestivalList from "./RecommendFestivalList";

const meta: Meta<typeof RecoomendFestivalList> = {
title: "Swiper/RecommendFestival",
component: RecoomendFestivalList,
parameters: {
controls: { include: [] },
},
argTypes: {},
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
recommendFestivals: {
festivals: [
{
festivalId: 64,
name: "dfdfd",
sido: "충청남도",
sigungu: "천안시 동남구",
thumbnailImage:
"https://fiesta-image.s3.ap-northeast-2.amazonaws.com/festival/6869294f-f5ef-4891-a3ca-60fac98e2873my-festival-type%20%282%29.png",
startDate: "2024-08-29",
endDate: "2024-08-31",
},
{
festivalId: 43,
name: "광주 버스킹 월드컵",
sido: "광주",
sigungu: "동구",
thumbnailImage:
"https://fiesta-image.s3.ap-northeast-2.amazonaws.com/festival/fd48e6eb-5ff6-457d-affd-d3cc659042503112130_image2_1.jpeg",
startDate: "2024-10-02",
endDate: "2024-10-06",
},
{
festivalId: 44,
name: "광주 추억의 충장축제",
sido: "광주",
sigungu: "동구",
thumbnailImage:
"https://fiesta-image.s3.ap-northeast-2.amazonaws.com/festival/00d385e7-5048-4265-abaf-8fd001ecff7711111111.jpg",
startDate: "2024-10-02",
endDate: "2024-10-06",
},
{
festivalId: 45,
name: "광주프린지페스티벌",
sido: "광주",
sigungu: "북구",
thumbnailImage:
"https://fiesta-image.s3.ap-northeast-2.amazonaws.com/festival/f54a1b88-0873-4696-b3a0-ca6e15b949ae3343042_image2_1.jpg",
startDate: "2024-09-21",
endDate: "2024-09-29",
},
{
festivalId: 54,
name: "국가유산 미디어아트 고흥분청사기요지",
sido: "전라남도",
sigungu: "고흥군",
thumbnailImage:
"https://fiesta-image.s3.ap-northeast-2.amazonaws.com/festival/d52dee4c-edbc-46c0-8236-b801411cad0d3340080_image2_1.jpg",
startDate: "2024-09-13",
endDate: "2024-10-06",
},
],
userType: {
userTypeId: 2,
name: "파티피플러",
},
},
},
render: (args) => (
<div className="h-[300px] w-[400px]">
<RecoomendFestivalList recommendFestivals={args.recommendFestivals} />
</div>
),
};
export const NoSession: Story = {
args: {},
render: (args) => (
<div className="h-[300px] w-[400px]">
<RecommendFestivalFallbackUI />
</div>
),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Image from "next/image";
import Link from "next/link";
import React from "react";

import RoundButton from "@/components/core/Button/RoundButton/RoundButton";

const RecommendFestivalFallbackUI = () => {
return (
<div className="flex w-full justify-between gap-[12px] px-[24px] py-[35px]">
<div className="flex w-full flex-col justify-between gap-[12px]">
<div className="flex flex-col">
<span className="whitespace-nowrap text-title-bold">
로그인을 통해
</span>
<span className="whitespace-nowrap text-title-bold">
페스티벌을 추천받아요
</span>
</div>
<Link href="/auth/sign-in">
<RoundButton
label={"로그인하러가기"}
className="w-auto bg-primary-01"
/>
</Link>
</div>
<div className="flex h-auto w-full items-end justify-end">
<Image
src="/images/fallbackLogo.png"
alt="romantist"
width={134}
height={112}
/>
</div>
</div>
);
};

export default RecommendFestivalFallbackUI;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Image from "next/image";

import { UserTypeImage, UserTypeText } from "@/utils";

const RecommendFestivalHeader = ({
userType,
}: {
userType: {
userTypeId: number;
name: string;
};
}) => {
const userTypeTextColor = UserTypeText[userType.userTypeId ?? 1];
const userTypeImage = UserTypeImage[userType.userTypeId ?? 1];

return (
<div className="relative flex w-full justify-between">
<div className="flex w-1/2 flex-wrap pb-[18px] text-title-bold">
<span className={userTypeTextColor}>{userType.name}</span>
<span>들을</span>
<span>위한 페스티벌이에요!</span>
</div>
<Image
className="absolute bottom-[-15px] right-[20px]"
src={userTypeImage ?? "/images/fallbackLogo.png"}
alt={userType.name}
width={109}
height={109}
/>
</div>
);
};

export default RecommendFestivalHeader;
101 changes: 101 additions & 0 deletions src/components/Swiper/RecommendFestival/RecommendFestivalList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"use client";

import "swiper/css";
import "swiper/css/pagination";

import Image from "next/image";
import Link from "next/link";
import { Pagination } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";

import { RecommendFestivalResponse } from "@/apis/festivals/recommendFestival/recommendFestivalType";
import { formatToKoreanDate } from "@/lib/dayjs";

import RecommendFestivalHeader from "./RecommendFestivalHeader";

const RecommendFestivalList = ({
recommendFestivals,
}: {
recommendFestivals: RecommendFestivalResponse;
}) => {
return (
<section className="relative h-full w-full px-[24px] py-[35px]">
<RecommendFestivalHeader userType={recommendFestivals.userType} />
<Swiper
pagination={{
type: "fraction",
el: ".pagination_fraction",
renderFraction: function (currentClass, totalClass) {
return (
'<span class="' +
currentClass +
'"></span>' +
" / " +
'<span class="' +
totalClass +
'"></span>'
);
},
}}
// navigation={{
// enabled: true,
// prevEl: ".nav_prev",
// nextEl: ".nav_next",
// }}
// modules={[Pagination, Navigation]}
modules={[Pagination]}
className="relative flex h-[289px] w-full items-center justify-center rounded-[18px]"
>
{recommendFestivals.festivals.map((festival) => (
<SwiperSlide
key={festival.festivalId}
className="relative flex h-[289px] w-full cursor-pointer items-center justify-center"
>
<Image
src={festival.thumbnailImage}
alt="image"
fill
className="rounded-[18px]"
/>
<Link
href={`/festivals/${festival.festivalId}`}
className="absolute bottom-[20px] left-[10px] flex h-auto w-auto flex-col gap-[4px] rounded-[10px] bg-gray-scale-900/30 px-[12px] py-[8px]"
>
<h2 className="text-body2-bold text-gray-scale-0">
{`${festival.sido} ${festival.sigungu} | ${formatToKoreanDate(festival.startDate)} - ${formatToKoreanDate(festival.endDate)}`}
</h2>
<h1 className="text-title-bold text-gray-scale-0">
{festival.name}
</h1>
</Link>
</SwiperSlide>
))}
<button className="absolute right-[10px] top-[10px] z-[4] rounded-[40px] bg-gray-scale-900/50 px-[12px] py-[8px] text-button2-medium text-white">
<span className="pagination_fraction"></span>
</button>
{/* <button
type="button"
className="nav_prev absolute left-[10px] top-1/2 translate-y-[-50%] z-[4] bg-gray-scale-900/40 size-[40px] flex justify-center items-center rounded-full"
>
<ArrowLeftSmallIcon
width={20}
height={20}
className="text-gray-scale-0"
/>
</button>
<button
type="button"
className="nav_next absolute right-[10px] top-1/2 translate-y-[-50%] z-[4] bg-gray-scale-900/40 size-[40px] flex justify-center items-center rounded-full"
>
<ArrowRightSmallIcon
width={20}
height={20}
className="text-gray-scale-0"
/>
</button> */}
</Swiper>
</section>
);
};

export default RecommendFestivalList;
16 changes: 16 additions & 0 deletions src/components/Swiper/RecommendFestival/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { getRecommendFestival } from "@/apis/festivals/recommendFestival/recommendFestival";

import RecommendFestivalFallbackUI from "./RecommendFestivalFallbackUI";
import RecommendFestivalList from "./RecommendFestivalList";

const RecommendFestival = async () => {
const festivals = await getRecommendFestival();

if (!festivals) {
return <RecommendFestivalFallbackUI />;
}

return <RecommendFestivalList recommendFestivals={festivals} />;
};

export default RecommendFestival;
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from "./extractKeyFromArray";
export * from "./generateQueryString";
export * from "./generateUrlWithParams";
export * from "./getSettledValue";
export * from "./getUserType";
export * from "./isEmpty";
export * from "./isMatchPath";
export * from "./log";

0 comments on commit 3454c0c

Please sign in to comment.