From 21c3fe270962d851f35e779c5a62e523ec62b61c Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 01:43:12 +0900 Subject: [PATCH 01/27] =?UTF-8?q?=F0=9F=94=A8=20settings:=20nextjs=20cachi?= =?UTF-8?q?ng=20logging=20config=20=EC=B6=94=EA=B0=80=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/next.config.mjs b/next.config.mjs index 0cb182d..bfaf54d 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -36,6 +36,12 @@ const nextConfig = { return config; }, + // ? https://nextjs.org/docs/app/api-reference/next-config-js/logging + logging: { + fetches: { + fullUrl: true, + }, + }, }; export default nextConfig; From e320a6bffd5858be0c2f708c34bcae713935e3cf Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 01:45:34 +0900 Subject: [PATCH 02/27] =?UTF-8?q?=F0=9F=94=A7=20chore:=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=ED=99=98=EA=B2=BD=20=EB=A1=9C=EA=B9=85=20=EC=9C=A0?= =?UTF-8?q?=ED=8B=B8=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/log.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/utils/log.ts diff --git a/src/utils/log.ts b/src/utils/log.ts new file mode 100644 index 0000000..a9600b9 --- /dev/null +++ b/src/utils/log.ts @@ -0,0 +1,11 @@ +export const log = (...args: unknown[]) => { + if (process.env.NODE_ENV === "development") { + console.log(...args); + } +}; + +export const errorLog = (...args: unknown[]) => { + if (process.env.NODE_ENV === "development") { + console.error(...args); + } +}; From 21319f4ba0d66cf850850754bcef19527014901d Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 01:46:53 +0900 Subject: [PATCH 03/27] =?UTF-8?q?=F0=9F=94=A7=20chore:=20onboading=20API?= =?UTF-8?q?=20=EB=AA=85=EC=84=B8=EC=97=90=20=EB=94=B0=EB=A5=B8=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/onboarding.ts | 225 +++++++--------------------------------- 1 file changed, 37 insertions(+), 188 deletions(-) diff --git a/src/model/onboarding.ts b/src/model/onboarding.ts index 350c0bf..d3ec3e3 100644 --- a/src/model/onboarding.ts +++ b/src/model/onboarding.ts @@ -1,206 +1,55 @@ -export type MoodModel = { +export type FestivalMood = { moodId: number; mood: string; }; -export type PriorityModel = { - priorityId: number; - priority: string; -}; - -export type CompanyModel = { +export type FestivalCompanion = { companionTypeId: number; companionType: string; }; -export type CategoryModel = { +export type FestivalCategory = { categoryId: number; + categoryEmoji: string; category: string; }; -export const MOODS = [ - { - moodId: 1, - mood: "낭만적인", - }, - { - moodId: 2, - mood: "여유로운", - }, - { - moodId: 3, - mood: "활기찬", - }, - { - moodId: 4, - mood: "모험적인", - }, - { - moodId: 5, - mood: "화려한", - }, - { - moodId: 6, - mood: "예술적인", - }, - { - moodId: 7, - mood: "힙한", - }, - { - moodId: 8, - mood: "감성적인", - }, - { - moodId: 9, - mood: "레트로한", - }, - { - moodId: 10, - mood: "친근한", - }, - { - moodId: 11, - mood: "색다른", - }, - { - moodId: 12, - mood: "로맨틱한", - }, - { - moodId: 13, - mood: "클래식한", - }, - { - moodId: 14, - mood: "신비한", - }, - { - moodId: 15, - mood: "전통적인", - }, - { - moodId: 16, - mood: "재미있는", - }, - { - moodId: 17, - mood: "감동이 있는", - }, -]; +export type FestivalPriority = { + priorityId: number; + priority: string; +}; + +export type FestivalMoodResponse = { + statusCode: number; + status: string; + message: string; + data: FestivalMood[]; +}; -export const PRIORITIES = [ - { - priorityId: 1, - priority: "주제 관심사 일치", - }, - { - priorityId: 2, - priority: "페스티벌 입장료", - }, - { - priorityId: 3, - priority: "페스티벌 내 음식 가격", - }, - { - priorityId: 4, - priority: "주요 프로그램", - }, - { - priorityId: 5, - priority: "동행하는 사람", - }, - { - priorityId: 6, - priority: "날짜", - }, - { - priorityId: 7, - priority: "위치", - }, - { - priorityId: 8, - priority: "포토스팟", - }, -]; +export type FestivalCompanionResponse = { + statusCode: number; + status: string; + message: string; + data: FestivalCompanion[]; +}; -export const COMPANIES = [ - { - companionTypeId: 1, - companionType: "가족", - }, - { - companionTypeId: 2, - companionType: "친구", - }, - { - companionTypeId: 3, - companionType: "직장 동료", - }, - { - companionTypeId: 4, - companionType: "연인", - }, - { - companionTypeId: 5, - companionType: "혼자", - }, -]; +export type FestivalCategoryResponse = { + statusCode: number; + status: string; + message: string; + data: FestivalCategory[]; +}; -export const CATEGORIES: Array = [ - { - categoryId: 1, - category: "문화", - }, - { - categoryId: 2, - category: "음악&댄스", - }, - { - categoryId: 3, - category: "영화", - }, - { - categoryId: 4, - category: "음식&술", - }, - { - categoryId: 5, - category: "엑티비티", - }, - { - categoryId: 6, - category: "미술", - }, - { - categoryId: 7, - category: "역사", - }, - { - categoryId: 8, - category: "자연", - }, - { - categoryId: 9, - category: "반려동물", - }, - { - categoryId: 10, - category: "야간", - }, - { - categoryId: 11, - category: "불꽃축제", - }, - { - categoryId: 12, - category: "이색축제", - }, -]; +export type FestivalPriorityResponse = { + statusCode: number; + status: string; + message: string; + data: FestivalPriority[]; +}; export type OnboardingModel = { - categories: Array; - moods: Array; - companies: Array; - priorities: Array; + categories: Array; + companies: Array; + priorities: Array; + moods: Array; }; From 5b8c1f3000af55b46239a5700aad63c08782b4d0 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 01:48:13 +0900 Subject: [PATCH 04/27] =?UTF-8?q?=F0=9F=94=A7=20chore:=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=20=EB=8D=B0=EB=B8=8C=ED=88=B4=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/ReactQueryProvider.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/ReactQueryProvider.tsx b/src/lib/ReactQueryProvider.tsx index eb3862b..ee049dc 100644 --- a/src/lib/ReactQueryProvider.tsx +++ b/src/lib/ReactQueryProvider.tsx @@ -3,7 +3,6 @@ // ? Reference - https://codevoweb.com/how-to-set-up-and-use-react-query-in-next-js-14/ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { PropsWithChildren, useState } from "react"; function ReactQueryProvider({ children }: PropsWithChildren) { @@ -12,7 +11,7 @@ function ReactQueryProvider({ children }: PropsWithChildren) { return ( {children} - + {/* */} ); } From 20fad688ab8c6aa453ea0f4c509741d5ca0ddc75 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 01:51:13 +0900 Subject: [PATCH 05/27] =?UTF-8?q?=E2=9C=A8=20feat:=20fetch=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EC=83=81=ED=99=94=ED=95=9C=20http=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=9E=84=EC=8B=9C=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/http.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/apis/http.ts diff --git a/src/apis/http.ts b/src/apis/http.ts new file mode 100644 index 0000000..2118df9 --- /dev/null +++ b/src/apis/http.ts @@ -0,0 +1,59 @@ +class Http { + private baseUrl: string; + + constructor() { + this.baseUrl = process.env.NEXT_PUBLIC_BASE_URL as string; + } + + async request(url: string, options = {}): Promise { + const defaultOptions = { + headers: { + "Content-Type": "application/json", + }, + ...options, + }; + + try { + const response = await fetch(`${this.baseUrl}${url}`, defaultOptions); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + return await response.json(); + } catch (error) { + console.error("Fetch error: ", error); + throw error; + } + } + + async get(url: string, options = {}): Promise { + return this.request(url, { + method: "GET", + cache: "force-cache", + ...options, + }); + } + + async post(url: string, body = {}, options = {}): Promise { + return this.request(url, { + method: "POST", + body: JSON.stringify(body), + ...options, + }); + } + + async put(url: string, body = {}, options = {}): Promise { + return this.request(url, { + method: "PUT", + body: JSON.stringify(body), + ...options, + }); + } + + async delete(url: string, options = {}): Promise { + return this.request(url, { method: "DELETE", ...options }); + } +} + +export default Http; From 5fd7bfdb18663dfe79a05bfed081cb1abff53f85 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 01:55:08 +0900 Subject: [PATCH 06/27] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=98=A8=EB=B3=B4?= =?UTF-8?q?=EB=94=A9=20=EC=84=9C=EB=B2=84=EC=95=A1=EC=85=98,=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=EC=BD=94=EB=93=9C=20=EA=B5=AC=ED=98=84=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/onboarding/onboardingService.ts | 57 ++++++++++++++++++++++++ src/app/onboarding/action.ts | 20 +++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/apis/onboarding/onboardingService.ts create mode 100644 src/app/onboarding/action.ts diff --git a/src/apis/onboarding/onboardingService.ts b/src/apis/onboarding/onboardingService.ts new file mode 100644 index 0000000..e3d8aa7 --- /dev/null +++ b/src/apis/onboarding/onboardingService.ts @@ -0,0 +1,57 @@ +import { + FestivalCategoryResponse, + FestivalCompanionResponse, + FestivalMoodResponse, + FestivalPriorityResponse, +} from "@/model/onboarding"; +import { errorLog } from "@/utils/log"; + +import http from "../http"; + +export class OnboardingService extends http { + async getMoods() { + try { + const response = await this.get("/festivals/moods"); + return response.data; + } catch (error) { + errorLog("Failed to fetch moods:", error); + throw error; + } + } + + async getCategories() { + try { + const response = await this.get( + "/festivals/categories", + ); + return response.data; + } catch (error) { + errorLog("Failed to fetch categories:", error); + throw error; + } + } + + async getCompanions() { + try { + const response = await this.get( + "/festivals/companions", + ); + return response.data; + } catch (error) { + errorLog("Failed to fetch companions:", error); + throw error; + } + } + + async getPriority() { + try { + const response = await this.get( + "/festivals/priorities", + ); + return response.data; + } catch (error) { + errorLog("Failed to fetch priorities:", error); + throw error; + } + } +} diff --git a/src/app/onboarding/action.ts b/src/app/onboarding/action.ts new file mode 100644 index 0000000..b9c1af0 --- /dev/null +++ b/src/app/onboarding/action.ts @@ -0,0 +1,20 @@ +"use server"; + +import { OnboardingService } from "@/apis/onboarding/onboardingService"; +import { OnboardingModel } from "@/model/onboarding"; + +const onboardingService = new OnboardingService(); + +export const getInitialOnboadingData = async (): Promise => { + const moods = await onboardingService.getMoods(); + const categories = await onboardingService.getCategories(); + const companies = await onboardingService.getCompanions(); + const priorities = await onboardingService.getPriority(); + + return { + moods, + categories, + companies, + priorities, + }; +}; From e10301e6322067cf9ea4d6fb6ea55f4c7a094173 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 01:56:01 +0900 Subject: [PATCH 07/27] =?UTF-8?q?=F0=9F=94=A7=20chore:=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=B3=80=EA=B2=BD=20=EC=A0=81=EC=9A=A9=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/OnBoardingCategories.tsx | 14 +++++++++----- .../_components/OnBoardingCompanies.tsx | 13 ++++++++----- .../onboarding/_components/OnBoardingMoods.tsx | 6 +++--- .../_components/OnBoardingPriorities.tsx | 6 +++--- src/app/onboarding/page.tsx | 14 +++++++------- src/app/onboarding/view.tsx | 16 ++++++++-------- 6 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/app/onboarding/_components/OnBoardingCategories.tsx b/src/app/onboarding/_components/OnBoardingCategories.tsx index 3657b3d..c48b5ff 100644 --- a/src/app/onboarding/_components/OnBoardingCategories.tsx +++ b/src/app/onboarding/_components/OnBoardingCategories.tsx @@ -2,13 +2,13 @@ import { FC } from "react"; import { useFieldArray, useFormContext } from "react-hook-form"; import { SquareTabButton } from "@/components/core/Button"; -import { CategoryModel, OnboardingModel } from "@/model/onboarding"; +import { FestivalCategory, OnboardingModel } from "@/model/onboarding"; import { ONBOARDING } from "../_constants"; import OnBoardingTitle from "./OnBoardingTitle"; interface Props { - categories: Array; + categories: Array; } const OnBoardingCategories: FC = ({ categories }) => { @@ -20,7 +20,7 @@ const OnBoardingCategories: FC = ({ categories }) => { const handleCategoryToggle = ( isSelected: boolean, - category: CategoryModel, + category: FestivalCategory, ) => { if (isSelected) { replace(fields.filter((v) => v.categoryId !== category.categoryId)); @@ -38,7 +38,7 @@ const OnBoardingCategories: FC = ({ categories }) => { />
- {categories.map(({ categoryId, category }) => { + {categories.map(({ categoryId, category, categoryEmoji }) => { const isSelected = fields.some((c) => c.categoryId === categoryId); return ( = ({ categories }) => { active={isSelected} disabled={fields.length === 2 && !isSelected} onClick={() => - handleCategoryToggle(isSelected, { categoryId, category }) + handleCategoryToggle(isSelected, { + categoryId, + category, + categoryEmoji, + }) } /> ); diff --git a/src/app/onboarding/_components/OnBoardingCompanies.tsx b/src/app/onboarding/_components/OnBoardingCompanies.tsx index 33675b5..5fe63f2 100644 --- a/src/app/onboarding/_components/OnBoardingCompanies.tsx +++ b/src/app/onboarding/_components/OnBoardingCompanies.tsx @@ -3,24 +3,27 @@ import { useFieldArray, useFormContext } from "react-hook-form"; import BasicTile from "@/components/core/List/BasicTitle/BasicTile"; import { CheckCircleIcon } from "@/components/icons"; -import { CompanyModel, OnboardingModel } from "@/model/onboarding"; +import { FestivalCompanion, OnboardingModel } from "@/model/onboarding"; import { cn } from "@/utils/cn"; import { ONBOARDING } from "../_constants"; import OnBoardingTitle from "./OnBoardingTitle"; interface Props { - companies: Array; + companies: Array; } -const OnBoardingCategories: FC = ({ companies }) => { +const OnBoardingCompanions: FC = ({ companies }) => { const { control } = useFormContext(); const { fields, replace, append, remove } = useFieldArray({ control: control, name: "companies", }); - const handleMoodToggle = (isSelected: boolean, company: CompanyModel) => { + const handleMoodToggle = ( + isSelected: boolean, + company: FestivalCompanion, + ) => { isSelected ? replace( fields.filter((v) => v.companionTypeId !== company.companionTypeId), @@ -94,4 +97,4 @@ const OnBoardingCategories: FC = ({ companies }) => { ); }; -export default OnBoardingCategories; +export default OnBoardingCompanions; diff --git a/src/app/onboarding/_components/OnBoardingMoods.tsx b/src/app/onboarding/_components/OnBoardingMoods.tsx index 5eb2c21..fdb2d76 100644 --- a/src/app/onboarding/_components/OnBoardingMoods.tsx +++ b/src/app/onboarding/_components/OnBoardingMoods.tsx @@ -2,13 +2,13 @@ import { FC } from "react"; import { useFieldArray, useFormContext } from "react-hook-form"; import BasicChip from "@/components/core/Chip/BasicChip/BasicChip"; -import { MoodModel, OnboardingModel } from "@/model/onboarding"; +import { FestivalMood, OnboardingModel } from "@/model/onboarding"; import { ONBOARDING } from "../_constants"; import OnBoardingTitle from "./OnBoardingTitle"; interface Props { - moods: Array; + moods: Array; } const OnBoardingCategories: FC = ({ moods }) => { @@ -18,7 +18,7 @@ const OnBoardingCategories: FC = ({ moods }) => { name: "moods", }); - const handleMoodToggle = (isSelected: boolean, moodItem: MoodModel) => { + const handleMoodToggle = (isSelected: boolean, moodItem: FestivalMood) => { isSelected ? replace(fields.filter((v) => v.moodId !== moodItem.moodId)) : append(moodItem); diff --git a/src/app/onboarding/_components/OnBoardingPriorities.tsx b/src/app/onboarding/_components/OnBoardingPriorities.tsx index 4d7c342..408dcc6 100644 --- a/src/app/onboarding/_components/OnBoardingPriorities.tsx +++ b/src/app/onboarding/_components/OnBoardingPriorities.tsx @@ -2,13 +2,13 @@ import { FC } from "react"; import { useFieldArray, useFormContext } from "react-hook-form"; import BasicTile from "@/components/core/List/BasicTitle/BasicTile"; -import { OnboardingModel, PriorityModel } from "@/model/onboarding"; +import { FestivalPriority, OnboardingModel } from "@/model/onboarding"; import { ONBOARDING } from "../_constants"; import OnBoardingTitle from "./OnBoardingTitle"; interface Props { - priorities: Array; + priorities: Array; } const OnBoardingPriorities: FC = ({ priorities }) => { @@ -23,7 +23,7 @@ const OnBoardingPriorities: FC = ({ priorities }) => { const handlePriorityToggle = ( isSelected: boolean, - priorityItem: PriorityModel, + priorityItem: FestivalPriority, ) => { isSelected ? replace(fields.filter((v) => v.priorityId !== priorityItem.priorityId)) diff --git a/src/app/onboarding/page.tsx b/src/app/onboarding/page.tsx index 85fdfee..9b89238 100644 --- a/src/app/onboarding/page.tsx +++ b/src/app/onboarding/page.tsx @@ -1,16 +1,16 @@ -import { CATEGORIES, COMPANIES, MOODS, PRIORITIES } from "@/model/onboarding"; - +import { getInitialOnboadingData } from "./action"; import OnBoardingView from "./view"; export default async function OnBoarding() { - // TODO: server side fetching + const { moods, categories, companies, priorities } = + await getInitialOnboadingData(); return ( ); } diff --git a/src/app/onboarding/view.tsx b/src/app/onboarding/view.tsx index 497beaa..d4a85cd 100644 --- a/src/app/onboarding/view.tsx +++ b/src/app/onboarding/view.tsx @@ -7,11 +7,11 @@ import { FormProvider, useForm } from "react-hook-form"; import { ProgressBar } from "@/components/core/Progress"; import { DefaultHeader } from "@/layout/Mobile/MobileHeader"; import { - CategoryModel, - CompanyModel, - MoodModel, + FestivalCategory, + FestivalCompanion, + FestivalMood, + FestivalPriority, OnboardingModel, - PriorityModel, } from "@/model/onboarding"; import { OnBoardingSchema } from "@/validations/OnboardingSchema"; @@ -25,10 +25,10 @@ import { import { ONBOARDING } from "./_constants"; interface Props { - categories: Array; - companies: Array; - priorities: Array; - moods: Array; + categories: Array; + companies: Array; + priorities: Array; + moods: Array; } const OnBoardingView: FC = ({ From 52300b818f6ce32b058ecb8b1b6b98736aefeed2 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 02:33:33 +0900 Subject: [PATCH 08/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95=EC=97=90=20=EC=9D=98?= =?UTF-8?q?=ED=95=9C=20=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/OnBoardingCategories.tsx | 1 + .../_components/OnBoardingCompanies.tsx | 15 +++++++-------- src/model/onboarding.ts | 2 +- src/validations/OnboardingSchema.ts | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/app/onboarding/_components/OnBoardingCategories.tsx b/src/app/onboarding/_components/OnBoardingCategories.tsx index c48b5ff..f6d90fb 100644 --- a/src/app/onboarding/_components/OnBoardingCategories.tsx +++ b/src/app/onboarding/_components/OnBoardingCategories.tsx @@ -46,6 +46,7 @@ const OnBoardingCategories: FC = ({ categories }) => { type="button" label={category} active={isSelected} + emoji={categoryEmoji} disabled={fields.length === 2 && !isSelected} onClick={() => handleCategoryToggle(isSelected, { diff --git a/src/app/onboarding/_components/OnBoardingCompanies.tsx b/src/app/onboarding/_components/OnBoardingCompanies.tsx index 5fe63f2..6c8d925 100644 --- a/src/app/onboarding/_components/OnBoardingCompanies.tsx +++ b/src/app/onboarding/_components/OnBoardingCompanies.tsx @@ -25,9 +25,7 @@ const OnBoardingCompanions: FC = ({ companies }) => { company: FestivalCompanion, ) => { isSelected - ? replace( - fields.filter((v) => v.companionTypeId !== company.companionTypeId), - ) + ? replace(fields.filter((v) => v.companionId !== company.companionId)) : append(company); }; @@ -76,18 +74,19 @@ const OnBoardingCompanions: FC = ({ companies }) => { - {companies.map((companyItem) => { - const { companionTypeId, companionType } = companyItem; + {companies.map(({ companionId, companionType }) => { const isSelected = fields.some( - (c) => c.companionTypeId === companionTypeId, + (c) => c.companionId === companionId, ); return ( handleMoodToggle(isSelected, companyItem)} + onClick={() => + handleMoodToggle(isSelected, { companionId, companionType }) + } /> ); })} diff --git a/src/model/onboarding.ts b/src/model/onboarding.ts index d3ec3e3..20b37d2 100644 --- a/src/model/onboarding.ts +++ b/src/model/onboarding.ts @@ -4,7 +4,7 @@ export type FestivalMood = { }; export type FestivalCompanion = { - companionTypeId: number; + companionId: number; companionType: string; }; diff --git a/src/validations/OnboardingSchema.ts b/src/validations/OnboardingSchema.ts index be69e6c..8dac850 100644 --- a/src/validations/OnboardingSchema.ts +++ b/src/validations/OnboardingSchema.ts @@ -11,7 +11,7 @@ const PrioritySchema = z.object({ }); const CompanySchema = z.object({ - companionTypeId: z.number(), + companionId: z.number(), companionType: z.string(), }); From 3697a9502de5406b05a6edcb1de5a82cbbf5d9fd Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 02:34:22 +0900 Subject: [PATCH 09/27] =?UTF-8?q?=F0=9F=92=85=20style:=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=B3=80=EA=B2=BD=EC=97=90=EC=9D=98=ED=95=9C=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=88=98=EC=A0=95=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Button/SquareTabButton/SquareTabButton.tsx | 18 +++++++++++++----- .../core/List/BasicTitle/BasicTile.tsx | 17 +++++++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/components/core/Button/SquareTabButton/SquareTabButton.tsx b/src/components/core/Button/SquareTabButton/SquareTabButton.tsx index 50e7258..0a8a636 100644 --- a/src/components/core/Button/SquareTabButton/SquareTabButton.tsx +++ b/src/components/core/Button/SquareTabButton/SquareTabButton.tsx @@ -4,15 +4,21 @@ import { cn } from "@/utils/cn"; export interface Props extends Omit, "children"> { + emoji: string; active: boolean; label: string; } -const SquareTabButton: FC = ({ label, active = false, ...props }) => { +const SquareTabButton: FC = ({ + label, + active = false, + emoji, + ...props +}) => { return ( From bf0a6a0a35a576b4119b1e3ef734963c378f02af Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 03:42:42 +0900 Subject: [PATCH 10/27] =?UTF-8?q?=F0=9F=94=A7=20chore:=20=EB=94=9C?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/delay.ts | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/utils/delay.ts diff --git a/src/utils/delay.ts b/src/utils/delay.ts new file mode 100644 index 0000000..98eaa4f --- /dev/null +++ b/src/utils/delay.ts @@ -0,0 +1,3 @@ +export function delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} From 76e73300577e2a887c09a9e49b252449342fa5f6 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 14 Aug 2024 03:43:29 +0900 Subject: [PATCH 11/27] =?UTF-8?q?=F0=9F=92=85=20style:=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=A7=88=EC=9D=B4=EB=84=88=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/core/Button/SquareTabButton/SquareTabButton.tsx | 2 +- src/components/core/Progress/ProgressCircle/ProgressCircle.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/core/Button/SquareTabButton/SquareTabButton.tsx b/src/components/core/Button/SquareTabButton/SquareTabButton.tsx index 0a8a636..56c2e06 100644 --- a/src/components/core/Button/SquareTabButton/SquareTabButton.tsx +++ b/src/components/core/Button/SquareTabButton/SquareTabButton.tsx @@ -18,7 +18,7 @@ const SquareTabButton: FC = ({ return ( - {companies.map(({ companionId, companionType }) => { + {companions.map(({ companionId, companionType }) => { const isSelected = fields.some( - (c) => c.companionId === companionId, + (festival) => festival.companionId === companionId, ); return ( = ({ companies }) => { label={companionType} active={isSelected} onClick={() => - handleMoodToggle(isSelected, { companionId, companionType }) + handleMoodToggle(isSelected, { + companionId, + companionType, + }) } /> ); diff --git a/src/app/onboarding/_components/onBoardingStep/OnBoardingMoods.tsx b/src/app/onboarding/_components/onBoardingStep/OnBoardingMoods.tsx index 99679bb..9eb5082 100644 --- a/src/app/onboarding/_components/onBoardingStep/OnBoardingMoods.tsx +++ b/src/app/onboarding/_components/onBoardingStep/OnBoardingMoods.tsx @@ -1,10 +1,13 @@ import { FC } from "react"; import { useFieldArray, useFormContext } from "react-hook-form"; +import { + FestivalMood, + OnboardingModel, +} from "@/apis/onboarding/onboardingType"; import BasicChip from "@/components/core/Chip/BasicChip/BasicChip"; -import { FestivalMood, OnboardingModel } from "@/model/onboarding"; +import { ONBOARDING_SETTING } from "@/config"; -import { ONBOARDING } from "../../_constants"; import OnBoardingTitle from "./OnBoardingTitle"; interface Props { @@ -20,7 +23,9 @@ const OnBoardingMoods: FC = ({ moods }) => { const handleMoodToggle = (isSelected: boolean, moodItem: FestivalMood) => { isSelected - ? replace(fields.filter((v) => v.moodId !== moodItem.moodId)) + ? replace( + fields.filter((festival) => festival.moodId !== moodItem.moodId), + ) : append(moodItem); }; @@ -28,19 +33,21 @@ const OnBoardingMoods: FC = ({ moods }) => { <>
{moods.map((moodItem) => { - const { moodId, mood } = moodItem; - const isSelected = fields.some((c) => c.moodId === moodId); + const { moodId, name } = moodItem; + const isSelected = fields.some( + (festival) => festival.moodId === moodId, + ); return ( handleMoodToggle(isSelected, moodItem)} diff --git a/src/app/onboarding/_components/onBoardingStep/OnBoardingPriorities.tsx b/src/app/onboarding/_components/onBoardingStep/OnBoardingPriorities.tsx index 9769324..d564e6c 100644 --- a/src/app/onboarding/_components/onBoardingStep/OnBoardingPriorities.tsx +++ b/src/app/onboarding/_components/onBoardingStep/OnBoardingPriorities.tsx @@ -1,10 +1,13 @@ import { FC } from "react"; import { useFieldArray, useFormContext } from "react-hook-form"; +import { + FestivalPriority, + OnboardingModel, +} from "@/apis/onboarding/onboardingType"; import BasicTile from "@/components/core/List/BasicTitle/BasicTile"; -import { FestivalPriority, OnboardingModel } from "@/model/onboarding"; +import { ONBOARDING_SETTING } from "@/config"; -import { ONBOARDING } from "../../_constants"; import OnBoardingTitle from "./OnBoardingTitle"; interface Props { @@ -26,7 +29,11 @@ const OnBoardingPriorities: FC = ({ priorities }) => { priorityItem: FestivalPriority, ) => { isSelected - ? replace(fields.filter((v) => v.priorityId !== priorityItem.priorityId)) + ? replace( + fields.filter( + (festival) => festival.priorityId !== priorityItem.priorityId, + ), + ) : append(priorityItem); }; @@ -34,14 +41,16 @@ const OnBoardingPriorities: FC = ({ priorities }) => { <>
{priorities.map((priorityItem) => { const { priorityId, priority } = priorityItem; - const isSelected = fields.some((c) => c.priorityId === priorityId); + const isSelected = fields.some( + (festival) => festival.priorityId === priorityId, + ); return ( ; - companies: Array; + companions: Array; priorities: Array; moods: Array; } const OnBoardingContainer: FC = ({ categories, - companies, + companions, priorities, moods, }) => { const router = useRouter(); - const { currentStep, handleNextStep, handlePrevStep, ONBOARDING } = - useOnBoardingStep(); + const { currentStep, handleNextStep, handlePrevStep } = useOnBoardingStep(); const { trigger, handleSubmit } = useFormContext(); // * 첫 렌더링에 유효성 검사 1회 실행 @@ -46,7 +46,6 @@ const OnBoardingContainer: FC = ({ const onSubmit = async (data: OnboardingModel) => { await delay(5000); - console.log("🚀 ~ onSubmit ~ data:", data); router.replace("/onboarding/complete"); }; @@ -55,18 +54,18 @@ const OnBoardingContainer: FC = ({ } = { 1: , 2: , - 3: , + 3: , 4: , }; return (
@@ -76,7 +75,7 @@ const OnBoardingContainer: FC = ({ > <>{renderCurrentStep[currentStep]} diff --git a/src/app/onboarding/_constants/index.tsx b/src/app/onboarding/_constants/index.tsx deleted file mode 100644 index 65c9846..0000000 --- a/src/app/onboarding/_constants/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export const ONBOARDING = Object.freeze({ - INITIAL_STEP: 1, - TOTAL_STEP: 4, - CATEGORY_TITLE: "관심있는 페스티벌을 알려주세요!", - CATEGORY_SUBTITLE: "관심 분야 2가지를 선택해주세요", - MOOD_TITLE: "선호하는 페스티벌 분위기를 알려주세요!", - MOOD_SUBTITLE: "선호하는 무드 3가지를 골라주세요", - COMPANY_TITLE: "주로 누구와 함께 가시나요?", - COMPANY_SUBTITLE: "선택하신 대상과 함께 갈 페스티벌을 추천해드려요.", - PRIORITY_TITLE: "페스티벌에서 어떤 것이 가장 중요하신가요?", - PRIORITY_SUBTITLE: "중요 요소 3가지를 선택해주세요", -}); diff --git a/src/app/onboarding/action.ts b/src/app/onboarding/action.ts deleted file mode 100644 index b9c1af0..0000000 --- a/src/app/onboarding/action.ts +++ /dev/null @@ -1,20 +0,0 @@ -"use server"; - -import { OnboardingService } from "@/apis/onboarding/onboardingService"; -import { OnboardingModel } from "@/model/onboarding"; - -const onboardingService = new OnboardingService(); - -export const getInitialOnboadingData = async (): Promise => { - const moods = await onboardingService.getMoods(); - const categories = await onboardingService.getCategories(); - const companies = await onboardingService.getCompanions(); - const priorities = await onboardingService.getPriority(); - - return { - moods, - categories, - companies, - priorities, - }; -}; diff --git a/src/app/onboarding/page.tsx b/src/app/onboarding/page.tsx index 9b89238..0574c21 100644 --- a/src/app/onboarding/page.tsx +++ b/src/app/onboarding/page.tsx @@ -1,14 +1,15 @@ -import { getInitialOnboadingData } from "./action"; +import { getOnboardingData } from "@/apis/onboarding/onboarding"; + import OnBoardingView from "./view"; export default async function OnBoarding() { - const { moods, categories, companies, priorities } = - await getInitialOnboadingData(); + const { moods, categories, companions, priorities } = + await getOnboardingData(); return ( diff --git a/src/app/onboarding/view.tsx b/src/app/onboarding/view.tsx index 52a8cb3..af560fe 100644 --- a/src/app/onboarding/view.tsx +++ b/src/app/onboarding/view.tsx @@ -11,7 +11,7 @@ import { FestivalMood, FestivalPriority, OnboardingModel, -} from "@/model/onboarding"; +} from "@/apis/onboarding/onboardingType"; import { OnBoardingSchema } from "@/validations/OnboardingSchema"; import { OnBoardingContainer } from "./_components"; @@ -22,14 +22,14 @@ const OnBoardingLoading = dynamic( interface Props { categories: Array; - companies: Array; + companions: Array; priorities: Array; moods: Array; } const OnBoardingView: FC = ({ categories, - companies, + companions, priorities, moods, }) => { @@ -38,7 +38,7 @@ const OnBoardingView: FC = ({ defaultValues: { categories: [], moods: [], - companies: [], + companions: [], priorities: [], }, resolver: zodResolver(OnBoardingSchema), @@ -56,7 +56,7 @@ const OnBoardingView: FC = ({ diff --git a/src/model/onboarding.ts b/src/model/onboarding.ts index 20b37d2..e69de29 100644 --- a/src/model/onboarding.ts +++ b/src/model/onboarding.ts @@ -1,55 +0,0 @@ -export type FestivalMood = { - moodId: number; - mood: string; -}; - -export type FestivalCompanion = { - companionId: number; - companionType: string; -}; - -export type FestivalCategory = { - categoryId: number; - categoryEmoji: string; - category: string; -}; - -export type FestivalPriority = { - priorityId: number; - priority: string; -}; - -export type FestivalMoodResponse = { - statusCode: number; - status: string; - message: string; - data: FestivalMood[]; -}; - -export type FestivalCompanionResponse = { - statusCode: number; - status: string; - message: string; - data: FestivalCompanion[]; -}; - -export type FestivalCategoryResponse = { - statusCode: number; - status: string; - message: string; - data: FestivalCategory[]; -}; - -export type FestivalPriorityResponse = { - statusCode: number; - status: string; - message: string; - data: FestivalPriority[]; -}; - -export type OnboardingModel = { - categories: Array; - companies: Array; - priorities: Array; - moods: Array; -}; diff --git a/src/validations/OnboardingSchema.ts b/src/validations/OnboardingSchema.ts index 8dac850..e1612d9 100644 --- a/src/validations/OnboardingSchema.ts +++ b/src/validations/OnboardingSchema.ts @@ -2,7 +2,7 @@ import { z } from "zod"; const MoodSchema = z.object({ moodId: z.number(), - mood: z.string(), + name: z.string(), }); const PrioritySchema = z.object({ @@ -17,17 +17,18 @@ const CompanySchema = z.object({ const CategorySchema = z.object({ categoryId: z.number(), - category: z.string(), + emoji: z.string(), + name: z.string(), }); const MoodsSchema = z.array(MoodSchema).min(3, "at least three items"); const PrioritiesSchema = z.array(PrioritySchema).min(3, "at least one item"); -const CompaniesSchema = z.array(CompanySchema).min(1, "at least one item"); +const companionsSchema = z.array(CompanySchema).min(1, "at least one item"); const CategoriesSchema = z.array(CategorySchema).min(2, "at least two items"); export const OnBoardingSchema = z.object({ categories: CategoriesSchema, moods: MoodsSchema, - companies: CompaniesSchema, + companions: companionsSchema, priorities: PrioritiesSchema, }); From 693f5552f1bc6acef7ea31edbf116908f7804e13 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Sun, 18 Aug 2024 23:50:02 +0900 Subject: [PATCH 23/27] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=98=A8=EB=B3=B4?= =?UTF-8?q?=EB=94=A9=20=EA=B4=80=EB=A0=A8=20=ED=83=80=EC=9E=85,=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=ED=8E=98=EC=B9=AD,=20=ED=82=A4=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/onboarding/onboarding.ts | 78 +++++++++++++++++++++++++++ src/apis/onboarding/onboardingKeys.ts | 3 ++ src/apis/onboarding/onboardingType.ts | 27 ++++++++++ src/hooks/useOnBoardingStep.ts | 5 +- 4 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 src/apis/onboarding/onboarding.ts create mode 100644 src/apis/onboarding/onboardingKeys.ts create mode 100644 src/apis/onboarding/onboardingType.ts diff --git a/src/apis/onboarding/onboarding.ts b/src/apis/onboarding/onboarding.ts new file mode 100644 index 0000000..7913c19 --- /dev/null +++ b/src/apis/onboarding/onboarding.ts @@ -0,0 +1,78 @@ +"use server"; +import { FIESTA_ENDPOINTS } from "@/config"; + +import instance from "../instance"; +import { festivalOnBoarding } from "./onboardingKeys"; +import { + FestivalCategory, + FestivalCompanion, + FestivalMood, + FestivalPriority, + OnboardingModel, +} from "./onboardingType"; + +export const getMoods = async () => { + const endpoint = FIESTA_ENDPOINTS.festivals.moods; + const { data } = await instance.get>(endpoint, { + next: { + tags: festivalOnBoarding.all, + }, + }); + + return data; +}; +export const getCategories = async () => { + const endpoint = FIESTA_ENDPOINTS.festivals.categories; + const { data } = await instance.get>(endpoint, { + next: { + tags: festivalOnBoarding.all, + }, + }); + + return data; +}; +export const getCompanions = async () => { + const endpoint = FIESTA_ENDPOINTS.festivals.companions; + const { data } = await instance.get>(endpoint, { + next: { + tags: festivalOnBoarding.all, + }, + }); + + return data; +}; +export const getPriority = async () => { + const endpoint = FIESTA_ENDPOINTS.festivals.priorities; + const { data } = await instance.get>(endpoint, { + next: { + tags: festivalOnBoarding.all, + }, + }); + + return data; +}; + +export const getOnboardingData = async (): Promise => { + const [moodsPromise, categoriesPromise, companionsPromise, priorityPromise] = + await Promise.allSettled([ + getMoods(), + getCategories(), + getCompanions(), + getPriority(), + ]); + + const moods = moodsPromise.status === "fulfilled" ? moodsPromise.value : []; + const companions = + companionsPromise.status === "fulfilled" ? companionsPromise.value : []; + const priorities = + priorityPromise.status === "fulfilled" ? priorityPromise.value : []; + const categories = + categoriesPromise.status === "fulfilled" ? categoriesPromise.value : []; + + return { + moods, + companions, + priorities, + categories, + }; +}; diff --git a/src/apis/onboarding/onboardingKeys.ts b/src/apis/onboarding/onboardingKeys.ts new file mode 100644 index 0000000..fded849 --- /dev/null +++ b/src/apis/onboarding/onboardingKeys.ts @@ -0,0 +1,3 @@ +export const festivalOnBoarding = { + all: ["FestivalOnBoarding"], +}; diff --git a/src/apis/onboarding/onboardingType.ts b/src/apis/onboarding/onboardingType.ts new file mode 100644 index 0000000..3c2a097 --- /dev/null +++ b/src/apis/onboarding/onboardingType.ts @@ -0,0 +1,27 @@ +export type FestivalMood = { + moodId: number; + name: string; +}; + +export type FestivalCompanion = { + companionId: number; + companionType: string; +}; + +export type FestivalCategory = { + categoryId: number; + emoji: string; + name: string; +}; + +export type FestivalPriority = { + priorityId: number; + priority: string; +}; + +export type OnboardingModel = { + categories: Array; + companions: Array; + priorities: Array; + moods: Array; +}; diff --git a/src/hooks/useOnBoardingStep.ts b/src/hooks/useOnBoardingStep.ts index d3edea1..bf54b0b 100644 --- a/src/hooks/useOnBoardingStep.ts +++ b/src/hooks/useOnBoardingStep.ts @@ -1,9 +1,9 @@ import { useState } from "react"; -import { ONBOARDING } from "@/app/onboarding/_constants"; +import { ONBOARDING_SETTING } from "@/config"; export const useOnBoardingStep = () => { - const { INITIAL_STEP, TOTAL_STEP } = ONBOARDING; + const { INITIAL_STEP, TOTAL_STEP } = ONBOARDING_SETTING; const [currentStep, setCurrentStep] = useState(INITIAL_STEP); const handleStepChange = (stepChange: number) => { @@ -22,6 +22,5 @@ export const useOnBoardingStep = () => { handleNextStep, INITIAL_STEP, TOTAL_STEP, - ONBOARDING, }; }; From 5d00b02adc9f26e9b00e1a15f8c69b54468cb0a5 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Sun, 18 Aug 2024 23:51:15 +0900 Subject: [PATCH 24/27] =?UTF-8?q?=F0=9F=94=A7=20chore:=20default=20Header?= =?UTF-8?q?=EB=A5=BC=20=EC=84=9C=EB=B2=84,=20=ED=81=B4=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EC=96=B8=ED=8A=B8=20=EC=96=91=EC=AA=BD=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=B2=84=ED=8A=BC=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultHeader/ClientBackButton.tsx | 28 +++++++++++++++++++ .../DefaultHeader/DefaultHeader.tsx | 13 ++++----- 2 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 src/layout/Mobile/MobileHeader/DefaultHeader/ClientBackButton.tsx diff --git a/src/layout/Mobile/MobileHeader/DefaultHeader/ClientBackButton.tsx b/src/layout/Mobile/MobileHeader/DefaultHeader/ClientBackButton.tsx new file mode 100644 index 0000000..3eb5181 --- /dev/null +++ b/src/layout/Mobile/MobileHeader/DefaultHeader/ClientBackButton.tsx @@ -0,0 +1,28 @@ +import Link from "next/link"; +import { FC } from "react"; +import { UrlObject } from "url"; + +import { ArrowLeftSmallIcon } from "@/components/icons"; + +interface Props { + href?: UrlObject | string; + onClick?: () => void; +} + +const ClientBackButton: FC = ({ href, onClick }) => { + if (href) { + return ( + + + + ); + } else { + return ( + + ); + } +}; + +export default ClientBackButton; diff --git a/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeader.tsx b/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeader.tsx index 420d9af..aec4878 100644 --- a/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeader.tsx +++ b/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeader.tsx @@ -1,27 +1,24 @@ -import Link from "next/link"; import { FC } from "react"; import { UrlObject } from "url"; -import { ArrowLeftSmallIcon } from "@/components/icons"; +import ClientBackButton from "./ClientBackButton"; interface Props { label?: string; showBackButton?: boolean; - href: UrlObject | string; + href?: UrlObject | string; + onClick?: () => void; } const DefaultHeader: FC = ({ label = "", showBackButton = true, href, + onClick, }) => { return (
- {showBackButton && ( - - - - )} + {showBackButton && } {label}
From 397e3303060e6d1e113c0dbda7d942136553dc93 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Mon, 19 Aug 2024 00:17:48 +0900 Subject: [PATCH 25/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20defaultH?= =?UTF-8?q?eaderBackButton=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultHeader/ClientBackButton.tsx | 28 ---------------- .../DefaultHeader/DefaultHeader.tsx | 2 +- .../DefaultHeader/DefaultHeaderBackButton.tsx | 33 +++++++++++++++++++ 3 files changed, 34 insertions(+), 29 deletions(-) delete mode 100644 src/layout/Mobile/MobileHeader/DefaultHeader/ClientBackButton.tsx create mode 100644 src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeaderBackButton.tsx diff --git a/src/layout/Mobile/MobileHeader/DefaultHeader/ClientBackButton.tsx b/src/layout/Mobile/MobileHeader/DefaultHeader/ClientBackButton.tsx deleted file mode 100644 index 3eb5181..0000000 --- a/src/layout/Mobile/MobileHeader/DefaultHeader/ClientBackButton.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import Link from "next/link"; -import { FC } from "react"; -import { UrlObject } from "url"; - -import { ArrowLeftSmallIcon } from "@/components/icons"; - -interface Props { - href?: UrlObject | string; - onClick?: () => void; -} - -const ClientBackButton: FC = ({ href, onClick }) => { - if (href) { - return ( - - - - ); - } else { - return ( - - ); - } -}; - -export default ClientBackButton; diff --git a/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeader.tsx b/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeader.tsx index aec4878..2036f61 100644 --- a/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeader.tsx +++ b/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeader.tsx @@ -1,7 +1,7 @@ import { FC } from "react"; import { UrlObject } from "url"; -import ClientBackButton from "./ClientBackButton"; +import ClientBackButton from "./DefaultHeaderBackButton"; interface Props { label?: string; diff --git a/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeaderBackButton.tsx b/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeaderBackButton.tsx new file mode 100644 index 0000000..78c38c9 --- /dev/null +++ b/src/layout/Mobile/MobileHeader/DefaultHeader/DefaultHeaderBackButton.tsx @@ -0,0 +1,33 @@ +import Link from "next/link"; +import { FC } from "react"; +import { UrlObject } from "url"; + +import { IconButton } from "@/components/core/Button"; +import { ArrowLeftSmallIcon } from "@/components/icons"; + +interface Props { + href?: UrlObject | string; + onClick?: () => void; +} + +const DefaultHeaderBackButton: FC = ({ href, onClick }) => { + if (onClick) { + return ( + + + + ); + } + + return ( + + + + ); +}; + +export default DefaultHeaderBackButton; From 32199ef6a34adda01f7bbb23b53d4e87a2944b8e Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Mon, 19 Aug 2024 00:28:05 +0900 Subject: [PATCH 26/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=ED=95=B4=EC=95=BC=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EC=B5=9C=EC=86=9F=EA=B0=92=EB=93=A4=20=EC=83=81=EC=88=98?= =?UTF-8?q?=ED=99=94=20#6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onBoardingStep/OnBoardingButton.tsx | 7 ++++--- .../onBoardingStep/OnBoardingCategories.tsx | 5 ++++- .../onBoardingStep/OnBoardingCompanies.tsx | 6 +++--- .../_components/onBoardingStep/OnBoardingMoods.tsx | 4 +++- src/config/onBoardingSetting.ts | 3 +++ src/validations/OnboardingSchema.ts | 14 +++++++++++--- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/app/onboarding/_components/onBoardingStep/OnBoardingButton.tsx b/src/app/onboarding/_components/onBoardingStep/OnBoardingButton.tsx index 755e19b..d3c1012 100644 --- a/src/app/onboarding/_components/onBoardingStep/OnBoardingButton.tsx +++ b/src/app/onboarding/_components/onBoardingStep/OnBoardingButton.tsx @@ -3,6 +3,7 @@ import { useFormContext, useWatch } from "react-hook-form"; import { OnboardingModel } from "@/apis/onboarding/onboardingType"; import { BasicButton } from "@/components/core/Button"; +import { ONBOARDING_SETTING } from "@/config"; import { checkNumber } from "@/utils/checkNumber"; interface Props { @@ -23,11 +24,11 @@ const OnBoardingButton: FC = ({ currentStep, totalStep, onNext }) => { [key: number]: { label: string; isError: boolean }; } = { 1: { - label: `다음 (${checkNumber(fields.categories?.length)}/2)`, + label: `다음 (${checkNumber(fields.categories?.length)}/${ONBOARDING_SETTING.CATEGORY_MIN})`, isError: !!errors.categories, }, 2: { - label: `다음 (${checkNumber(fields.moods?.length)}/3)`, + label: `다음 (${checkNumber(fields.moods?.length)}/${ONBOARDING_SETTING.MOOD_MIN})`, isError: !!errors.moods, }, 3: { @@ -35,7 +36,7 @@ const OnBoardingButton: FC = ({ currentStep, totalStep, onNext }) => { isError: !!errors.companions, }, 4: { - label: `다음 (${checkNumber(fields.priorities?.length)}/3)`, + label: `다음 (${checkNumber(fields.priorities?.length)}/${ONBOARDING_SETTING.PRIORITY_MIN})`, isError: !!errors.priorities, }, }; diff --git a/src/app/onboarding/_components/onBoardingStep/OnBoardingCategories.tsx b/src/app/onboarding/_components/onBoardingStep/OnBoardingCategories.tsx index 27e0e90..0ca9265 100644 --- a/src/app/onboarding/_components/onBoardingStep/OnBoardingCategories.tsx +++ b/src/app/onboarding/_components/onBoardingStep/OnBoardingCategories.tsx @@ -56,7 +56,10 @@ const OnBoardingCategories: FC = ({ categories }) => { label={name} active={isSelected} emoji={emoji} - disabled={fields.length === 2 && !isSelected} + disabled={ + fields.length === ONBOARDING_SETTING.CATEGORY_MIN && + !isSelected + } onClick={() => handleCategoryToggle(isSelected, { categoryId, diff --git a/src/app/onboarding/_components/onBoardingStep/OnBoardingCompanies.tsx b/src/app/onboarding/_components/onBoardingStep/OnBoardingCompanies.tsx index 09cee0c..fb5995e 100644 --- a/src/app/onboarding/_components/onBoardingStep/OnBoardingCompanies.tsx +++ b/src/app/onboarding/_components/onBoardingStep/OnBoardingCompanies.tsx @@ -39,7 +39,7 @@ const OnBoardingCompanions: FC = ({ companions }) => { const handleCheckAllToggle = () => { remove(fields.map((_, index) => index)); - if (fields.length < 5) { + if (fields.length < companions.length) { companions.forEach((companyItem) => append(companyItem)); } }; @@ -64,7 +64,7 @@ const OnBoardingCompanions: FC = ({ companions }) => { width={18} height={18} className={cn( - fields.length === 5 + fields.length === companions.length ? "text-primary-01" : "text-gray-scale-300", )} @@ -72,7 +72,7 @@ const OnBoardingCompanions: FC = ({ companions }) => { = ({ moods }) => { type="button" label={name} active={isSelected} - disabled={fields.length === 3 && !isSelected} + disabled={ + fields.length === ONBOARDING_SETTING.MOOD_MIN && !isSelected + } onClick={() => handleMoodToggle(isSelected, moodItem)} /> ); diff --git a/src/config/onBoardingSetting.ts b/src/config/onBoardingSetting.ts index 356d746..b0c1d7c 100644 --- a/src/config/onBoardingSetting.ts +++ b/src/config/onBoardingSetting.ts @@ -1,6 +1,9 @@ const ONBOARDING_SETTING = Object.freeze({ INITIAL_STEP: 1, TOTAL_STEP: 4, + CATEGORY_MIN: 2, + MOOD_MIN: 3, + PRIORITY_MIN: 3, CATEGORY_TITLE: "관심있는 페스티벌을 알려주세요!", CATEGORY_SUBTITLE: "관심 분야 2가지를 선택해주세요", MOOD_TITLE: "선호하는 페스티벌 분위기를 알려주세요!", diff --git a/src/validations/OnboardingSchema.ts b/src/validations/OnboardingSchema.ts index e1612d9..4a9e86a 100644 --- a/src/validations/OnboardingSchema.ts +++ b/src/validations/OnboardingSchema.ts @@ -1,5 +1,7 @@ import { z } from "zod"; +import { ONBOARDING_SETTING } from "@/config"; + const MoodSchema = z.object({ moodId: z.number(), name: z.string(), @@ -21,10 +23,16 @@ const CategorySchema = z.object({ name: z.string(), }); -const MoodsSchema = z.array(MoodSchema).min(3, "at least three items"); -const PrioritiesSchema = z.array(PrioritySchema).min(3, "at least one item"); +const MoodsSchema = z + .array(MoodSchema) + .min(ONBOARDING_SETTING.MOOD_MIN, "at least three items"); +const PrioritiesSchema = z + .array(PrioritySchema) + .min(ONBOARDING_SETTING.PRIORITY_MIN, "at least one item"); const companionsSchema = z.array(CompanySchema).min(1, "at least one item"); -const CategoriesSchema = z.array(CategorySchema).min(2, "at least two items"); +const CategoriesSchema = z + .array(CategorySchema) + .min(ONBOARDING_SETTING.CATEGORY_MIN, "at least two items"); export const OnBoardingSchema = z.object({ categories: CategoriesSchema, From 19ecd15dd917c6d275238771a73dccb17894f958 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Mon, 19 Aug 2024 22:30:00 +0900 Subject: [PATCH 27/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/onboarding/onboarding.ts | 13 ++++++------- .../_components/onBoardingLoading/index.tsx | 8 ++++---- src/app/onboarding/view.tsx | 1 - .../core/Button/SquareTabButton/SquareTabButton.tsx | 2 +- src/components/core/List/BasicTitle/BasicTile.tsx | 9 ++------- src/model/onboarding.ts | 0 src/utils/getSettledValue.ts | 6 ++++++ src/utils/index.ts | 4 ++++ 8 files changed, 23 insertions(+), 20 deletions(-) delete mode 100644 src/model/onboarding.ts create mode 100644 src/utils/getSettledValue.ts diff --git a/src/apis/onboarding/onboarding.ts b/src/apis/onboarding/onboarding.ts index 7913c19..1a1b463 100644 --- a/src/apis/onboarding/onboarding.ts +++ b/src/apis/onboarding/onboarding.ts @@ -1,5 +1,6 @@ "use server"; import { FIESTA_ENDPOINTS } from "@/config"; +import { getSettledValue } from "@/utils"; import instance from "../instance"; import { festivalOnBoarding } from "./onboardingKeys"; @@ -41,6 +42,7 @@ export const getCompanions = async () => { return data; }; + export const getPriority = async () => { const endpoint = FIESTA_ENDPOINTS.festivals.priorities; const { data } = await instance.get>(endpoint, { @@ -61,13 +63,10 @@ export const getOnboardingData = async (): Promise => { getPriority(), ]); - const moods = moodsPromise.status === "fulfilled" ? moodsPromise.value : []; - const companions = - companionsPromise.status === "fulfilled" ? companionsPromise.value : []; - const priorities = - priorityPromise.status === "fulfilled" ? priorityPromise.value : []; - const categories = - categoriesPromise.status === "fulfilled" ? categoriesPromise.value : []; + const moods = getSettledValue(moodsPromise, []); + const categories = getSettledValue(categoriesPromise, []); + const companions = getSettledValue(companionsPromise, []); + const priorities = getSettledValue(priorityPromise, []); return { moods, diff --git a/src/app/onboarding/_components/onBoardingLoading/index.tsx b/src/app/onboarding/_components/onBoardingLoading/index.tsx index d974d40..487cccc 100644 --- a/src/app/onboarding/_components/onBoardingLoading/index.tsx +++ b/src/app/onboarding/_components/onBoardingLoading/index.tsx @@ -6,7 +6,7 @@ import { ProgressCircle } from "@/components/core/Progress"; import { CheckIcon } from "@/components/icons"; import { cn } from "@/utils/cn"; -const strings = [ +const ONBOARDING_LOADING_MESSAGES = [ "페스티벌 관심사 파악 완료!", "페스티벌 무드 파악 완료!", "페스티벌 일행 파악 완료!", @@ -19,10 +19,10 @@ const OnBoardingLoading = () => {

페스티벌 유형 프로필을 -

-

+
설정하는 중이예요

+

잠시만 기다려주세요...

@@ -42,7 +42,7 @@ const OnBoardingLoading = () => {
- {strings.map((str, idx) => ( + {ONBOARDING_LOADING_MESSAGES.map((str, idx) => ( = ({ priorities={priorities} moods={moods} /> - ; ); }; diff --git a/src/components/core/Button/SquareTabButton/SquareTabButton.tsx b/src/components/core/Button/SquareTabButton/SquareTabButton.tsx index 56c2e06..8080cb6 100644 --- a/src/components/core/Button/SquareTabButton/SquareTabButton.tsx +++ b/src/components/core/Button/SquareTabButton/SquareTabButton.tsx @@ -5,7 +5,7 @@ import { cn } from "@/utils/cn"; export interface Props extends Omit, "children"> { emoji: string; - active: boolean; + active?: boolean; label: string; } diff --git a/src/components/core/List/BasicTitle/BasicTile.tsx b/src/components/core/List/BasicTitle/BasicTile.tsx index f91bfb5..d36083f 100644 --- a/src/components/core/List/BasicTitle/BasicTile.tsx +++ b/src/components/core/List/BasicTitle/BasicTile.tsx @@ -1,15 +1,10 @@ -import { ButtonHTMLAttributes, FC } from "react"; +import { ComponentPropsWithoutRef, FC } from "react"; import { cn } from "@/utils/cn"; -export interface Props - extends Omit< - ButtonHTMLAttributes, - "children" | "className" - > { +export interface Props extends ComponentPropsWithoutRef<"button"> { active: boolean; label: string; - className?: string; } const BasicTile: FC = ({ active, label, className, ...props }) => { diff --git a/src/model/onboarding.ts b/src/model/onboarding.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/utils/getSettledValue.ts b/src/utils/getSettledValue.ts new file mode 100644 index 0000000..8431d04 --- /dev/null +++ b/src/utils/getSettledValue.ts @@ -0,0 +1,6 @@ +export const getSettledValue = ( + result: PromiseSettledResult, + defaultValue: T, +): T => { + return result.status === "fulfilled" ? result.value : defaultValue; +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index 13feabe..bcdab56 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,5 +1,9 @@ export * from "./checkNumber"; export * from "./cn"; +export * from "./delay"; +export * from "./downloadImageByUrl"; export * from "./generateQueryString"; export * from "./generateUrlWithParams"; +export * from "./getSettledValue"; export * from "./isEmpty"; +export * from "./log";