이벤트 API 및 타입 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
merrycoral 2025-10-29 15:03:37 +09:00
parent 78cc41b453
commit a62aa9bae8
3 changed files with 162 additions and 5 deletions

View File

@ -20,6 +20,7 @@ import {
import { ArrowBack, CheckCircle, Edit, RocketLaunch, Save, People, AttachMoney, TrendingUp } from '@mui/icons-material'; import { ArrowBack, CheckCircle, Edit, RocketLaunch, Save, People, AttachMoney, TrendingUp } from '@mui/icons-material';
import { EventData } from '../page'; import { EventData } from '../page';
import { cardStyles, colors, responsiveText } from '@/shared/lib/button-styles'; import { cardStyles, colors, responsiveText } from '@/shared/lib/button-styles';
import { eventApi } from '@/entities/event/api/eventApi';
interface ApprovalStepProps { interface ApprovalStepProps {
eventData: EventData; eventData: EventData;
@ -33,16 +34,98 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
const [successDialogOpen, setSuccessDialogOpen] = useState(false); const [successDialogOpen, setSuccessDialogOpen] = useState(false);
const [isDeploying, setIsDeploying] = useState(false); const [isDeploying, setIsDeploying] = useState(false);
const handleApprove = () => { const handleApprove = async () => {
if (!agreeTerms) return; if (!agreeTerms) return;
setIsDeploying(true); setIsDeploying(true);
// 배포 시뮬레이션 try {
setTimeout(() => { // 1. 이벤트 생성 API 호출
console.log('📞 Creating event with objective:', eventData.objective);
// objective 매핑 (Frontend → Backend)
const objectiveMap: Record<string, string> = {
'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<string, string> = {
'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); setIsDeploying(false);
setSuccessDialogOpen(true); alert('이벤트 배포에 실패했습니다. 다시 시도해 주세요.');
}, 2000); }
}; };
const handleSaveDraft = () => { const handleSaveDraft = () => {

View File

@ -10,6 +10,9 @@ import type {
JobAcceptedResponse, JobAcceptedResponse,
ImageGenerationRequest, ImageGenerationRequest,
ImageGenerationResponse, ImageGenerationResponse,
UpdateEventRequest,
SelectChannelsRequest,
SelectImageRequest,
} from '../model/types'; } from '../model/types';
/** /**
@ -193,6 +196,52 @@ export const eventApi = {
); );
return response.data; return response.data;
}, },
/**
*
*/
updateEvent: async (
eventId: string,
data: UpdateEventRequest
): Promise<ApiResponse<EventDetail>> => {
console.log('📞 eventApi.updateEvent 호출', eventId, data);
const response = await eventApiClient.put<ApiResponse<EventDetail>>(
`${EVENT_API_BASE}/${eventId}`,
data
);
return response.data;
},
/**
*
*/
selectChannels: async (
eventId: string,
data: SelectChannelsRequest
): Promise<ApiResponse<void>> => {
console.log('📞 eventApi.selectChannels 호출', eventId, data);
const response = await eventApiClient.put<ApiResponse<void>>(
`${EVENT_API_BASE}/${eventId}/channels`,
data
);
return response.data;
},
/**
*
*/
selectImage: async (
eventId: string,
imageId: string,
data: SelectImageRequest
): Promise<ApiResponse<void>> => {
console.log('📞 eventApi.selectImage 호출', eventId, imageId, data);
const response = await eventApiClient.put<ApiResponse<void>>(
`${EVENT_API_BASE}/${eventId}/images/${imageId}/select`,
data
);
return response.data;
},
}; };
export default eventApi; export default eventApi;

View File

@ -171,3 +171,28 @@ export interface ImageGenerationResponse {
eventId: string; eventId: string;
status: 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;
}