From 811be7ef0930d607bd290632c4fac2166f45b891 Mon Sep 17 00:00:00 2001 From: varkased Date: Wed, 10 Jul 2024 08:04:45 +0700 Subject: [PATCH] feat: add new endpoint to event service and change current update event endpoint implementation (#7) --- .../circle/detail-page/CircleCutSection.tsx | 1 + .../circle/detail-page/EditEventSection.tsx | 61 +++++++++++-------- src/hooks/circle/useUpdateEventByCircleID.ts | 21 +++++++ src/services/event.ts | 24 +++++++- src/types/circle.ts | 24 +------- src/types/common.ts | 14 +++++ src/types/event.ts | 10 ++- 7 files changed, 104 insertions(+), 51 deletions(-) create mode 100644 src/hooks/circle/useUpdateEventByCircleID.ts diff --git a/src/components/circle/detail-page/CircleCutSection.tsx b/src/components/circle/detail-page/CircleCutSection.tsx index e5e33c2..b49d670 100644 --- a/src/components/circle/detail-page/CircleCutSection.tsx +++ b/src/components/circle/detail-page/CircleCutSection.tsx @@ -18,6 +18,7 @@ function CircleCutSection() { base: 'relative w-full border border-neutral-200 bg-white shadow px-4', }} title={

Circle Cut

} + textValue="circle-cut" >
{data?.cover_picture_url ? ( diff --git a/src/components/circle/detail-page/EditEventSection.tsx b/src/components/circle/detail-page/EditEventSection.tsx index 6a2e4a4..5a6e8d8 100644 --- a/src/components/circle/detail-page/EditEventSection.tsx +++ b/src/components/circle/detail-page/EditEventSection.tsx @@ -1,9 +1,11 @@ import EachPageLayout from '@/components/general/EachPageLayout'; import { useGetCircleBySlug } from '@/hooks/circle/useGetCircleBySlug'; -import { useUpdateCircle } from '@/hooks/circle/useUpdateCircle'; +import { useUpdateEventByCircleID } from '@/hooks/circle/useUpdateEventByCircleID'; import { useGetEvents } from '@/hooks/event/useGetEvent'; import ChevronUpIcon from '@/icons/ChevronUpIcon'; -import { dayEnum } from '@/types/circle'; +import XCircleIcon from '@/icons/XCircleIcon'; +import { eventService } from '@/services/event'; +import { dayEnum } from '@/types/common'; import { eventEntity } from '@/types/event'; import { prettifyError } from '@/utils/helper'; import { time } from '@/utils/time'; @@ -30,7 +32,7 @@ import { z } from 'zod'; const editEventSchema = z.object({ event: eventEntity, - day: dayEnum.nullish(), + day: dayEnum.or(z.literal('')).nullish(), block: z .string() .trim() @@ -75,7 +77,6 @@ type EditEventForm = z.infer; const ConfirmationButton = () => { const { isOpen, onOpenChange } = useDisclosure(); const { data: circle } = useGetCircleBySlug(); - const updateEvent = useUpdateCircle(); const router = useRouter(); return ( <> @@ -120,14 +121,9 @@ const ConfirmationButton = () => { onClick={async () => { if (!circle) return; try { - await updateEvent.mutateAsync({ - circleID: circle.id, - payload: { - circle_block: '', - event_id: 0, - day: '', - }, - }); + await eventService.deleteAttendingEventByCircleID( + circle.id, + ); toast.success('Successfully reset attending event'); router.push({ pathname: '/[circleSlug]', @@ -163,7 +159,7 @@ function EditEventSection() { const form = useForm({ resolver: zodResolver(editEventSchema), }); - const updateEvent = useUpdateCircle(); + const updateEvent = useUpdateEventByCircleID(); useEffect(() => { if (initalized || !circle) return; @@ -200,8 +196,8 @@ function EditEventSection() { await updateEvent.mutateAsync({ circleID: circle.id, payload: { - circle_block: val.block ?? undefined, - day: val.day ?? undefined, + circle_block: val.block ?? '', + day: val.day ?? null, event_id: val.event.id, }, }); @@ -287,18 +283,29 @@ function EditEventSection() { render={({ field }) => { const { disabled, value, ...fieldProps } = field; return ( - - First Day - Second Day - Both Days - +
+ + First Day + Second Day + Both Days + + +
); }} /> diff --git a/src/hooks/circle/useUpdateEventByCircleID.ts b/src/hooks/circle/useUpdateEventByCircleID.ts new file mode 100644 index 0000000..3c846c3 --- /dev/null +++ b/src/hooks/circle/useUpdateEventByCircleID.ts @@ -0,0 +1,21 @@ +import { eventService } from '@/services/event'; +import { UpdateAttendingEventBody } from '@/types/event'; +import { useMutation } from '@tanstack/react-query'; + +export const useUpdateEventByCircleID = () => { + return useMutation({ + mutationFn: async ({ + circleID, + payload, + }: { + circleID: number; + payload: UpdateAttendingEventBody; + }) => { + const res = await eventService.putUpdateAttendingEventByCircleID( + circleID, + payload, + ); + return res.data; + }, + }); +}; diff --git a/src/services/event.ts b/src/services/event.ts index 5a8f291..1999d96 100644 --- a/src/services/event.ts +++ b/src/services/event.ts @@ -1,4 +1,8 @@ -import { getEventPaginationSchema } from '@/types/event'; +import { getOneCircleResponse } from '@/types/circle'; +import { + getEventPaginationSchema, + UpdateAttendingEventBody, +} from '@/types/event'; import { fetchInstance } from '@/utils/fetch-wrapper'; export const eventService = { @@ -6,4 +10,22 @@ export const eventService = { const res = await fetchInstance(null, '/v1/event', { params }); return getEventPaginationSchema.parse(res); }, + putUpdateAttendingEventByCircleID: async ( + circleID: number, + body: UpdateAttendingEventBody, + ) => { + const res = await fetchInstance(null, `/v1/circle/${circleID}/event`, { + body, + method: 'PUT', + }); + + return getOneCircleResponse.parse(res); + }, + + deleteAttendingEventByCircleID: async (circleID: number) => { + const res = await fetchInstance(null, `/v1/circle/${circleID}/event`, { + method: 'DELETE', + }); + return getOneCircleResponse.parse(res); + }, }; diff --git a/src/types/circle.ts b/src/types/circle.ts index 0f85832..b9241ad 100644 --- a/src/types/circle.ts +++ b/src/types/circle.ts @@ -2,6 +2,8 @@ import { z } from 'zod'; import { backendResponsePagination, backendResponseSchema, + blockString, + dayEnum, optionalUrl, trimmedString, varchar255, @@ -47,11 +49,8 @@ export const circleBlockEntity = z.object({ name: z.string(), }); -export const dayEnum = z.enum(['first', 'second', 'both']); - export const circleEntity = z.object({ id: z.number(), - batch: z.number().nullable(), created_at: z.string(), updated_at: z.string(), day: dayEnum.nullable(), @@ -100,18 +99,6 @@ export const onboardingPayloadSchema = z.object({ facebook_url: optionalUrl, }); -const blockString = trimmedString.refine( - (x) => { - const split = x.split('-'); - const prefix = split[0]; - const postfix = split[1]; - return split.length === 2 || (prefix.length <= 2 && postfix.length <= 8); - }, - { - message: 'Invalid block format', - }, -); - export const editGeneralInfoPayload = onboardingPayloadSchema.extend({ block: blockString.optional(), file: @@ -150,13 +137,7 @@ export const getAllWorkTypeResponse = backendResponseSchema( export const updateCirclePayload = z.object({ name: varchar255.optional(), - circle_block: blockString.optional(), - /** - * TODO: HTML string validation - */ description: z.string().optional(), - batch: z.number().optional(), - day: dayEnum.or(z.literal('')).optional(), url: optionalUrl.optional(), facebook_url: optionalUrl.optional(), twitter_url: optionalUrl.optional(), @@ -164,7 +145,6 @@ export const updateCirclePayload = z.object({ picture_url: optionalUrl.optional(), fandom_ids: z.array(z.number()).optional(), work_type_ids: z.array(z.number()).optional(), - event_id: z.number().optional(), cover_picture_url: optionalUrl.optional(), }); diff --git a/src/types/common.ts b/src/types/common.ts index 0479cc9..6f5d562 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -41,3 +41,17 @@ export type CommonStoreSetter> = { }; export type SVGS = JSX.IntrinsicElements['svg']; + +export const blockString = trimmedString.refine( + (x) => { + const split = x.split('-'); + const prefix = split[0]; + const postfix = split[1]; + return split.length === 2 || (prefix.length <= 2 && postfix.length <= 8); + }, + { + message: 'Invalid block format', + }, +); + +export const dayEnum = z.enum(['first', 'second', 'both']); diff --git a/src/types/event.ts b/src/types/event.ts index e38c0da..07730ee 100644 --- a/src/types/event.ts +++ b/src/types/event.ts @@ -1,5 +1,5 @@ import { z } from 'zod'; -import { backendResponsePagination } from './common'; +import { backendResponsePagination, blockString, dayEnum } from './common'; export const eventEntity = z.object({ id: z.number(), @@ -11,3 +11,11 @@ export const eventEntity = z.object({ }); export const getEventPaginationSchema = backendResponsePagination(eventEntity); + +export const updateAttendingEventBody = z.object({ + circle_block: blockString.optional(), + day: dayEnum.or(z.literal('')).nullish(), + event_id: z.number(), +}); + +export type UpdateAttendingEventBody = z.infer;