diff --git a/frontend/src/interfaces.ts b/frontend/src/interfaces.ts index 5bd8ea06..c862c9fa 100644 --- a/frontend/src/interfaces.ts +++ b/frontend/src/interfaces.ts @@ -95,6 +95,8 @@ export interface IProfileUserInfo extends IBaseUserInfo, ITitleBucket {} export type UserInfoType = IMyUserInfo | IOtherUserInfo | IProfileUserInfo +export type PeriodType = null | 'oneDay' | 'oneWeek' | 'twoWeeks' | 'oneMonth' | 'oneYear' + export interface IBucketInfo { writerId: number reviewId: number | null @@ -102,7 +104,7 @@ export interface IBucketInfo { timeCapsule: string | null bucketPicture: string | null color: ColorType - reminderDate: null | 'oneDay' | 'oneWeek' | 'twoWeeks' | 'oneMonth' | 'oneYear' + reminderDate: PeriodType latitude: number longitude: number address: string diff --git a/frontend/src/pages/Bucket/AddBucket/AdditionalInfo/component/RemindPeriod.tsx b/frontend/src/pages/Bucket/AddBucket/AdditionalInfo/component/RemindPeriod.tsx index 71b69805..b7ce11e7 100644 --- a/frontend/src/pages/Bucket/AddBucket/AdditionalInfo/component/RemindPeriod.tsx +++ b/frontend/src/pages/Bucket/AddBucket/AdditionalInfo/component/RemindPeriod.tsx @@ -1,6 +1,8 @@ import { Menu, Transition } from '@headlessui/react' import { useBucketStore } from '../../../../../store/bucketStore' -import { PeriodType } from '../../../../../types/bucket' +import { isValidatePeriod } from '../../../../../utils/typeFilter' +import { MouseEvent } from 'react' +import { PeriodType } from '../../../../../interfaces' const periodData = { none: '없음', @@ -14,6 +16,15 @@ const periodData = { const RemindPeriod = () => { const { period, changePeriod } = useBucketStore() + const handleChangePeriod = (event: MouseEvent) => { + const { period } = event.currentTarget.dataset + if (period === 'none') { + changePeriod(null) + } else if (period) { + changePeriod(period as PeriodType) + } + } + return (

리마인드 주기

@@ -24,7 +35,7 @@ const RemindPeriod = () => { after:content-clockImage after:inline-block after:h-[19px] after:absolute after:right-4 after:translate-y-1/2 after:bottom-1/2 " > - {period && periodData[period]} + {isValidatePeriod(period) ? periodData[period] : periodData['none']} { {({ active }) => ( diff --git a/frontend/src/store/bucketStore.ts b/frontend/src/store/bucketStore.ts index b61ccdc8..330196d3 100644 --- a/frontend/src/store/bucketStore.ts +++ b/frontend/src/store/bucketStore.ts @@ -1,6 +1,6 @@ import { create, SlicePattern, StateCreator } from 'zustand' import { devtools } from 'zustand/middleware' -import { ColorType } from '../interfaces' +import { ColorType, IBucketInfo, PeriodType } from '../interfaces' import { defaultCategories } from '../utils/category' import { immer } from 'zustand/middleware/immer' import { startOfToday } from 'date-fns' @@ -13,7 +13,9 @@ import { IPeriodSlice, IStartDateSlice, ITimeCapsuleSlice, - PeriodType, + IResetStateSlice, + IAddStateSlice, + ImageUrlType, } from '../types/bucket' declare module 'zustand' { @@ -42,7 +44,7 @@ const createSelectedCategorySlice: SlicePattern = (set) => ({ }), }) -const createBucketColorSlice: StateCreator = (set) => ({ +const createBucketColorSlice: SlicePattern = (set) => ({ bucketColor: null, changeBucketColor: (color: ColorType) => set(() => { @@ -54,7 +56,7 @@ const createBucketColorSlice: StateCreator = (set) => ({ }), }) -const createBucketTitleSlice: StateCreator = (set) => ({ +const createBucketTitleSlice: SlicePattern = (set) => ({ bucketTitle: '', changeBucketTitle: (text: string) => set(() => { @@ -66,7 +68,7 @@ const createBucketTitleSlice: StateCreator = (set) => ({ }), }) -const createTimeCapsuleSlice: StateCreator = (set) => ({ +const createTimeCapsuleSlice: SlicePattern = (set) => ({ timeCapsule: '', changeTimeCapsule: (text: string) => set(() => { @@ -78,9 +80,9 @@ const createTimeCapsuleSlice: StateCreator = (set) => ({ }), }) -const createBucketImageSlice: StateCreator = (set) => ({ +const createBucketImageSlice: SlicePattern = (set) => ({ bucketImage: null, - changeBucketImage: (image: File) => + changeBucketImage: (image: File | ImageUrlType | null) => set(() => { return { bucketImage: image } }), @@ -90,9 +92,9 @@ const createBucketImageSlice: StateCreator = (set) => ({ }), }) -const createStartDateSlice: StateCreator = (set) => ({ +const createStartDateSlice: SlicePattern = (set) => ({ createdDate: startOfToday(), - changeCreatedDate: (date: Date) => + changeCreatedDate: (date: Date | string) => set(() => { return { createdDate: date } }), @@ -102,7 +104,7 @@ const createStartDateSlice: StateCreator = (set) => ({ }), }) -const createPeriodSlice: StateCreator = (set) => ({ +const createPeriodSlice: SlicePattern = (set) => ({ period: 'twoWeeks', changePeriod: (period: PeriodType) => set(() => { @@ -114,7 +116,7 @@ const createPeriodSlice: StateCreator = (set) => ({ }), }) -const createIsPrivateSlice: StateCreator = (set) => ({ +const createIsPrivateSlice: SlicePattern = (set) => ({ isPrivate: false, changeIsPrivate: (privateValue: boolean) => set(() => { @@ -126,6 +128,60 @@ const createIsPrivateSlice: StateCreator = (set) => ({ }), }) +const addBucketInfoSlices: StateCreator< + ICategorySlice & + IBucketColorSlice & + IBucketTitleSlice & + ITimeCapsuleSlice & + IBucketImageSlice & + IStartDateSlice & + IPeriodSlice & + IIsPrivateSlice & + IAddStateSlice, + [['zustand/immer', never], ['zustand/devtools', never]], + [], + IAddStateSlice +> = (set, get) => ({ + addBucketState: (bucketInfo: IBucketInfo) => { + get().resetCategory() // 객체 형식이기 때문에 reset이 필요 + + bucketInfo.category.forEach((category) => get().addCategory(category)) + get().changeBucketColor(bucketInfo.color) + get().changeBucketTitle(bucketInfo.title) + get().changeTimeCapsule(bucketInfo.timeCapsule ? bucketInfo.timeCapsule : '') + get().changeBucketImage(bucketInfo.bucketPicture) + get().changeCreatedDate(bucketInfo.createdDate) + get().changePeriod(bucketInfo.reminderDate) + get().changeIsPrivate(bucketInfo.isPrivate) + }, +}) + +const resetAllSlices: StateCreator< + ICategorySlice & + IBucketColorSlice & + IBucketTitleSlice & + ITimeCapsuleSlice & + IBucketImageSlice & + IStartDateSlice & + IPeriodSlice & + IIsPrivateSlice & + IResetStateSlice, + [['zustand/immer', never], ['zustand/devtools', never]], + [], + IResetStateSlice +> = (set, get) => ({ + resetAllState: () => { + get().resetCategory() + get().resetBucketColor() + get().resetBucketTitle() + get().resetTimeCapsule() + get().resetBucketImage() + get().resetCreatedDate() + get().resetPeriod() + get().resetIsPrivate() + }, +}) + // 버킷 정보를 관리하는 전역 State // - 버킷 생성 // - 상세 버킷 조회 @@ -137,7 +193,9 @@ export const useBucketStore = create< IBucketImageSlice & IStartDateSlice & IPeriodSlice & - IIsPrivateSlice + IIsPrivateSlice & + IResetStateSlice & + IAddStateSlice >()( devtools( immer((...a) => ({ @@ -149,6 +207,8 @@ export const useBucketStore = create< ...createStartDateSlice(...a), ...createPeriodSlice(...a), ...createIsPrivateSlice(...a), + ...resetAllSlices(...a), + ...addBucketInfoSlices(...a), })) ) ) diff --git a/frontend/src/types/bucket.d.ts b/frontend/src/types/bucket.d.ts index afb2cecf..74877b5c 100644 --- a/frontend/src/types/bucket.d.ts +++ b/frontend/src/types/bucket.d.ts @@ -1,6 +1,4 @@ -import { CategoryType, ColorType, selectedInfoType } from '../interfaces' - -export type PeriodType = 'none' | 'oneDay' | 'oneWeek' | 'twoWeeks' | 'oneMonth' | 'oneYear' +import { CategoryType, ColorType, IBucketInfo, PeriodType, selectedInfoType } from '../interfaces' export interface ICategorySlice { // State @@ -29,15 +27,17 @@ export interface ITimeCapsuleSlice { resetTimeCapsule: () => void } +type ImageUrlType = string + export interface IBucketImageSlice { - bucketImage: File | null - changeBucketImage: (image: File) => void + bucketImage: File | ImageUrlType | null + changeBucketImage: (image: File | ImageUrlType | null) => void resetBucketImage: () => void } export interface IStartDateSlice { - createdDate: Date - changeCreatedDate: (date: Date) => void + createdDate: Date | string + changeCreatedDate: (date: Date | string) => void resetCreatedDate: () => void } @@ -53,6 +53,14 @@ export interface IIsPrivateSlice { resetIsPrivate: () => void } +export interface IResetStateSlice { + resetAllState: () => void +} + +export interface IAddStateSlice { + addBucketState: (bucket: IBucketInfo) => void +} + // :: Reaction export type ReactionType = '멋져요' | '응원해요' | '나도할래' export type ReactionCountType = Record diff --git a/frontend/src/utils/typeFilter.ts b/frontend/src/utils/typeFilter.ts index 5e1d5309..16fca09b 100644 --- a/frontend/src/utils/typeFilter.ts +++ b/frontend/src/utils/typeFilter.ts @@ -1,5 +1,5 @@ import { categoryData } from './category' -import { CategoryType, ColorType, IMyUserInfo, IOtherUserInfo } from '../interfaces' +import { CategoryType, ColorType, IMyUserInfo, IOtherUserInfo, PeriodType } from '../interfaces' import { IProfileUserInfo } from './../interfaces' import { ReactionType } from '../types/bucket' @@ -46,3 +46,9 @@ export const isColorType = (input: string): input is ColorType => { export const isReactionType = (reaction: string): reaction is ReactionType => { return reaction === '멋져요' || reaction === '응원해요' || reaction === '나도할래' } + +export const isValidatePeriod = ( + period: PeriodType +): period is 'oneDay' | 'oneWeek' | 'twoWeeks' | 'oneMonth' | 'oneYear' => { + return period !== null +}