diff --git a/src/app/(main)/events/[eventId]/page.tsx b/src/app/(main)/events/[eventId]/page.tsx
index 6d718dc..578ecd4 100644
--- a/src/app/(main)/events/[eventId]/page.tsx
+++ b/src/app/(main)/events/[eventId]/page.tsx
@@ -15,6 +15,7 @@ import {
Menu,
MenuItem,
Divider,
+ LinearProgress,
} from '@mui/material';
import {
MoreVert,
@@ -23,13 +24,63 @@ import {
TrendingUp,
Share,
CardGiftcard,
- HowToReg,
AttachMoney,
People,
Edit,
Download,
Person,
+ Phone,
+ Email,
+ ShoppingCart,
+ Warning,
+ LocalFireDepartment,
+ Star,
+ NewReleases,
} from '@mui/icons-material';
+import { Line, Bar } from 'react-chartjs-2';
+import {
+ Chart as ChartJS,
+ CategoryScale,
+ LinearScale,
+ PointElement,
+ LineElement,
+ BarElement,
+ Title,
+ Tooltip,
+ Legend,
+ Filler,
+} from 'chart.js';
+
+// Chart.js 등록
+ChartJS.register(
+ CategoryScale,
+ LinearScale,
+ PointElement,
+ LineElement,
+ BarElement,
+ Title,
+ Tooltip,
+ Legend,
+ Filler
+);
+
+// 디자인 시스템 색상
+const colors = {
+ pink: '#F472B6',
+ purple: '#C084FC',
+ purpleLight: '#E9D5FF',
+ blue: '#60A5FA',
+ mint: '#34D399',
+ orange: '#FB923C',
+ yellow: '#FBBF24',
+ gray: {
+ 900: '#1A1A1A',
+ 700: '#4A4A4A',
+ 500: '#9E9E9E',
+ 300: '#D9D9D9',
+ 100: '#F5F5F5',
+ },
+};
// Mock 데이터
const mockEventData = {
@@ -41,12 +92,17 @@ const mockEventData = {
prize: '커피 쿠폰',
method: 'SNS 팔로우',
cost: 250000,
- channels: ['홈페이지', '카카오톡', 'Instagram'],
+ channels: ['우리동네TV', '링고비즈', 'SNS'],
participants: 128,
views: 456,
roi: 450,
conversion: 28,
+ targetParticipants: 200,
isAIRecommended: true,
+ isUrgent: false,
+ isPopular: true,
+ isHighROI: true,
+ isNew: false,
};
const recentParticipants = [
@@ -57,6 +113,86 @@ const recentParticipants = [
{ name: '정*희', phone: '010-****-7890', time: '2시간 전' },
];
+// 차트 데이터 생성 함수
+const generateParticipationTrendData = (period: '7d' | '30d' | 'all') => {
+ const labels =
+ period === '7d'
+ ? ['1/20', '1/21', '1/22', '1/23', '1/24', '1/25', '1/26']
+ : period === '30d'
+ ? Array.from({ length: 30 }, (_, i) => `1/${i + 1}`)
+ : Array.from({ length: 31 }, (_, i) => `1/${i + 1}`);
+
+ const data =
+ period === '7d'
+ ? [12, 19, 15, 25, 22, 30, 28]
+ : period === '30d'
+ ? Array.from({ length: 30 }, () => Math.floor(Math.random() * 30) + 10)
+ : Array.from({ length: 31 }, () => Math.floor(Math.random() * 30) + 10);
+
+ return {
+ labels,
+ datasets: [
+ {
+ label: '일별 참여자',
+ data,
+ borderColor: colors.blue,
+ backgroundColor: `${colors.blue}40`,
+ fill: true,
+ tension: 0.4,
+ },
+ ],
+ };
+};
+
+const channelPerformanceData = {
+ labels: ['우리동네TV', '링고비즈', 'SNS'],
+ datasets: [
+ {
+ label: '참여자 수',
+ data: [58, 38, 32],
+ backgroundColor: [colors.pink, colors.blue, colors.orange],
+ borderRadius: 8,
+ },
+ ],
+};
+
+const roiTrendData = {
+ labels: ['1주차', '2주차', '3주차', '4주차'],
+ datasets: [
+ {
+ label: 'ROI (%)',
+ data: [150, 280, 380, 450],
+ borderColor: colors.mint,
+ backgroundColor: `${colors.mint}40`,
+ fill: true,
+ tension: 0.4,
+ },
+ ],
+};
+
+// 헬퍼 함수
+const getMethodIcon = (method: string) => {
+ switch (method) {
+ case '전화번호 입력':
+ return ;
+ case 'SNS 팔로우':
+ return ;
+ case '구매 인증':
+ return ;
+ case '이메일 등록':
+ return ;
+ default:
+ return ;
+ }
+};
+
+const calculateProgress = (event: typeof mockEventData) => {
+ if (event.status !== 'active') return 0;
+ const total = new Date(event.endDate).getTime() - new Date(event.startDate).getTime();
+ const elapsed = Date.now() - new Date(event.startDate).getTime();
+ return Math.min(Math.max((elapsed / total) * 100, 0), 100);
+};
+
export default function EventDetailPage() {
const router = useRouter();
const params = useParams();
@@ -119,11 +255,11 @@ export default function EventDetailPage() {
return (
-
+
{/* Event Header */}
-
-
-
+
+
+
{event.title}
@@ -131,13 +267,13 @@ export default function EventDetailPage() {
-
-
+
+
{event.isAIRecommended && (
+
+ )}
+ {event.isUrgent && (
}
+ label="마감임박"
+ size="medium"
+ sx={{ bgcolor: '#FEF3C7', color: '#92400E' }}
+ />
+ )}
+ {event.isPopular && (
+ }
+ label="인기"
+ size="medium"
+ sx={{ bgcolor: '#FEE2E2', color: '#991B1B' }}
+ />
+ )}
+ {event.isHighROI && (
+ }
+ label="높은 ROI"
+ size="medium"
+ sx={{ bgcolor: '#DCFCE7', color: '#166534' }}
+ />
+ )}
+ {event.isNew && (
+ }
+ label="신규"
+ size="medium"
+ sx={{ bgcolor: '#DBEAFE', color: '#1E40AF' }}
/>
)}
-
- {event.startDate} ~ {event.endDate}
+
+ 📅 {event.startDate} ~ {event.endDate}
+
+ {/* 진행률 바 (진행중인 이벤트만) */}
+ {event.status === 'active' && (
+
+
+
+ 이벤트 진행률
+
+
+ {Math.round(calculateProgress(event))}%
+
+
+
+
+ )}
{/* Real-time KPIs */}
-
-
-
+
+
+
실시간 현황
-
+
@@ -183,56 +383,86 @@ export default function EventDetailPage() {
-
+
-
-
-
-
+
+
+
+
참여자
-
+
{event.participants}명
+
+ 목표: {event.targetParticipants}명 (
+ {Math.round((event.participants / event.targetParticipants) * 100)}%)
+
-
-
-
-
+
+
+
+
조회수
-
+
{event.views}
-
-
-
-
+
+
+
+
ROI
-
+
{event.roi}%
-
-
-
- conversion_path
-
-
+
+
+
+
전환율
-
+
{event.conversion}%
@@ -241,112 +471,236 @@ export default function EventDetailPage() {
- {/* Chart Section */}
-
-
- 참여 추이
+ {/* Chart Section - 참여 추이 */}
+
+
+ 📈 참여 추이
-
-
-
+
+
+
-
-
- show_chart
-
-
- 참여자 추이 차트
-
+
+
+ {/* Chart Section - 채널별 성과 & ROI 추이 */}
+
+
+
+ 📊 채널별 참여자
+
+
+
+
+
+
+
+
+
+
+
+
+ 💰 ROI 추이
+
+
+
+
+
+
+
+
+
+
+
{/* Event Details */}
-
-
- 이벤트 정보
+
+
+ 🎯 이벤트 정보
-
-
-
-
-
-
- 경품
-
- {event.prize}
-
-
-
-
-
-
-
-
-
- 참여 방법
-
- {event.method}
-
-
-
-
-
-
-
-
-
- 예상 비용
-
- {event.cost.toLocaleString()}원
-
-
-
-
-
-
-
+
+
+
+
+ 경품
+
+
+ {event.prize}
+
+
+
+
+
+
+
+ {getMethodIcon(event.method)}
+
+
+ 참여 방법
+
+
+ {event.method}
+
+
+
+
+
+
+
+
+
+
+ 예상 비용
+
+
+ {event.cost.toLocaleString()}원
+
+
+
+
+
+
+
+
+
+
배포 채널
-
+
{event.channels.map((channel) => (
-
+
))}
@@ -356,29 +710,31 @@ export default function EventDetailPage() {
{/* Quick Actions */}
-
-
- 빠른 작업
+
+
+ ⚡ 빠른 작업
-
+
router.push(`/events/${eventId}/participants`)}
>
-
-
- 참여자 목록
+
+
+
+ 참여자 목록
+
@@ -387,18 +743,20 @@ export default function EventDetailPage() {
elevation={0}
sx={{
cursor: 'pointer',
- borderRadius: 3,
- boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
+ borderRadius: 4,
+ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
transition: 'all 0.2s',
'&:hover': {
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
- transform: 'translateY(-2px)',
+ transform: 'translateY(-4px)',
},
}}
>
-
-
- 이벤트 수정
+
+
+
+ 이벤트 수정
+
@@ -407,18 +765,20 @@ export default function EventDetailPage() {
elevation={0}
sx={{
cursor: 'pointer',
- borderRadius: 3,
- boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
+ borderRadius: 4,
+ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
transition: 'all 0.2s',
'&:hover': {
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
- transform: 'translateY(-2px)',
+ transform: 'translateY(-4px)',
},
}}
>
-
-
- 공유하기
+
+
+
+ 공유하기
+
@@ -427,18 +787,20 @@ export default function EventDetailPage() {
elevation={0}
sx={{
cursor: 'pointer',
- borderRadius: 3,
- boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
+ borderRadius: 4,
+ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
transition: 'all 0.2s',
'&:hover': {
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
- transform: 'translateY(-2px)',
+ transform: 'translateY(-4px)',
},
}}
>
-
-
- 데이터 다운
+
+
+
+ 데이터 다운
+
@@ -446,51 +808,51 @@ export default function EventDetailPage() {
{/* Recent Participants */}
-
-
-
- 최근 참여자
+
+
+
+ 👥 최근 참여자
-
-
+
+
{recentParticipants.map((participant, index) => (
- {index > 0 && }
+ {index > 0 && }
-
+
-
+
-
+
{participant.name}
-
+
{participant.phone}
-
+
{participant.time}