Skip to content

Commit 8a26ec3

Browse files
committed
fix(sell): 수정 모드 다중 이미지 처리 및 삭제 캐시 개선
1 parent 9dfabcf commit 8a26ec3

3 files changed

Lines changed: 33 additions & 23 deletions

File tree

src/pages/buy-detail/model/useManageActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const useManageActions = (item: BuyItem | undefined) => {
1919
postId: item.id,
2020
title: item.title,
2121
price: String(item.priceValue),
22-
imageUrl: item.image,
22+
imageUrls: item.imageUrls,
2323
manufacturer: item.specs.manufacturer,
2424
modelName: item.specs.model,
2525
colorName: item.specs.color,

src/pages/sell/model/useSellForm.ts

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { zodResolver } from '@hookform/resolvers/zod';
2-
import { uploadImage } from '@shared/apis/image';
2+
import { uploadImages } from '@shared/apis/image';
33
import { useCreateSellPostMutation, useSellAutocompleteQuery, useUpdateSellPostMutation } from '@shared/apis/sell';
44
import { ROUTES } from '@shared/constants';
55
import { 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,

src/shared/apis/sell/queries.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ export const useDeleteSellPostMutation = (postId: number | string) => {
4444
return useMutation({
4545
mutationFn: () => deleteSellPost(postId),
4646
onSuccess: () => {
47+
queryClient.removeQueries({ queryKey: buyKeys.detail(postId) });
48+
queryClient.removeQueries({ queryKey: buyKeys.lists() });
4749
queryClient.invalidateQueries({ queryKey: sellKeys.lists() });
48-
queryClient.invalidateQueries({ queryKey: buyKeys.lists() });
4950
},
5051
});
5152
};

0 commit comments

Comments
 (0)