Skip to content

Commit

Permalink
[FE] Feat #133: Bucket 정보 zustand state를 한번에 추가할 수 있는 메서드 개발
Browse files Browse the repository at this point in the history
Change-Id: I42c55e5744b9dca4a0697d756557217a23f1dce8
  • Loading branch information
leewooseong committed Feb 13, 2024
1 parent c18d6d1 commit efcc2ab
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 24 deletions.
4 changes: 3 additions & 1 deletion frontend/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,16 @@ 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
title: string
timeCapsule: string | null
bucketPicture: string | null
color: ColorType
reminderDate: null | 'oneDay' | 'oneWeek' | 'twoWeeks' | 'oneMonth' | 'oneYear'
reminderDate: PeriodType
latitude: number
longitude: number
address: string
Expand Down
Original file line number Diff line number Diff line change
@@ -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: '없음',
Expand All @@ -14,6 +16,15 @@ const periodData = {
const RemindPeriod = () => {
const { period, changePeriod } = useBucketStore()

const handleChangePeriod = (event: MouseEvent<HTMLButtonElement>) => {
const { period } = event.currentTarget.dataset
if (period === 'none') {
changePeriod(null)
} else if (period) {
changePeriod(period as PeriodType)
}
}

return (
<div>
<p className="mb-[14px] text-sm font-bold ml-[2px]">리마인드 주기</p>
Expand All @@ -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']}
</Menu.Button>
<Transition
enter="transition duration-100 ease-out"
Expand All @@ -42,10 +53,11 @@ const RemindPeriod = () => {
<Menu.Item key={key}>
{({ active }) => (
<button
data-period={key}
className={`${
active ? 'bg-gray-100' : 'text-gray-900'
} group flex w-full items-center px-2 py-2 text-sm`}
onClick={() => changePeriod(key as PeriodType)}
onClick={handleChangePeriod}
>
{value}
</button>
Expand Down
84 changes: 72 additions & 12 deletions frontend/src/store/bucketStore.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -13,7 +13,9 @@ import {
IPeriodSlice,
IStartDateSlice,
ITimeCapsuleSlice,
PeriodType,
IResetStateSlice,
IAddStateSlice,
ImageUrlType,
} from '../types/bucket'

declare module 'zustand' {
Expand Down Expand Up @@ -42,7 +44,7 @@ const createSelectedCategorySlice: SlicePattern<ICategorySlice> = (set) => ({
}),
})

const createBucketColorSlice: StateCreator<IBucketColorSlice> = (set) => ({
const createBucketColorSlice: SlicePattern<IBucketColorSlice> = (set) => ({
bucketColor: null,
changeBucketColor: (color: ColorType) =>
set(() => {
Expand All @@ -54,7 +56,7 @@ const createBucketColorSlice: StateCreator<IBucketColorSlice> = (set) => ({
}),
})

const createBucketTitleSlice: StateCreator<IBucketTitleSlice> = (set) => ({
const createBucketTitleSlice: SlicePattern<IBucketTitleSlice> = (set) => ({
bucketTitle: '',
changeBucketTitle: (text: string) =>
set(() => {
Expand All @@ -66,7 +68,7 @@ const createBucketTitleSlice: StateCreator<IBucketTitleSlice> = (set) => ({
}),
})

const createTimeCapsuleSlice: StateCreator<ITimeCapsuleSlice> = (set) => ({
const createTimeCapsuleSlice: SlicePattern<ITimeCapsuleSlice> = (set) => ({
timeCapsule: '',
changeTimeCapsule: (text: string) =>
set(() => {
Expand All @@ -78,9 +80,9 @@ const createTimeCapsuleSlice: StateCreator<ITimeCapsuleSlice> = (set) => ({
}),
})

const createBucketImageSlice: StateCreator<IBucketImageSlice> = (set) => ({
const createBucketImageSlice: SlicePattern<IBucketImageSlice> = (set) => ({
bucketImage: null,
changeBucketImage: (image: File) =>
changeBucketImage: (image: File | ImageUrlType | null) =>
set(() => {
return { bucketImage: image }
}),
Expand All @@ -90,9 +92,9 @@ const createBucketImageSlice: StateCreator<IBucketImageSlice> = (set) => ({
}),
})

const createStartDateSlice: StateCreator<IStartDateSlice> = (set) => ({
const createStartDateSlice: SlicePattern<IStartDateSlice> = (set) => ({
createdDate: startOfToday(),
changeCreatedDate: (date: Date) =>
changeCreatedDate: (date: Date | string) =>
set(() => {
return { createdDate: date }
}),
Expand All @@ -102,7 +104,7 @@ const createStartDateSlice: StateCreator<IStartDateSlice> = (set) => ({
}),
})

const createPeriodSlice: StateCreator<IPeriodSlice> = (set) => ({
const createPeriodSlice: SlicePattern<IPeriodSlice> = (set) => ({
period: 'twoWeeks',
changePeriod: (period: PeriodType) =>
set(() => {
Expand All @@ -114,7 +116,7 @@ const createPeriodSlice: StateCreator<IPeriodSlice> = (set) => ({
}),
})

const createIsPrivateSlice: StateCreator<IIsPrivateSlice> = (set) => ({
const createIsPrivateSlice: SlicePattern<IIsPrivateSlice> = (set) => ({
isPrivate: false,
changeIsPrivate: (privateValue: boolean) =>
set(() => {
Expand All @@ -126,6 +128,60 @@ const createIsPrivateSlice: StateCreator<IIsPrivateSlice> = (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
// - 버킷 생성
// - 상세 버킷 조회
Expand All @@ -137,7 +193,9 @@ export const useBucketStore = create<
IBucketImageSlice &
IStartDateSlice &
IPeriodSlice &
IIsPrivateSlice
IIsPrivateSlice &
IResetStateSlice &
IAddStateSlice
>()(
devtools(
immer((...a) => ({
Expand All @@ -149,6 +207,8 @@ export const useBucketStore = create<
...createStartDateSlice(...a),
...createPeriodSlice(...a),
...createIsPrivateSlice(...a),
...resetAllSlices(...a),
...addBucketInfoSlices(...a),
}))
)
)
22 changes: 15 additions & 7 deletions frontend/src/types/bucket.d.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
}

Expand All @@ -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<ReactionType, number>
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/utils/typeFilter.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -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
}

0 comments on commit efcc2ab

Please sign in to comment.