Skip to content

Commit 3818571

Browse files
committed
refactor: 기존제안하기 데이터 패칭 로직 수정
1 parent e7d2ce5 commit 3818571

1 file changed

Lines changed: 15 additions & 157 deletions

File tree

app/routes/matching/suggest/create/create-campaign-content.tsx

Lines changed: 15 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useNavigate, useSearchParams } from "react-router";
33
import { useForm, useWatch } from "react-hook-form";
44
import { zodResolver } from "@hookform/resolvers/zod";
55
import { toast } from "sonner";
6-
import { createCampaignProposal, getCampaignDetail } from "../../api/matching";
6+
import { createCampaignProposal } from "../../api/matching";
77
import { tokenStorage } from "../../../../lib/token";
88
import { useCampaignProposalStore } from "../../../../stores/campaign-proposal";
99
import { useAuthStore } from "../../../../stores/auth-store";
@@ -28,7 +28,6 @@ import {
2828
TONE_TAGS,
2929
INVOLVEMENT_TAGS,
3030
USAGE_RANGE_TAGS,
31-
PROPOSAL_TAG_ID_BY_NAME,
3231
type ProposalTag,
3332
} from "../../../../data/proposalTags";
3433
import {
@@ -106,171 +105,30 @@ export default function CreateCampaignContent() {
106105
}, []);
107106

108107
useEffect(() => {
109-
// 신규 제안 시 폼 초기화
110-
if (type !== "existing") {
111-
reset(defaultCampaignFormValues);
112-
return;
113-
}
114-
115-
let alive = true;
116-
117-
// URL 파라미터로 캠페인 조회 (기존 캠페인 제안 시)
118-
const campaignIdParam = searchParams.get("campaignId");
119-
120-
if (campaignIdParam) {
121-
const campaignId = Number(campaignIdParam);
122-
123-
// campaignId가 0보다 큰 경우에만 API 호출 (0은 광고 캠페인이므로 proposalData 사용)
124-
if (Number.isFinite(campaignId) && campaignId > 0) {
125-
(async () => {
126-
try {
127-
const detail = await getCampaignDetail(campaignId);
128-
if (!alive) return;
129-
130-
setValue("campaignName", detail.title);
131-
setValue("description", detail.description);
132-
setValue("fee", detail.rewardAmount.toString());
133-
setValue("sponsorProduct", detail.product ? [detail.product] : []);
134-
if (detail.startDate) setValue("startDate", detail.startDate);
135-
if (detail.endDate) setValue("endDate", detail.endDate);
136-
137-
if (detail.contentTags?.formats?.length > 0) {
138-
setValue("format", detail.contentTags.formats.map(f => String(f.id)));
139-
}
140-
if (detail.contentTags?.categories?.length > 0) {
141-
setValue("category", detail.contentTags.categories.map(c => String(c.id)));
142-
}
143-
if (detail.contentTags?.tones?.length > 0) {
144-
setValue("tone", detail.contentTags.tones.map(t => String(t.id)));
145-
}
146-
if (detail.contentTags?.involvements?.length > 0) {
147-
setValue("involvement", detail.contentTags.involvements.map(i => String(i.id)));
148-
}
149-
if (detail.contentTags?.usageRanges?.length > 0) {
150-
setValue("usageScope", detail.contentTags.usageRanges.map(u => String(u.id)));
151-
}
152-
} catch (error) {
153-
console.error("캠페인 상세 조회 실패:", error);
154-
toast.error("캠페인 정보를 불러오지 못했습니다");
155-
}
156-
})();
157-
158-
return () => {
159-
alive = false;
160-
};
161-
}
162-
}
163-
164-
if (proposalData) {
165-
if (proposalData.campaignTitle) setValue("campaignName", proposalData.campaignTitle);
166-
if (proposalData.campaignDescription) setValue("description", proposalData.campaignDescription);
167-
168-
// 태그 매핑 (ID를 문자열로 변환하여 배열로 사용)
169-
if (proposalData.contentTags?.formats && proposalData.contentTags.formats.length > 0) {
170-
setValue("format", proposalData.contentTags.formats.map(f => String(f.id)));
171-
}
172-
if (proposalData.contentTags?.categories && proposalData.contentTags.categories.length > 0) {
173-
setValue("category", proposalData.contentTags.categories.map(c => String(c.id)));
174-
}
175-
if (proposalData.contentTags?.tones && proposalData.contentTags.tones.length > 0) {
176-
setValue("tone", proposalData.contentTags.tones.map(t => String(t.id)));
177-
}
178-
if (proposalData.contentTags?.involvements && proposalData.contentTags.involvements.length > 0) {
179-
setValue("involvement", proposalData.contentTags.involvements.map(i => String(i.id)));
180-
}
181-
if (proposalData.contentTags?.usageRanges && proposalData.contentTags.usageRanges.length > 0) {
182-
setValue("usageScope", proposalData.contentTags.usageRanges.map(u => String(u.id)));
183-
}
184-
185-
const reward = proposalData.rewardAmount?.toString();
186-
if (reward) setValue("fee", reward);
187-
188-
// products 배열이 있으면 id가 0이 아닌 첫 번째 제품을 선택, 없으면 단일 product 사용
189-
let productSet = false;
190-
if (proposalData.products && proposalData.products.length > 0) {
191-
const validProduct = proposalData.products.find(p => {
192-
const id = Number(p.id);
193-
return Number.isFinite(id) && id > 0;
194-
});
195-
if (validProduct) {
196-
setValue("sponsorProduct", [String(validProduct.id)]);
197-
productSet = true;
198-
}
199-
}
200-
201-
// products에서 유효한 제품을 찾지 못했거나 products가 없으면 product 필드 사용
202-
if (!productSet && proposalData.product) {
203-
setValue("sponsorProduct", [proposalData.product]);
204-
}
205-
206-
if (proposalData.startDate) setValue("startDate", proposalData.startDate);
207-
if (proposalData.endDate) setValue("endDate", proposalData.endDate);
208-
}
209-
210-
return () => {
211-
alive = false;
212-
};
213-
}, [type, proposalData, searchParams, setValue, reset]);
108+
// 신규/기존 모두 폼 초기화 (기존 제안도 빈 폼으로 시작)
109+
reset(defaultCampaignFormValues);
110+
}, [type, reset]);
214111

