From fe0fbd6af729989d651ee2f3daf6ed4c76e38457 Mon Sep 17 00:00:00 2001 From: HopeFullee Date: Mon, 15 Dec 2025 19:06:50 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=93=B1=EB=A1=9D=20=EC=B5=9C?= =?UTF-8?q?=EB=8C=80=203=EC=9E=A5=20=EC=A0=9C=ED=95=9C,=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/service/group-service/index.ts | 7 +- src/app/post-meetup/page.tsx | 15 ++++- .../post-meetup/fields/images-field/index.tsx | 65 ++++++++++--------- src/types/service/common.ts | 2 +- 4 files changed, 54 insertions(+), 35 deletions(-) diff --git a/src/api/service/group-service/index.ts b/src/api/service/group-service/index.ts index 18a7bc3d..04caa524 100644 --- a/src/api/service/group-service/index.ts +++ b/src/api/service/group-service/index.ts @@ -38,9 +38,6 @@ export const groupServiceRemote = () => ({ }, // 모임 이미지 사전 업로드 (POST /groups/images/upload) - multipart/form-data - uploadGroupImages: (payload: FormData) => { - return api.post('/groups/images/upload', payload); - }, createGroup: (payload: CreateGroupPayload) => { return api.post('/groups/create', payload); @@ -61,4 +58,8 @@ export const groupServiceRemote = () => ({ deleteGroup: (payload: GroupIdPayload) => { return api.delete(`/groups/${payload.groupId}`); }, + + uploadGroupImages: (payload: FormData) => { + return api.post('/groups/images/upload', payload); + }, }); diff --git a/src/app/post-meetup/page.tsx b/src/app/post-meetup/page.tsx index 216e061c..59ac31cc 100644 --- a/src/app/post-meetup/page.tsx +++ b/src/app/post-meetup/page.tsx @@ -15,7 +15,7 @@ import { MeetupTitleField, } from '@/components/pages/post-meetup'; import { useCreateGroup } from '@/hooks/use-group/use-group-create'; -import { CreateGroupPayload } from '@/types/service/group'; +import { CreateGroupPayload, PreUploadGroupImageResponse } from '@/types/service/group'; const PostMeetupPage = () => { const { replace } = useRouter(); @@ -35,7 +35,18 @@ const PostMeetupPage = () => { images: [], } as CreateGroupPayload, onSubmit: async ({ value }) => { - const res = await createGroup(value); + const images = [] as PreUploadGroupImageResponse['images']; + + if (value.images) { + value.images.forEach((image, idx) => { + images.push({ + ...image, + sortOrder: idx, + }); + }); + } + + const res = await createGroup({ ...value, images: images }); replace(`/meetup/${res.id}`); }, }); 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 05cddd27..b26aa0b0 100644 --- a/src/components/pages/post-meetup/fields/images-field/index.tsx +++ b/src/components/pages/post-meetup/fields/images-field/index.tsx @@ -20,8 +20,11 @@ export const MeetupImagesField = ({ field }: Props) => { const { mutateAsync } = useUploadGroupImages(); const onUploadImage = async (e: React.ChangeEvent) => { + const maxAllowed = 3 - field.state.value.length; const files = e.target.files; + if (!files || files.length === 0) return; + if (files.length > maxAllowed) return; const fileArray = Array.from(files); @@ -29,7 +32,7 @@ export const MeetupImagesField = ({ field }: Props) => { const invalidFile = fileArray.find((file) => !ALLOWED_IMAGE_TYPES.includes(file.type as any)); if (invalidFile) { - alert('jpg 또는 png 파일만 업로드 가능합니다.'); + alert('jpg, png, webp 파일만 업로드 가능합니다.'); e.target.value = ''; return; } @@ -38,17 +41,19 @@ export const MeetupImagesField = ({ field }: Props) => { images: fileArray, }); - field.handleChange([...response.images]); + field.handleChange([...field.state.value, ...response.images]); }; const onUploadImageButtonClick = () => { - if (!inputRef.current) { - return; - } - + if (!inputRef.current) return; inputRef.current.click(); }; + const onRemoveImageClick = (removeIdx: number) => { + const removedArray = field.state.value.filter(({}, idx: number) => idx !== removeIdx); + field.handleChange(removedArray); + }; + const inputRef = useRef(null); return ( @@ -81,29 +86,31 @@ export const MeetupImagesField = ({ field }: Props) => { onChange={(e) => onUploadImage(e)} /> - {field.state.value.map(({ imageUrl100x100 }: PreUploadGroupImageResponse['images'][0]) => ( -
- 썸네일 이미지 - - {/* */} -
- ))} + {field.state.value.map( + ({ imageUrl100x100 }: PreUploadGroupImageResponse['images'][0], idx: number) => ( +
+ 썸네일 이미지 + + +
+ ), + )}

최대 3개까지 업로드할 수 있어요.

diff --git a/src/types/service/common.ts b/src/types/service/common.ts index 1756185a..7361141b 100644 --- a/src/types/service/common.ts +++ b/src/types/service/common.ts @@ -13,4 +13,4 @@ export interface CommonSuccessResponse { data: T; } -export const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png'] as const; +export const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/webp'] as const;