diff --git a/src/app/(main)/events/[eventId]/page.tsx b/src/app/(main)/events/[eventId]/page.tsx
index 412f739..dfcf8e9 100644
--- a/src/app/(main)/events/[eventId]/page.tsx
+++ b/src/app/(main)/events/[eventId]/page.tsx
@@ -687,8 +687,8 @@ export default function EventDetailPage() {
- {/* Chart Section - 참여 추이 */}
-
+ {/* Chart Section - 참여 추이 - 임시 주석처리 */}
+ {/*
📈 참여 추이
@@ -757,7 +757,7 @@ export default function EventDetailPage() {
-
+ */}
{/* Chart Section - 채널별 성과 & ROI 추이 */}
diff --git a/src/app/(main)/events/create/page.tsx b/src/app/(main)/events/create/page.tsx
index 59ccec7..97470b7 100644
--- a/src/app/(main)/events/create/page.tsx
+++ b/src/app/(main)/events/create/page.tsx
@@ -3,11 +3,13 @@
import { useFunnel } from '@use-funnel/browser';
import { useRouter } from 'next/navigation';
import ObjectiveStep from './steps/ObjectiveStep';
+import LoadingStep from './steps/LoadingStep';
import RecommendationStep from './steps/RecommendationStep';
import ContentPreviewStep from './steps/ContentPreviewStep';
import ContentEditStep from './steps/ContentEditStep';
import ChannelStep from './steps/ChannelStep';
import ApprovalStep from './steps/ApprovalStep';
+import type { AiRecommendationResult } from '@/shared/api/eventApi';
// 이벤트 생성 데이터 타입
export type EventObjective = 'new_customer' | 'revisit' | 'sales' | 'awareness';
@@ -18,6 +20,7 @@ export interface EventData {
eventDraftId?: number;
eventId?: string;
objective?: EventObjective;
+ aiResult?: AiRecommendationResult;
recommendation?: {
recommendation: {
optionNumber: number;
@@ -74,6 +77,7 @@ export default function EventCreatePage() {
const funnel = useFunnel<{
objective: EventData;
+ loading: EventData;
recommendation: EventData;
contentPreview: EventData;
contentEdit: EventData;
@@ -97,13 +101,27 @@ export default function EventCreatePage() {
objective={({ history }) => (
{
- history.push('recommendation', { objective, eventId });
+ history.push('loading', { objective, eventId });
+ }}
+ />
+ )}
+ loading={({ context, history }) => (
+ {
+ history.push('recommendation', { ...context, aiResult });
+ }}
+ onError={(error) => {
+ console.error('❌ AI 추천 생성 실패:', error);
+ alert(error);
+ history.go(-1); // ObjectiveStep으로 돌아가기
}}
/>
)}
recommendation={({ context, history }) => (
{
history.push('channel', { ...context, recommendation });
}}
@@ -122,13 +140,18 @@ export default function EventCreatePage() {
if (needsContent) {
// localStorage에 이벤트 정보 저장
+ const baseTrends = context.recommendation?.recommendation.promotionChannels || [];
+ const requiredTrends = ['Samgyupsal', '삼겹살', 'Korean Pork BBQ'];
+ // 중복 제거하면서 필수 trends 추가
+ const allTrends = [...new Set([...requiredTrends, ...baseTrends])];
+
const eventData = {
eventDraftId: context.recommendation?.eventId || String(Date.now()), // eventId 사용
eventTitle: context.recommendation?.recommendation.title || '',
eventDescription: context.recommendation?.recommendation.description || '',
industry: '',
location: '',
- trends: context.recommendation?.recommendation.promotionChannels || [],
+ trends: allTrends,
prize: '',
};
localStorage.setItem('eventCreationData', JSON.stringify(eventData));
diff --git a/src/app/(main)/events/create/steps/ApprovalStep.tsx b/src/app/(main)/events/create/steps/ApprovalStep.tsx
index 2937336..c119a8a 100644
--- a/src/app/(main)/events/create/steps/ApprovalStep.tsx
+++ b/src/app/(main)/events/create/steps/ApprovalStep.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useState, useEffect } from 'react';
import {
Box,
Container,
@@ -17,12 +17,29 @@ import {
DialogActions,
Link,
} from '@mui/material';
-import { ArrowBack, CheckCircle, Edit, RocketLaunch, Save, People, AttachMoney, TrendingUp } from '@mui/icons-material';
+import {
+ ArrowBack,
+ CheckCircle,
+ 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';
import type { EventObjective } from '@/entities/event/model/types';
+interface EventCreationData {
+ eventDraftId: string;
+ eventTitle: string;
+ eventDescription: string;
+ industry: string;
+ location: string;
+ trends: string[];
+ prize: string;
+}
interface ApprovalStepProps {
eventData: EventData;
@@ -35,7 +52,17 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
const [termsDialogOpen, setTermsDialogOpen] = useState(false);
const [successDialogOpen, setSuccessDialogOpen] = useState(false);
const [isDeploying, setIsDeploying] = useState(false);
- const DISTRIBUTION_API_BASE_URL = process.env.NEXT_PUBLIC_DISTRIBUTION_HOST || 'http://kt-event-marketing-api.20.214.196.128.nip.io';
+ const [localStorageData, setLocalStorageData] = useState(null);
+ const DISTRIBUTION_API_BASE_URL =
+ process.env.NEXT_PUBLIC_DISTRIBUTION_HOST ||
+ 'http://kt-event-marketing-api.20.214.196.128.nip.io';
+
+ useEffect(() => {
+ const storedData = localStorage.getItem('eventCreationData');
+ if (storedData) {
+ setLocalStorageData(JSON.parse(storedData));
+ }
+ }, []);
const handleApprove = async () => {
if (!agreeTerms) return;
@@ -48,13 +75,15 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
// objective 매핑 (Frontend → Backend)
const objectiveMap: Record = {
- 'new_customer': 'CUSTOMER_ACQUISITION',
- 'revisit': 'Customer Retention',
- 'sales': 'Sales Promotion',
- 'awareness': 'awareness',
+ new_customer: 'CUSTOMER_ACQUISITION',
+ revisit: 'Customer Retention',
+ sales: 'Sales Promotion',
+ awareness: 'awareness',
};
- const backendObjective: EventObjective = (objectiveMap[eventData.objective || 'new_customer'] || 'CUSTOMER_ACQUISITION') as EventObjective;
+ const backendObjective: EventObjective = (objectiveMap[
+ eventData.objective || 'new_customer'
+ ] || 'CUSTOMER_ACQUISITION') as EventObjective;
const createResponse = await eventApi.createEvent({
objective: backendObjective,
@@ -70,7 +99,10 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
console.log('📞 Updating event details:', eventId);
// 이벤트명 가져오기 (contentEdit.title 또는 recommendation.title)
- const eventName = eventData.contentEdit?.title || eventData.recommendation?.recommendation?.title || '이벤트';
+ const eventName =
+ eventData.contentEdit?.title ||
+ eventData.recommendation?.recommendation?.title ||
+ '이벤트';
// 날짜 설정 (오늘부터 30일간)
const today = new Date();
@@ -82,7 +114,10 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
await eventApi.updateEvent(eventId, {
eventName: eventName,
- description: eventData.contentEdit?.guide || eventData.recommendation?.recommendation?.description || '',
+ description:
+ eventData.contentEdit?.guide ||
+ eventData.recommendation?.recommendation?.description ||
+ '',
startDate: startDateStr,
endDate: endDateStr,
});
@@ -96,12 +131,15 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
sns: ['INSTAGRAM', 'NAVER', 'KAKAO'],
};
- const apiChannels = eventData.channels?.flatMap(ch => channelMap[ch] || []) || [];
+ const apiChannels = eventData.channels?.flatMap((ch) => channelMap[ch] || []) || [];
const distributionRequest = {
eventId: eventId,
title: eventName,
- description: eventData.contentEdit?.guide || eventData.recommendation?.recommendation?.description || '',
+ description:
+ eventData.contentEdit?.guide ||
+ eventData.recommendation?.recommendation?.description ||
+ '',
imageUrl: '', // TODO: 이미지 URL 연동 필요
channels: apiChannels,
channelSettings: {},
@@ -109,13 +147,16 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
console.log('🚀 Distributing event:', distributionRequest);
- const response = await fetch(`${DISTRIBUTION_API_BASE_URL}/api/v1/distribution/distribute`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(distributionRequest),
- });
+ const response = await fetch(
+ `${DISTRIBUTION_API_BASE_URL}/api/v1/distribution/distribute`,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(distributionRequest),
+ }
+ );
if (!response.ok) {
const errorData = await response.json();
@@ -127,7 +168,6 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
setIsDeploying(false);
setSuccessDialogOpen(true);
-
} else {
throw new Error('Event creation failed: No event ID returned');
}
@@ -138,7 +178,6 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
}
};
-
const handleSaveDraft = () => {
// TODO: 임시저장 API 연동
alert('임시저장되었습니다');
@@ -156,10 +195,27 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
};
return (
-
-
+
+
{/* Header */}
-
+
@@ -180,7 +236,7 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
{/* Event Summary Statistics */}
-
+
-
-
-
+
+
+
이벤트 제목
- {eventData.recommendation?.recommendation.title || '이벤트 제목'}
+ {localStorageData?.eventTitle ||
+ eventData.recommendation?.recommendation.title ||
+ '이벤트 제목'}
@@ -228,19 +292,24 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
borderColor: 'transparent',
}}
>
-
-
-
+
+
+
목표 참여자
{eventData.recommendation?.recommendation.expectedMetrics.newCustomers.max || 0}
-
+
명
@@ -274,19 +346,24 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
borderColor: 'transparent',
}}
>
-
-
-
+
+
+
예상 비용
- {((eventData.recommendation?.recommendation.estimatedCost.max || 0) / 10000).toFixed(0)}
-
+ {(
+ (eventData.recommendation?.recommendation.estimatedCost.max || 0) / 10000
+ ).toFixed(0)}
+
만원
@@ -320,19 +402,24 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
borderColor: 'transparent',
}}
>
-
-
-
+
+
+
예상 ROI
@@ -357,53 +444,62 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
-
-
-
-
- 이벤트 제목
-
-
- {eventData.recommendation?.recommendation.title}
-
-
-
-
-
-
+
+
+ 이벤트 제목
+
+
+ {localStorageData?.eventTitle ||
+ eventData.recommendation?.recommendation.title ||
+ '이벤트 제목'}
+
-
-
-
-
- 경품
-
-
- {eventData.recommendation?.recommendation.mechanics.details || ''}
-
-
-
-
-
-
+
+
+ 경품
+
+
+ {localStorageData?.prize ||
+ eventData.recommendation?.recommendation.mechanics.details ||
+ ''}
+
-
-
-
-
- 참여 방법
-
-
- {eventData.recommendation?.recommendation.mechanics.details || ''}
-
-
-
+
+
+ 참여 방법
+
+
+ {localStorageData?.eventDescription ||
+ eventData.recommendation?.recommendation.mechanics.details ||
+ ''}
+
@@ -413,8 +509,8 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
-
-
+
+
{getChannelNames(eventData.channels).map((channel) => (
))}
- }
- sx={{
- ...responsiveText.body2,
- fontWeight: 600,
- color: colors.purple,
- }}
- >
- 채널 수정하기
-
{/* Terms Agreement */}
-
-
+
+
}
label={
-
+
이벤트 약관 및 개인정보 처리방침에 동의합니다{' '}
-
+
(필수)
@@ -551,21 +639,33 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
제1조 (목적)
-
- 본 약관은 KT AI 이벤트 마케팅 서비스를 통해 진행되는 이벤트의 참여 및 개인정보 처리에 관한
- 사항을 규정합니다.
+
+ 본 약관은 KT AI 이벤트 마케팅 서비스를 통해 진행되는 이벤트의 참여 및 개인정보 처리에
+ 관한 사항을 규정합니다.
제2조 (개인정보 수집 및 이용)
-
+
수집 항목: 이름, 전화번호, 이메일
-
+
이용 목적: 이벤트 참여 확인 및 경품 제공
-
+
보유 기간: 이벤트 종료 후 6개월
@@ -616,7 +716,11 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
배포 완료!
-
+
이벤트가 성공적으로 배포되었습니다.
실시간으로 참여자를 확인할 수 있습니다.
diff --git a/src/app/(main)/events/create/steps/ChannelStep.tsx b/src/app/(main)/events/create/steps/ChannelStep.tsx
index aa4df36..c2cac05 100644
--- a/src/app/(main)/events/create/steps/ChannelStep.tsx
+++ b/src/app/(main)/events/create/steps/ChannelStep.tsx
@@ -14,6 +14,8 @@ import {
FormControl,
InputLabel,
IconButton,
+ Radio,
+ RadioGroup,
} from '@mui/material';
import { ArrowBack } from '@mui/icons-material';
@@ -108,18 +110,18 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
return (
-
+
{/* Header */}
-
-
-
+
+
+
-
+
배포 채널 선택
-
+
(최소 1개 이상)
@@ -127,8 +129,8 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
-
+
handleChannelToggle('uriTV')}
sx={{
+ p: { xs: 0.5, sm: 1 },
color: colors.purple,
'&.Mui-checked': {
color: colors.purple,
@@ -151,46 +154,48 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
/>
}
label={
-
+
우리동네TV
}
- sx={{ mb: channels[0].selected ? 2 : 0 }}
+ sx={{ mb: channels[0].selected ? { xs: 1.5, sm: 2 } : 0 }}
/>
{channels[0].selected && (
-
-
- 반경
+
+
+ 반경
-
- 노출 시간대
+
+ 노출 시간대
-
+
예상 노출: 5만명
-
+
비용: 8만원
@@ -202,8 +207,8 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
-
+
handleChannelToggle('ringoBiz')}
sx={{
+ p: { xs: 0.5, sm: 1 },
color: colors.purple,
'&.Mui-checked': {
color: colors.purple,
@@ -226,30 +232,32 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
/>
}
label={
-
+
링고비즈
}
- sx={{ mb: channels[1].selected ? 2 : 0 }}
+ sx={{ mb: channels[1].selected ? { xs: 1.5, sm: 2 } : 0 }}
/>
{channels[1].selected && (
-
+
-
+
연결음 자동 업데이트
-
+
예상 노출: 3만명
-
+
비용: 무료
@@ -261,8 +269,8 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
-
+
handleChannelToggle('genieTV')}
sx={{
+ p: { xs: 0.5, sm: 1 },
color: colors.purple,
'&.Mui-checked': {
color: colors.purple,
@@ -285,37 +294,39 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
/>
}
label={
-
+
지니TV 광고
}
- sx={{ mb: channels[2].selected ? 2 : 0 }}
+ sx={{ mb: channels[2].selected ? { xs: 1.5, sm: 2 } : 0 }}
/>
{channels[2].selected && (
-
-
- 지역
+
+
+ 지역
-
- 노출 시간대
+
+ 노출 시간대
@@ -327,10 +338,12 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
value={getChannelConfig('genieTV', 'budget')}
onChange={(e) => handleConfigChange('genieTV', 'budget', e.target.value)}
InputProps={{ inputProps: { min: 0, step: 10000 } }}
- sx={{ mb: 2 }}
+ sx={{ mb: { xs: 1.5, sm: 2 } }}
+ InputLabelProps={{ sx: { fontSize: { xs: '0.875rem', sm: '1rem' } } }}
+ inputProps={{ sx: { fontSize: { xs: '0.875rem', sm: '1rem' } } }}
/>
-
+
예상 노출:{' '}
{getChannelConfig('genieTV', 'budget')
@@ -347,8 +360,8 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
-
+
handleChannelToggle('sns')}
sx={{
+ p: { xs: 0.5, sm: 1 },
color: colors.purple,
'&.Mui-checked': {
color: colors.purple,
@@ -371,16 +385,16 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
/>
}
label={
-
+
SNS
}
- sx={{ mb: channels[3].selected ? 2 : 0 }}
+ sx={{ mb: channels[3].selected ? { xs: 1.5, sm: 2 } : 0 }}
/>
{channels[3].selected && (
-
-
+
+
플랫폼 선택
}
- label="Instagram"
+ label={Instagram}
sx={{ display: 'block' }}
/>
}
- label="Naver Blog"
+ label={Naver Blog}
sx={{ display: 'block' }}
/>
}
- label="Kakao Channel"
- sx={{ display: 'block', mb: 2 }}
+ label={Kakao Channel}
+ sx={{ display: 'block', mb: { xs: 1.5, sm: 2 } }}
/>
-
- 예약 게시
+
+ 예약 게시
-
+
예상 노출: -
-
+
비용: 무료
@@ -465,26 +483,26 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
-
-
-
+
+
+
총 예상 비용
-
+
{totalCost.toLocaleString()}원
-
+
총 예상 노출
-
+
{totalExposure > 0 ? `${totalExposure.toLocaleString()}명+` : '0명'}
@@ -492,16 +510,16 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
{/* Action Buttons */}
-
+
-
+ */}
{/* Edit Section */}
-
- 편집
-
+
-
+
텍스트 편집
@@ -148,7 +173,7 @@ export default function ContentEditStep({
{/* Action Buttons */}
-
+
diff --git a/src/app/(main)/events/create/steps/RecommendationStep.tsx b/src/app/(main)/events/create/steps/RecommendationStep.tsx
index 4aabc27..5de6a44 100644
--- a/src/app/(main)/events/create/steps/RecommendationStep.tsx
+++ b/src/app/(main)/events/create/steps/RecommendationStep.tsx
@@ -42,6 +42,7 @@ const colors = {
interface RecommendationStepProps {
eventId?: string; // 이전 단계에서 생성된 eventId
+ aiResult?: AiRecommendationResult; // LoadingStep에서 전달받은 AI 추천 결과
onNext: (data: { recommendation: EventRecommendation; eventId: string }) => void;
onBack: () => void;
}
@@ -60,6 +61,7 @@ const getCookie = (name: string): string | null => {
export default function RecommendationStep({
eventId: initialEventId,
+ aiResult: initialAiResult,
onNext,
onBack,
}: RecommendationStepProps) {
@@ -67,7 +69,7 @@ export default function RecommendationStep({
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
- const [aiResult, setAiResult] = useState(null);
+ const [aiResult, setAiResult] = useState(initialAiResult || null);
const [selected, setSelected] = useState(null);
const [editedData, setEditedData] = useState<
Record
@@ -78,7 +80,15 @@ export default function RecommendationStep({
// 컴포넌트 마운트 시 AI 추천 결과 조회
useEffect(() => {
- // props에서만 eventId를 받음
+ // LoadingStep에서 이미 데이터를 전달받은 경우 API 호출 생략
+ if (initialAiResult) {
+ console.log('✅ LoadingStep에서 전달받은 AI 추천 결과 사용:', initialAiResult);
+ setAiResult(initialAiResult);
+ setEventId(initialEventId || null);
+ return;
+ }
+
+ // props에서만 eventId를 받음 (하위 호환성)
if (initialEventId) {
// 이미 요청한 eventId면 중복 요청하지 않음
if (requestedEventIdRef.current === initialEventId) {
@@ -95,28 +105,29 @@ export default function RecommendationStep({
console.error('❌ eventId가 없습니다. ObjectiveStep으로 돌아가세요.');
setError('이벤트 ID가 없습니다. 이전 단계로 돌아가서 다시 시도하세요.');
}
- }, [initialEventId]);
+ }, [initialEventId, initialAiResult]);
const fetchAIRecommendations = async (evtId: string) => {
try {
setLoading(true);
setError(null);
- console.log('📡 AI 추천 요청 시작, eventId:', evtId);
+ console.log('📡 AI 추천 결과 조회 시작, eventId:', evtId);
- // POST /events/{eventId}/ai-recommendations 엔드포인트로 AI 추천 요청
- const recommendations = await eventApi.requestAiRecommendations(evtId);
+ // GET /events/{eventId}/ai-recommendations 엔드포인트로 AI 추천 결과 조회
+ // ObjectiveStep에서 이미 POST 요청으로 생성했으므로 GET으로 조회
+ const recommendations = await eventApi.getAiRecommendations(evtId);
- console.log('✅ AI 추천 요청 성공:', recommendations);
+ console.log('✅ AI 추천 결과 조회 성공:', recommendations);
setAiResult(recommendations);
setLoading(false);
} catch (err: any) {
- console.error('❌ AI 추천 요청 실패:', err);
+ console.error('❌ AI 추천 결과 조회 실패:', err);
const errorMessage =
err.response?.data?.message ||
err.response?.data?.error ||
- 'AI 추천을 생성하는데 실패했습니다';
+ 'AI 추천 결과를 조회하는데 실패했습니다';
setError(errorMessage);
setLoading(false);
@@ -132,14 +143,25 @@ export default function RecommendationStep({
try {
setLoading(true);
- // AI 추천 선택 API 호출
- await eventApi.selectRecommendation(eventId, {
- recommendationId: `${eventId}-opt${selected}`,
- customizations: {
- eventName: edited?.title || selectedRec.title,
+ // localStorage에 선택한 추천 정보 저장
+ const selectedRecommendationData = {
+ eventId,
+ selectedOptionNumber: selected,
+ recommendation: {
+ ...selectedRec,
+ title: edited?.title || selectedRec.title,
description: edited?.description || selectedRec.description,
},
- });
+ trendAnalysis: aiResult.trendAnalysis,
+ timestamp: new Date().toISOString(),
+ };
+
+ try {
+ localStorage.setItem('selectedRecommendation', JSON.stringify(selectedRecommendationData));
+ console.log('💾 localStorage에 선택한 추천 정보 저장 완료:', selectedRecommendationData);
+ } catch (error) {
+ console.error('❌ localStorage 저장 실패:', error);
+ }
// 다음 단계로 이동
onNext({
@@ -182,24 +204,24 @@ export default function RecommendationStep({
if (loading) {
return (
-
-
-
-
+
+
+
+
-
+
AI 이벤트 추천
-
-
+
+
AI가 최적의 이벤트를 생성하고 있습니다...
-
+
업종, 지역, 시즌 트렌드를 분석하여 맞춤형 이벤트를 추천합니다
@@ -212,30 +234,30 @@ export default function RecommendationStep({
if (error) {
return (
-
-
-
-
+
+
+
+
-
+
AI 이벤트 추천
-
+
{error}
-
+