diff --git a/src/app/meeting/_features/form/MeetingForm.tsx b/src/app/meeting/_features/form/MeetingForm.tsx index 721549f..acd5c46 100644 --- a/src/app/meeting/_features/form/MeetingForm.tsx +++ b/src/app/meeting/_features/form/MeetingForm.tsx @@ -14,6 +14,7 @@ import { TechStackField, TitleField, } from '@/app/meeting/_features/form/form-filed'; +import { useToast } from '@/components/common/ToastContext'; import useMeetingFormMutation from '@/hooks/mutations/useMeetingFormMutation'; import { convertImageToBase64 } from '@/util/base64'; import { MEETING_TYPES } from 'constants/category/category'; @@ -34,7 +35,7 @@ export default function MeetingForm({ meetingId, }: MeetingFormProps) { const router = useRouter(); - const { createMeeting, isLoading } = useMeetingFormMutation(); + const { showToast } = useToast(); // 날짜 YYYY-MM-DD 형식으로 변환 const today = new Date(); @@ -46,6 +47,28 @@ export default function MeetingForm({ return category ? category.id : ''; }; + const { createMeeting, isLoading } = useMeetingFormMutation({ + onSuccessCallback: (response, formData) => { + if (mode === 'create') { + showToast('모임이 성공적으로 생성되었습니다', 'success', { + duration: 3000, + }); + const categoryId = getCategoryId(formData.categoryTitle); + router.push(`/meeting/${categoryId}/${response.data.meetingId}`); + } else if (mode === 'edit') { + showToast('모임이 성공적으로 수정되었습니다', 'success'); + const categoryId = getCategoryId(formData.categoryTitle); + router.push(`/meeting/${categoryId}/${meetingId}`); + } + }, + onErrorCallback: () => { + // 실패 시 토스트 표시 + showToast('모임 생성에 실패했습니다', 'error', { + duration: 3000, + }); + }, + }); + const defaultValues: CreateMeetingPayload = { meetingTitle: '', categoryTitle: '', @@ -67,30 +90,22 @@ export default function MeetingForm({ const { handleSubmit } = methods; - const onSubmit = async (data: CreateMeetingPayload) => { + const onSubmit = async (formData: CreateMeetingPayload) => { try { // 이미지 처리 const fileInput = document.getElementById('image') as HTMLInputElement; if (fileInput?.files && fileInput.files.length > 0) { const imageData = await convertImageToBase64(fileInput.files[0]); - data.imageName = imageData.name; - data.imageEncodedBase64 = imageData.base64; + formData.imageName = imageData.name; + formData.imageEncodedBase64 = imageData.base64; } if (mode === 'create') { - // 모임 생성 - const result = await createMeeting.mutateAsync(data); - - // 성공 시 상세 페이지로 이동 - const categoryId = getCategoryId(data.categoryTitle); - router.push(`/meeting/${categoryId}/${result.data.meetingId}`); + await createMeeting.mutateAsync(formData); } else if (mode === 'edit' && meetingId) { // 모임 수정 (TODO: API 구현 시 수정) - // const result = await updateMeeting.mutateAsync({ id: meetingId, data }); - - // 수정 성공 시 상세 페이지로 이동 - const categoryId = getCategoryId(data.categoryTitle); - router.push(`/meeting/${categoryId}/${meetingId}`); + // await updateMeeting.mutateAsync({ id: meetingId, data: formData }); + // API가 구현되지 않았으므로 수정 성공으로 처리 } } catch (error) {} }; diff --git a/src/hooks/mutations/useMeetingFormMutation.ts b/src/hooks/mutations/useMeetingFormMutation.ts index 8899887..e2c20e8 100644 --- a/src/hooks/mutations/useMeetingFormMutation.ts +++ b/src/hooks/mutations/useMeetingFormMutation.ts @@ -2,12 +2,31 @@ import { authAPI } from '@/lib/axios/authApi'; import { useMutation } from '@tanstack/react-query'; import { meetingURL } from 'service/api/endpoints'; import { CreateMeetingPayload } from 'types/meetingForm'; +import { CreateMeetingResponse } from 'types/meetingForm'; -const useMeetingFormMutation = () => { +const useMeetingFormMutation = ({ + onSuccessCallback, + onErrorCallback, +}: { + onSuccessCallback: ( + response: CreateMeetingResponse, + formData: CreateMeetingPayload, + ) => void; + onErrorCallback: (error: unknown) => void; +}) => { const createMeeting = useMutation({ - mutationFn: async (data: CreateMeetingPayload) => { - const response = await authAPI.post(meetingURL.create, data); - return response.data; + mutationFn: async (formData: CreateMeetingPayload) => { + const response = await authAPI.post( + meetingURL.create, + formData, + ); + return { response: response.data, formData }; + }, + onSuccess: (data) => { + onSuccessCallback(data.response, data.formData); + }, + onError: (error) => { + onErrorCallback(error); }, }); diff --git a/src/types/meetingForm.ts b/src/types/meetingForm.ts index 31f384c..2037c87 100644 --- a/src/types/meetingForm.ts +++ b/src/types/meetingForm.ts @@ -11,3 +11,11 @@ export interface CreateMeetingPayload { requireApproval: boolean; skillArray: string[]; } + +export interface CreateMeetingResponse { + statusCode: number; + data: { + meetingId: number; + }; + timestamp: string; +}