From c4fcb63d90622f852bae0b887f5ebe627755425f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=98=88=EC=A7=84?= Date: Mon, 19 Aug 2024 01:01:09 +0900 Subject: [PATCH] feat: fetch profile --- src/app/routes/profile.$key.tsx | 38 ++++++++++++++++--- .../model/convertIdealPartnerToDto.ts | 18 ++++++++- .../ideal_partner/model/idealPartnerStore.ts | 20 +++++----- .../profile/model/convertProfileToDto.ts | 22 ++++++++++- src/entities/profile/model/myProfileStore.tsx | 4 +- src/pages/profile/ProfilePage.tsx | 18 +++++---- src/shared/functions/createStoreContext.tsx | 10 +++-- src/shared/vo/date.ts | 8 ++++ .../ProfileCardList/ProfileCardList.tsx | 2 +- 9 files changed, 110 insertions(+), 30 deletions(-) diff --git a/src/app/routes/profile.$key.tsx b/src/app/routes/profile.$key.tsx index ce0db67..93f8f44 100644 --- a/src/app/routes/profile.$key.tsx +++ b/src/app/routes/profile.$key.tsx @@ -1,8 +1,16 @@ -import { LoaderFunction } from '@remix-run/node'; -import { fullProfileMock } from 'src/entities/profile/api/__mock__/fullProfile.mock'; +import { LoaderFunctionArgs } from '@remix-run/node'; import { ProfilePage } from 'src/pages/profile/ProfilePage'; +import { getInfo } from 'src/types'; +import { getAuthSession } from 'src/app/server/sessions'; +import { authenticate } from 'src/app/server/authenticate'; +import { useLoaderData } from '@remix-run/react'; +import { MyProfileProvider } from 'src/entities/profile/model/myProfileStore'; +import { IdealPartnerProvider } from 'src/entities/ideal_partner/model/idealPartnerStore'; +import { useMemo } from 'react'; +import { convertDtoToProfile } from 'src/entities/profile/model/convertProfileToDto'; +import { convertDtoToIdealPartner } from 'src/entities/ideal_partner/model/convertIdealPartnerToDto'; -export const loader: LoaderFunction = ({ params }) => { +export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { key } = params; if (!key) { @@ -12,9 +20,29 @@ export const loader: LoaderFunction = ({ params }) => { }); } - return { profile: fullProfileMock }; + const session = await getAuthSession(request); + const accessToken = await authenticate(request, session); + const { data } = await getInfo(key, { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }); + + return { profile: data }; }; export default function Page() { - return ; + const { profile } = useLoaderData(); + const profileInitialState = useMemo(() => convertDtoToProfile(profile.userInfo), [profile.userInfo]); + const idealPartnerInitialState = useMemo( + () => convertDtoToIdealPartner(profile.idealPartner), + [profile.idealPartner], + ); + return ( + + + + + + ); } diff --git a/src/entities/ideal_partner/model/convertIdealPartnerToDto.ts b/src/entities/ideal_partner/model/convertIdealPartnerToDto.ts index bbb767b..be1e8f5 100644 --- a/src/entities/ideal_partner/model/convertIdealPartnerToDto.ts +++ b/src/entities/ideal_partner/model/convertIdealPartnerToDto.ts @@ -1,5 +1,5 @@ import { IdealPartner } from 'src/entities/ideal_partner/model/idealPartnerStore'; -import { IdealPartnerRequest, ImageDto } from 'src/types'; +import { DetailedInfoIdealPartner, IdealPartnerRequest, ImageDto } from 'src/types'; export const convertIdealPartnerToDto = (idealPartner: IdealPartner, images: ImageDto[]): IdealPartnerRequest => { return { @@ -19,3 +19,19 @@ export const convertIdealPartnerToDto = (idealPartner: IdealPartner, images: Ima toMatchMaker: idealPartner.toMatchMaker, }; }; + +export const convertDtoToIdealPartner = (dto: DetailedInfoIdealPartner): IdealPartner => { + return { + ageRange: dto.ageRange, + drinking: dto.drinking, + heightRange: dto.heightRange, + hobbies: dto.hobbies?.map((h) => ({ name: h })) ?? [], + images: [], + locations: [], + religion: dto.religion, + requiredOptions: dto.requiredOptions ?? [], + smoking: dto.smoking, + style: dto.style ?? '', + toMatchMaker: dto.toMatchMaker ?? '', + }; +}; diff --git a/src/entities/ideal_partner/model/idealPartnerStore.ts b/src/entities/ideal_partner/model/idealPartnerStore.ts index 3d68f11..256c3f7 100644 --- a/src/entities/ideal_partner/model/idealPartnerStore.ts +++ b/src/entities/ideal_partner/model/idealPartnerStore.ts @@ -6,11 +6,11 @@ import { MAX_IDEAL_HEIGHT, MIN_IDEAL_HEIGHT } from 'src/processes/ideal_partner/ import { DrinkingDrinkingCategory, ReligionReligionCategory, SmokingSmokingCategory } from 'src/types'; export type IdealPartner = { - ageRange: { + ageRange?: { min: number; max: number; }; - heightRange: { + heightRange?: { min: number; max: number; }; @@ -18,17 +18,17 @@ export type IdealPartner = { images: File[]; locations: Location[]; hobbies: Hobby[]; - religion: { + religion?: { religionCategory: ReligionReligionCategory; - religionName: string; + religionName?: string; }; - drinking: { + drinking?: { drinkingCategory: DrinkingDrinkingCategory; - drinkingAmount: string; + drinkingAmount?: string; }; - smoking: { + smoking?: { smokingCategory: SmokingSmokingCategory; - smokingAmount: string; + smokingAmount?: string; }; requiredOptions: string[]; toMatchMaker: string; @@ -99,4 +99,6 @@ const createStoreHook = () => setToMatchMaker: (toMatchMaker) => set({ toMatchMaker }), })); -export const [IdealPartnerProvider, useIdealPartnerStore] = createStoreContext(createStoreHook); +export const [IdealPartnerProvider, useIdealPartnerStore] = createStoreContext( + createStoreHook, +); diff --git a/src/entities/profile/model/convertProfileToDto.ts b/src/entities/profile/model/convertProfileToDto.ts index 6feb8b9..215359d 100644 --- a/src/entities/profile/model/convertProfileToDto.ts +++ b/src/entities/profile/model/convertProfileToDto.ts @@ -1,6 +1,6 @@ import { MyProfile } from 'src/entities/profile/model/myProfileStore'; -import { ImageDto, UserInfoRequest, UserInfoRequestMbti } from 'src/types'; -import { convertDateObjectToDate } from 'src/shared/vo/date'; +import { DetailedInfoUserInfo, ImageDto, UserInfoRequest, UserInfoRequestMbti } from 'src/types'; +import { convertDateObjectToDate, convertDateToDateObject } from 'src/shared/vo/date'; export const convertProfileToDto = (profile: MyProfile, images: ImageDto[]): UserInfoRequest => { return { @@ -29,3 +29,21 @@ export const convertProfileToDto = (profile: MyProfile, images: ImageDto[]): Use pets: [], }; }; + +export const convertDtoToProfile = (dto: DetailedInfoUserInfo): MyProfile => { + return { + birthDate: convertDateToDateObject(new Date(dto.birthDate)), + drinking: dto.drinking, + gender: dto.gender === 'FEAMLE' ? 'FEMALE' : 'MALE', + height: dto.height, + hobbies: dto.hobbies.map((h) => ({ name: h })), + images: [], + introduction: '', + job: dto.job, + location: [], + mbti: dto.mbti, + name: dto.name, + religion: dto.religion, + smoking: dto.smoking, + }; +}; diff --git a/src/entities/profile/model/myProfileStore.tsx b/src/entities/profile/model/myProfileStore.tsx index 4fc4063..03b6d2c 100644 --- a/src/entities/profile/model/myProfileStore.tsx +++ b/src/entities/profile/model/myProfileStore.tsx @@ -113,4 +113,6 @@ const createStoreHook = (initialState?: MyProfile) => }, })); -export const [MyProfileProvider, useMyProfileStore] = createStoreContext(createStoreHook); +export const [MyProfileProvider, useMyProfileStore] = createStoreContext( + createStoreHook, +); diff --git a/src/pages/profile/ProfilePage.tsx b/src/pages/profile/ProfilePage.tsx index 812d841..266ded5 100644 --- a/src/pages/profile/ProfilePage.tsx +++ b/src/pages/profile/ProfilePage.tsx @@ -1,18 +1,20 @@ import { Button } from 'src/shared/ui/Button/Button'; import { PropsWithChildren } from 'react'; import { ArrowLeft, Edit, Share } from 'src/shared/ui/icons'; -import { fullProfileMock } from 'src/entities/profile/api/__mock__/fullProfile.mock'; import { calculateAge, convertDateObjectToDate } from 'src/shared/vo/date'; import { ProfileTab } from 'src/widgets/ProfileTab/ProfileTab'; -import { MockIdealPartner } from 'src/entities/ideal_partner/api/__mock__/idealPartner.mock'; import styles from './ProfilePage.module.css'; import { ScrollView } from 'src/shared/ui/ScrollView/ScrollView'; import { useInView } from 'react-intersection-observer'; +import { useMyProfileStore } from 'src/entities/profile/model/myProfileStore'; +import { useIdealPartnerStore } from 'src/entities/ideal_partner/model/idealPartnerStore'; +import { Link } from '@remix-run/react'; export const ProfilePage = () => { const { ref, inView } = useInView(); - const profile = fullProfileMock; + const profile = useMyProfileStore((state) => state); + const idealPartner = useIdealPartnerStore((state) => state); const age = calculateAge(convertDateObjectToDate(profile.birthDate)); const urls = [ @@ -26,9 +28,11 @@ export const ProfilePage = () => { return (
- - - + + + + + {inView ? ( ) : ( @@ -57,7 +61,7 @@ export const ProfilePage = () => {
- +
diff --git a/src/shared/functions/createStoreContext.tsx b/src/shared/functions/createStoreContext.tsx index d9e786c..876c018 100644 --- a/src/shared/functions/createStoreContext.tsx +++ b/src/shared/functions/createStoreContext.tsx @@ -1,13 +1,15 @@ import { StoreApi, UseBoundStore } from 'zustand'; import { createContext, ReactNode, useContext, useRef } from 'react'; -export const createStoreContext = (createStore: () => UseBoundStore>) => { +export const createStoreContext = ( + createStore: (initialState?: State) => UseBoundStore>, +) => { const Context = createContext> | null>(null); - const Provider = ({ children }: { children: ReactNode }) => { - const storeRef = useRef>>(); + const Provider = ({ children, initialState }: { children: ReactNode; initialState?: State }) => { + const storeRef = useRef>>(); if (!storeRef.current) { - storeRef.current = createStore(); + storeRef.current = createStore(initialState); } return {children}; }; diff --git a/src/shared/vo/date.ts b/src/shared/vo/date.ts index 1208050..76c2137 100644 --- a/src/shared/vo/date.ts +++ b/src/shared/vo/date.ts @@ -16,6 +16,14 @@ export const convertDateObjectToDate = ({ year, month, date }: Partial) return new Date(`${year}-${month}-${date}`); }; +export const convertDateToDateObject = (date: Date): DateObj => { + return { + year: date.getFullYear(), + month: date.getMonth() + 1, + date: date.getDate(), + }; +}; + export const calculateAge = (birthDate: Date) => { return dayjs(Date.now()).diff(birthDate, 'year'); }; diff --git a/src/widgets/ProfileCardList/ProfileCardList.tsx b/src/widgets/ProfileCardList/ProfileCardList.tsx index 20fd570..e8d6edc 100644 --- a/src/widgets/ProfileCardList/ProfileCardList.tsx +++ b/src/widgets/ProfileCardList/ProfileCardList.tsx @@ -12,7 +12,7 @@ export const ProfileCardList = ({ profileList }: Props) => {
    {profileList.map((profile) => (
  • - +