diff --git a/src/app/(main)/events/create/steps/ApprovalStep.tsx b/src/app/(main)/events/create/steps/ApprovalStep.tsx index 465029e..5f5b536 100644 --- a/src/app/(main)/events/create/steps/ApprovalStep.tsx +++ b/src/app/(main)/events/create/steps/ApprovalStep.tsx @@ -20,6 +20,7 @@ import { import { ArrowBack, CheckCircle, Edit, RocketLaunch, Save, People, AttachMoney, TrendingUp } from '@mui/icons-material'; import { EventData } from '../page'; import { cardStyles, colors, responsiveText } from '@/shared/lib/button-styles'; +import { eventApi } from '@/entities/event/api/eventApi'; interface ApprovalStepProps { eventData: EventData; @@ -33,16 +34,98 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS const [successDialogOpen, setSuccessDialogOpen] = useState(false); const [isDeploying, setIsDeploying] = useState(false); - const handleApprove = () => { + const handleApprove = async () => { if (!agreeTerms) return; setIsDeploying(true); - // 배포 시뮬레이션 - setTimeout(() => { + try { + // 1. 이벤트 생성 API 호출 + console.log('📞 Creating event with objective:', eventData.objective); + + // objective 매핑 (Frontend → Backend) + const objectiveMap: Record = { + 'new_customer': 'CUSTOMER_ACQUISITION', + 'revisit': 'Customer Retention', + 'sales': 'Sales Promotion', + 'awareness': 'awareness', + }; + + const backendObjective = objectiveMap[eventData.objective || 'new_customer'] || 'CUSTOMER_ACQUISITION'; + + const createResponse = await eventApi.createEvent({ + objective: backendObjective, + }); + + console.log('✅ Event created:', createResponse); + + if (createResponse.success && createResponse.data) { + const eventId = createResponse.data.eventId; + console.log('🎯 Event ID:', eventId); + + // 2. 이벤트 상세 정보 업데이트 + console.log('📞 Updating event details:', eventId); + + // 이벤트명 가져오기 (contentEdit.title 또는 recommendation.title) + const eventName = eventData.contentEdit?.title || eventData.recommendation?.title || '이벤트'; + + // 날짜 설정 (오늘부터 30일간) + const today = new Date(); + const endDate = new Date(today); + endDate.setDate(endDate.getDate() + 30); + + const startDateStr = today.toISOString().split('T')[0]; // YYYY-MM-DD + const endDateStr = endDate.toISOString().split('T')[0]; + + await eventApi.updateEvent(eventId, { + eventName: eventName, + description: eventData.contentEdit?.guide || eventData.recommendation?.participationMethod, + startDate: startDateStr, + endDate: endDateStr, + }); + console.log('✅ Event details updated'); + + // 3. 배포 채널 선택 + if (eventData.channels && eventData.channels.length > 0) { + console.log('📞 Selecting channels:', eventData.channels); + + // 채널명 매핑 (Frontend → Backend) + const channelMap: Record = { + 'uriTV': 'WEBSITE', + 'ringoBiz': 'EMAIL', + 'genieTV': 'KAKAO', + 'sns': 'INSTAGRAM', + }; + + const backendChannels = eventData.channels.map(ch => channelMap[ch] || ch.toUpperCase()); + + await eventApi.selectChannels(eventId, { + channels: backendChannels, + }); + console.log('✅ Channels selected'); + } + + // 4. TODO: 이미지 선택 + // 현재 frontend에서 selectedImageId를 추적하지 않음 + // 향후 contentPreview 단계에서 선택된 이미지 ID를 eventData에 저장 필요 + console.log('⚠️ Image selection skipped - imageId not tracked in frontend'); + + // 5. 이벤트 배포 API 호출 + console.log('📞 Publishing event:', eventId); + const publishResponse = await eventApi.publishEvent(eventId); + console.log('✅ Event published:', publishResponse); + + // 성공 다이얼로그 표시 + setIsDeploying(false); + setSuccessDialogOpen(true); + } else { + throw new Error('Event creation failed: No event ID returned'); + } + } catch (error) { + console.error('❌ Event deployment failed:', error); setIsDeploying(false); - setSuccessDialogOpen(true); - }, 2000); + alert('이벤트 배포에 실패했습니다. 다시 시도해 주세요.'); + } }; const handleSaveDraft = () => { diff --git a/src/entities/event/api/eventApi.ts b/src/entities/event/api/eventApi.ts index 929eefe..6820d7a 100644 --- a/src/entities/event/api/eventApi.ts +++ b/src/entities/event/api/eventApi.ts @@ -10,6 +10,9 @@ import type { JobAcceptedResponse, ImageGenerationRequest, ImageGenerationResponse, + UpdateEventRequest, + SelectChannelsRequest, + SelectImageRequest, } from '../model/types'; /** @@ -193,6 +196,52 @@ export const eventApi = { ); return response.data; }, + + /** + * 이벤트 수정 + */ + updateEvent: async ( + eventId: string, + data: UpdateEventRequest + ): Promise> => { + console.log('📞 eventApi.updateEvent 호출', eventId, data); + const response = await eventApiClient.put>( + `${EVENT_API_BASE}/${eventId}`, + data + ); + return response.data; + }, + + /** + * 배포 채널 선택 + */ + selectChannels: async ( + eventId: string, + data: SelectChannelsRequest + ): Promise> => { + console.log('📞 eventApi.selectChannels 호출', eventId, data); + const response = await eventApiClient.put>( + `${EVENT_API_BASE}/${eventId}/channels`, + data + ); + return response.data; + }, + + /** + * 이미지 선택 + */ + selectImage: async ( + eventId: string, + imageId: string, + data: SelectImageRequest + ): Promise> => { + console.log('📞 eventApi.selectImage 호출', eventId, imageId, data); + const response = await eventApiClient.put>( + `${EVENT_API_BASE}/${eventId}/images/${imageId}/select`, + data + ); + return response.data; + }, }; export default eventApi; diff --git a/src/entities/event/model/types.ts b/src/entities/event/model/types.ts index b3de860..c9d9b37 100644 --- a/src/entities/event/model/types.ts +++ b/src/entities/event/model/types.ts @@ -171,3 +171,28 @@ export interface ImageGenerationResponse { eventId: string; status: string; } + +/** + * 이벤트 수정 요청 + */ +export interface UpdateEventRequest { + eventName?: string; + description?: string; + startDate?: string; + endDate?: string; + discountRate?: number; +} + +/** + * 배포 채널 선택 요청 + */ +export interface SelectChannelsRequest { + channels: string[]; +} + +/** + * 이미지 선택 요청 + */ +export interface SelectImageRequest { + selectedImageId: string; +}