215112
const formValues = useWatch({ control, defaultValue: defaultCampaignFormValues });
216113

217-
const tags = type === "new" ? undefined : proposalData?.contentTags;
218-
219-
const toOptions = (defaultTags: ProposalTag[], campaignTags?: { id?: number; name: string }[]) => {
220-
if (campaignTags && campaignTags.length > 0) {
221-
return campaignTags.map((t) => ({
222-
value: String(t.id ?? PROPOSAL_TAG_ID_BY_NAME[t.name] ?? t.name),
223-
label: t.name,
224-
}));
225-
}
114+
const toOptions = (defaultTags: ProposalTag[]) => {
226115
return defaultTags.map((t) => ({ value: String(t.id), label: t.name }));
227116
};
228117

229-
const formatOptions = toOptions(FORMAT_TAGS, tags?.formats);
230-
const categoryOptions = toOptions(CATEGORY_TAGS, tags?.categories);
231-
const toneOptions = toOptions(TONE_TAGS, tags?.tones);
232-
const involvementOptions = toOptions(INVOLVEMENT_TAGS, tags?.involvements);
233-
const usageScopeOptions = toOptions(USAGE_RANGE_TAGS, tags?.usageRanges);
118+
const formatOptions = toOptions(FORMAT_TAGS);
119+
const categoryOptions = toOptions(CATEGORY_TAGS);
120+
const toneOptions = toOptions(TONE_TAGS);
121+
const involvementOptions = toOptions(INVOLVEMENT_TAGS);
122+
const usageScopeOptions = toOptions(USAGE_RANGE_TAGS);
234123

235124
const sponsorProductOptions = useMemo(() => {
236-
const options: { value: string; label: string }[] = [];
237-
238-
// product 필드가 있으면 추가 (문자열 값)
239-
if (proposalData?.product) {
240-
options.push({ value: proposalData.product, label: proposalData.product });
241-
}
242-
243-
// products 배열이 있으면 추가 (id > 0인 것만)
244-
if (proposalData?.products && proposalData.products.length > 0) {
245-
const validProducts = proposalData.products
246-
.filter((p) => {
247-
const id = String(p.id).trim();
248-
const name = String(p.name).trim();
249-
// id가 0이 아니고, id와 name이 모두 있는 경우만 포함
250-
return id && name && id !== "0";
251-
})
252-
.map((p) => ({ value: String(p.id), label: String(p.name).trim() }));
253-
options.push(...validProducts);
254-
}
255-
256-
// 중복 제거 (value 기준)
257-
const uniqueOptions = options.reduce((acc, current) => {
258-
const exists = acc.find(opt => opt.value === current.value);
259-
if (!exists) {
260-
acc.push(current);
261-
}
262-
return acc;
263-
}, [] as { value: string; label: string }[]);
264-
265-
const baseOptions = type === "new" ? [] : uniqueOptions;
266-
267-
// formValues.sponsorProduct 배열에 있는데 options에 없는 항목들 추가 (id가 0이 아닌 경우만)
268-
const missingOptions = (formValues.sponsorProduct || [])
269-
.filter(sp => sp !== "0" && !baseOptions.find(opt => opt.value === sp))
125+
// 사용자가 직접 입력한 협찬품 항목만 표시
126+
const customOptions = (formValues.sponsorProduct || [])
127+
.filter(sp => sp !== "0")
270128
.map(sp => ({ value: sp, label: sp }));
271129

272-
return [...missingOptions, ...baseOptions];
273-
}, [proposalData, type, formValues.sponsorProduct]);
130+
return customOptions;
131+
}, [formValues.sponsorProduct]);
274132

275133
// ID 배열로 label들 찾기 헬퍼 함수
276134
const findLabels = (options: { value: string; label: string }[], values?: string[]) => {

0 commit comments

Comments
 (0)