11import { zodResolver } from '@hookform/resolvers/zod' ;
2- import { uploadImage } from '@shared/apis/image' ;
2+ import { uploadImages } from '@shared/apis/image' ;
33import { useCreateSellPostMutation , useSellAutocompleteQuery , useUpdateSellPostMutation } from '@shared/apis/sell' ;
44import { ROUTES } from '@shared/constants' ;
55import { useClickOutside , useDebounce , useScrollToError , useToast } from '@shared/hooks' ;
@@ -19,12 +19,12 @@ export const useSellForm = () => {
1919 const createSellPostMutation = useCreateSellPostMutation ( ) ;
2020 const locationState = useMemo ( ( ) => ( location . state ?? { } ) as SellState , [ location . state ] ) ;
2121 const editPostId = locationState . postId ?? null ;
22- const existingImageUrl = locationState . imageUrl ?? null ;
22+ const existingImageUrls = locationState . imageUrls ?? ( locationState . imageUrl ? [ locationState . imageUrl ] : [ ] ) ;
2323 const updateSellPostMutation = useUpdateSellPostMutation ( editPostId ?? '' ) ;
2424 const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
2525 const isEditMode = Boolean ( editPostId ) ;
2626 const { scrollToFirstError } = useScrollToError < SellFormData > ( [
27- 'imageFile ' ,
27+ 'imageFiles ' ,
2828 'title' ,
2929 'manufacturer' ,
3030 'modelName' ,
@@ -42,7 +42,6 @@ export const useSellForm = () => {
4242 control,
4343 handleSubmit,
4444 reset,
45- resetField,
4645 setError,
4746 setValue,
4847 watch,
@@ -74,10 +73,9 @@ export const useSellForm = () => {
7473 setIsModelAutocompleteOpen ( false ) ;
7574 } ;
7675
77- const { previewUrl , setPreviewUrl , handleImageChange } = useSellImage ( {
76+ const { images , handleImageChange , removeImage , setExistingImages , canAddMore } = useSellImage ( {
7877 showToast,
7978 setError,
80- resetField,
8179 setValue,
8280 } ) ;
8381
@@ -113,34 +111,43 @@ export const useSellForm = () => {
113111 return ;
114112 }
115113 reset ( mapSellDraftToForm ( locationState ) ) ;
116- if ( locationState . imageFile ) {
117- setValue ( 'imageFile' , locationState . imageFile , { shouldValidate : true } ) ;
118- } else {
119- resetField ( 'imageFile' ) ;
114+ const urls = locationState . imageUrls ?? ( locationState . imageUrl ? [ locationState . imageUrl ] : [ ] ) ;
115+ if ( urls . length > 0 ) {
116+ setExistingImages ( urls ) ;
120117 }
121- setPreviewUrl ( locationState . imageUrl ?? null ) ;
122118 hasInitialized . current = true ;
123- } , [ locationState , reset , resetField , setValue , setPreviewUrl ] ) ;
119+ } , [ locationState , reset , setExistingImages ] ) ;
124120
125121 const onSubmit = handleSubmit ( async ( data ) => {
126122 try {
127- const imageFile = data . imageFile ;
128- if ( ! imageFile && ! existingImageUrl ) {
123+ // 새로 추가된 파일만 필터링
124+ const newFiles = data . imageFiles . filter ( ( file ) : file is File => file !== null ) ;
125+ const hasNewFiles = newFiles . length > 0 ;
126+
127+ // 기존 이미지 중 삭제 안된 것
128+ const keptExistingUrls = existingImageUrls . filter ( ( url : string ) => images . some ( ( img ) => img . previewUrl === url ) ) ;
129+ const hasKeptExistingImages = keptExistingUrls . length > 0 ;
130+
131+ if ( ! hasNewFiles && ! hasKeptExistingImages ) {
129132 const message = '이미지를 업로드해 주세요.' ;
130133 showToast ( message ) ;
131- setError ( 'imageFile ' , { type : 'validate' , message } ) ;
134+ setError ( 'imageFiles ' , { type : 'validate' , message } ) ;
132135 return ;
133136 }
134137
135138 setIsSubmitting ( true ) ;
136139
137- let imageUrl = existingImageUrl ?? '' ;
138- if ( imageFile ) {
139- const uploaded = await uploadImage ( 'PRODUCT' , imageFile ) ;
140- imageUrl = uploaded . fileUrl ;
140+ let imageUrls : string [ ] = [ ] ;
141+
142+ // 새 파일이 있으면 업로드
143+ if ( hasNewFiles ) {
144+ const uploaded = await uploadImages ( 'PRODUCT' , newFiles ) ;
145+ imageUrls = uploaded . fileUrls ;
141146 }
142147
143- const request = buildSellPostRequest ( data , imageUrl ) ;
148+ imageUrls = [ ...keptExistingUrls , ...imageUrls ] ;
149+
150+ const request = buildSellPostRequest ( data , imageUrls ) ;
144151
145152 if ( editPostId ) {
146153 await updateSellPostMutation . mutateAsync ( request ) ;
@@ -161,7 +168,8 @@ export const useSellForm = () => {
161168 return {
162169 control,
163170 errors,
164- previewUrl,
171+ images,
172+ canAddMore,
165173 isDropdownOpen,
166174 dropdownRef,
167175 manufacturerValue,
@@ -177,6 +185,7 @@ export const useSellForm = () => {
177185 screenCondition,
178186 batteryCondition,
179187 handleImageChange,
188+ removeImage,
180189 toggleDropdown,
181190 selectManufacturer,
182191 setConditionValue,
0 commit comments