diff --git a/src/api/service/group-service/index.ts b/src/api/service/group-service/index.ts index d6af4e22..1c2d5ec0 100644 --- a/src/api/service/group-service/index.ts +++ b/src/api/service/group-service/index.ts @@ -39,30 +39,10 @@ export const groupServiceRemote = () => ({ }, // 모임 이미지 사전 업로드 (POST /groups/images/upload) - multipart/form-data - uploadGroupImages: async ( - payload: PreUploadGroupImagePayload, - ): Promise => { - const formData = new FormData(); - payload.images.forEach((file) => { - if (file instanceof File) { - formData.append('images', file); - } else { - console.error('[이미지 업로드 오류] File 객체가 아닌 값이 포함됨:', file); - throw new Error('이미지 파일은 File 객체여야 합니다.'); - } + uploadGroupImages: (payload: PreUploadGroupImagePayload) => { + return api.post('/groups/images/upload', payload, { + headers: { 'Content-Type': 'multipart/form-data' }, }); - - const response = await api.post( - '/groups/images/upload', - formData, - { - headers: { - 'Content-Type': 'multipart/form-data', - }, - }, - ); - - return response; }, createGroup: (payload: CreateGroupPayload) => { diff --git a/src/app/post-meetup/page.tsx b/src/app/post-meetup/page.tsx index 424759e8..fa9f3219 100644 --- a/src/app/post-meetup/page.tsx +++ b/src/app/post-meetup/page.tsx @@ -1,5 +1,7 @@ 'use client'; +import { useRouter } from 'next/navigation'; + import { useForm } from '@tanstack/react-form'; import { @@ -12,14 +14,13 @@ import { MeetupTagsField, MeetupTitleField, } from '@/components/pages/post-meetup'; -import { ImageRecord } from '@/components/ui'; import { useCreateGroup } from '@/hooks/use-group/use-group-create'; -import { useUploadGroupImages } from '@/hooks/use-group/use-upload-group-images'; import { CreateGroupPayload } from '@/types/service/group'; const PostMeetupPage = () => { + const { replace } = useRouter(); + const { mutateAsync: createGroup } = useCreateGroup(); - const { mutateAsync: uploadImages } = useUploadGroupImages(); const form = useForm({ defaultValues: { @@ -28,46 +29,14 @@ const PostMeetupPage = () => { locationDetail: '', startTime: '', endTime: '', - tags: [] as string[], + tags: [], description: '', maxParticipants: 0, - images: {} as ImageRecord, - }, + images: [], + } as CreateGroupPayload, onSubmit: async ({ value }) => { - const imageRecords = value.images as ImageRecord; - const imageFiles = Object.values(imageRecords).filter( - (file): file is File => file !== null && file instanceof File, - ); - - // 이미지가 있으면 먼저 업로드하여 URL 배열 수확 - let uploadedImages = null; - if (imageFiles.length > 0) { - const uploadResponse = await uploadImages({ images: imageFiles }); - uploadedImages = uploadResponse.images; - } - - if (!value.startTime) { - throw new Error('모임 시작 시간을 입력해주세요.'); - } - - const maxParticipantsNumber = Number(value.maxParticipants); - if (isNaN(maxParticipantsNumber) || maxParticipantsNumber < 1) { - throw new Error('모임 최대 인원은 1명 이상이어야 합니다.'); - } - - const createPayload: CreateGroupPayload = { - title: value.title.trim(), - location: value.location.trim(), - locationDetail: value.locationDetail?.trim() || null, - startTime: value.startTime, - ...(value.endTime && { endTime: value.endTime }), - tags: value.tags && value.tags.length > 0 ? value.tags : null, - description: value.description.trim(), - maxParticipants: maxParticipantsNumber, - images: uploadedImages && uploadedImages.length > 0 ? uploadedImages : null, - }; - - await createGroup(createPayload); + const res = await createGroup(value); + replace(`/meetup/${res.id}`); }, }); diff --git a/src/components/pages/meetup/meetup-modal/index.tsx b/src/components/pages/meetup/meetup-modal/index.tsx index 6427a642..bb8c9ef9 100644 --- a/src/components/pages/meetup/meetup-modal/index.tsx +++ b/src/components/pages/meetup/meetup-modal/index.tsx @@ -64,18 +64,15 @@ const MODAL_MESSAGE = { title: '모임에 참여하시겠어요?', description: '참여 후 바로 그룹채팅에 참여할 수 있어요!', confirm: '참여하기', - onConfirm: (attendMutate: () => void) => attendMutate(), }, cancel: { title: '모임을 정말 탈퇴하시겠어요?', description: '탈퇴 시 그룹채팅과 모임 활동이 종료돼요.', confirm: '탈퇴하기', - onConfirm: (cancelMutate: () => void) => cancelMutate(), }, delete: { title: '모임을 정말 취소하시겠어요?', description: '취소 후에는 다시 복구할 수 없어요.', confirm: '취소하기', - onConfirm: (deleteMutate: () => void) => deleteMutate(), }, }; diff --git a/src/components/pages/post-meetup/fields/images-field/index.tsx b/src/components/pages/post-meetup/fields/images-field/index.tsx index a8dda984..a6f7c076 100644 --- a/src/components/pages/post-meetup/fields/images-field/index.tsx +++ b/src/components/pages/post-meetup/fields/images-field/index.tsx @@ -8,10 +8,9 @@ import { Icon } from '@/components/icon'; import { ImageInput, ImageInputProps } from '@/components/ui'; import { cn } from '@/lib/utils'; -type ImageUploadPropsWithoutChildren = Omit; - -interface Props extends ImageUploadPropsWithoutChildren { +interface Props { field: AnyFieldApi; + initialImages?: ImageInputProps['initialImages']; } export const MeetupImagesField = ({ field, initialImages }: Props) => { @@ -62,6 +61,7 @@ export const MeetupImagesField = ({ field, initialImages }: Props) => { 'transition-all duration-300', // animation 스타일 )} aria-label='이미지 삭제 버튼' + type='button' onClick={() => onRemoveImageClick(url)} > diff --git a/src/components/pages/post-meetup/modals/date-picker-modal/index.tsx b/src/components/pages/post-meetup/modals/date-picker-modal/index.tsx index fc2612f3..cbabcd61 100644 --- a/src/components/pages/post-meetup/modals/date-picker-modal/index.tsx +++ b/src/components/pages/post-meetup/modals/date-picker-modal/index.tsx @@ -7,13 +7,14 @@ import clsx from 'clsx'; import { Icon } from '@/components/icon'; import { Calendar } from '@/components/pages/post-meetup/modals/date-picker-modal/calendar'; -import { ModalContent, ModalTitle } from '@/components/ui'; +import { Button, ModalContent, ModalTitle, useModal } from '@/components/ui'; interface Props { dateField: AnyFieldApi; } export const DatePickerModal = ({ dateField }: Props) => { + const { close } = useModal(); const [tabMenu, setTabMenu] = useState<'date' | 'time'>('date'); return ( @@ -45,17 +46,10 @@ export const DatePickerModal = ({ dateField }: Props) => { updateDateField={(selectedDate: string) => dateField.handleChange(selectedDate)} /> -
- - +
diff --git a/src/hooks/use-group/use-group-create/index.ts b/src/hooks/use-group/use-group-create/index.ts index 9f9eaf14..348fb147 100644 --- a/src/hooks/use-group/use-group-create/index.ts +++ b/src/hooks/use-group/use-group-create/index.ts @@ -7,7 +7,6 @@ export const useCreateGroup = () => { const query = useMutation({ mutationFn: (payload: CreateGroupPayload) => API.groupService.createGroup(payload), onSuccess: () => { - // 상세 페이지 이동할거라 목록 캐시를 갱신할 이유가 없음 (GPT 피셜) console.log('모임 생성 성공.'); }, onError: () => { diff --git a/src/hooks/use-group/use-upload-group-images/index.ts b/src/hooks/use-group/use-upload-group-images/index.ts deleted file mode 100644 index bbd4f885..00000000 --- a/src/hooks/use-group/use-upload-group-images/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { useMutation } from '@tanstack/react-query'; - -import { API } from '@/api'; -import { PreUploadGroupImagePayload } from '@/types/service/group'; - -export const useUploadGroupImages = () => { - const query = useMutation({ - mutationFn: (payload: PreUploadGroupImagePayload) => - API.groupService.uploadGroupImages(payload), - }); - return query; -};