mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 10:56:23 +00:00
이벤트 상세 페이지 디자인 개선 및 차트 추가
- 전체 간격 2배 이상 확대하여 다른 페이지와 디자인 통일 - 실제 Chart.js 라이브러리로 3개 차트 구현 - 참여 추이 차트 (Line): 7일/30일/전체 기간 선택 가능 - 채널별 참여자 차트 (Bar): 우리동네TV, 링고비즈, SNS - ROI 추이 차트 (Line): 주차별 ROI 성장 추이 - 상태 배지 추가 (AI 추천, 마감임박, 인기, 높은 ROI, 신규) - 진행중인 이벤트에 진행률 바 추가 - KPI 카드에 그라데이션 배경 적용 및 목표 달성률 표시 - 이벤트 정보 섹션 디자인 개선 (아이콘 색상, 간격 확대) - Quick Actions 카드 hover 효과 개선 - 최근 참여자 아바타 디자인 개선 - 실시간 업데이트 인디케이터에 pulse 애니메이션 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e8ea659c0b
commit
de7726ffad
@ -15,6 +15,7 @@ import {
|
|||||||
Menu,
|
Menu,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Divider,
|
Divider,
|
||||||
|
LinearProgress,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import {
|
import {
|
||||||
MoreVert,
|
MoreVert,
|
||||||
@ -23,13 +24,63 @@ import {
|
|||||||
TrendingUp,
|
TrendingUp,
|
||||||
Share,
|
Share,
|
||||||
CardGiftcard,
|
CardGiftcard,
|
||||||
HowToReg,
|
|
||||||
AttachMoney,
|
AttachMoney,
|
||||||
People,
|
People,
|
||||||
Edit,
|
Edit,
|
||||||
Download,
|
Download,
|
||||||
Person,
|
Person,
|
||||||
|
Phone,
|
||||||
|
Email,
|
||||||
|
ShoppingCart,
|
||||||
|
Warning,
|
||||||
|
LocalFireDepartment,
|
||||||
|
Star,
|
||||||
|
NewReleases,
|
||||||
} from '@mui/icons-material';
|
} 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 데이터
|
// Mock 데이터
|
||||||
const mockEventData = {
|
const mockEventData = {
|
||||||
@ -41,12 +92,17 @@ const mockEventData = {
|
|||||||
prize: '커피 쿠폰',
|
prize: '커피 쿠폰',
|
||||||
method: 'SNS 팔로우',
|
method: 'SNS 팔로우',
|
||||||
cost: 250000,
|
cost: 250000,
|
||||||
channels: ['홈페이지', '카카오톡', 'Instagram'],
|
channels: ['우리동네TV', '링고비즈', 'SNS'],
|
||||||
participants: 128,
|
participants: 128,
|
||||||
views: 456,
|
views: 456,
|
||||||
roi: 450,
|
roi: 450,
|
||||||
conversion: 28,
|
conversion: 28,
|
||||||
|
targetParticipants: 200,
|
||||||
isAIRecommended: true,
|
isAIRecommended: true,
|
||||||
|
isUrgent: false,
|
||||||
|
isPopular: true,
|
||||||
|
isHighROI: true,
|
||||||
|
isNew: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const recentParticipants = [
|
const recentParticipants = [
|
||||||
@ -57,6 +113,86 @@ const recentParticipants = [
|
|||||||
{ name: '정*희', phone: '010-****-7890', time: '2시간 전' },
|
{ 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 <Phone sx={{ fontSize: 18 }} />;
|
||||||
|
case 'SNS 팔로우':
|
||||||
|
return <Share sx={{ fontSize: 18 }} />;
|
||||||
|
case '구매 인증':
|
||||||
|
return <ShoppingCart sx={{ fontSize: 18 }} />;
|
||||||
|
case '이메일 등록':
|
||||||
|
return <Email sx={{ fontSize: 18 }} />;
|
||||||
|
default:
|
||||||
|
return <Share sx={{ fontSize: 18 }} />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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() {
|
export default function EventDetailPage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@ -119,11 +255,11 @@ export default function EventDetailPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 10 }}>
|
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 10 }}>
|
||||||
<Container maxWidth="lg" sx={{ pt: 4, pb: 4, px: { xs: 3, sm: 3, md: 4 } }}>
|
<Container maxWidth="lg" sx={{ pt: 8, pb: 8, px: { xs: 6, sm: 8, md: 10 } }}>
|
||||||
{/* Event Header */}
|
{/* Event Header */}
|
||||||
<Box sx={{ mb: 4 }}>
|
<Box sx={{ mb: 8 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 4 }}>
|
||||||
<Typography variant="h4" sx={{ fontWeight: 700 }}>
|
<Typography variant="h4" sx={{ fontWeight: 700, fontSize: '2rem' }}>
|
||||||
{event.title}
|
{event.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<IconButton onClick={handleMenuOpen}>
|
<IconButton onClick={handleMenuOpen}>
|
||||||
@ -131,13 +267,13 @@ export default function EventDetailPage() {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
<Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleMenuClose}>
|
<Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleMenuClose}>
|
||||||
<MenuItem onClick={handleMenuClose}>
|
<MenuItem onClick={handleMenuClose}>
|
||||||
<Edit sx={{ mr: 1 }} /> 이벤트 수정
|
<Edit sx={{ mr: 2 }} /> 이벤트 수정
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={handleMenuClose}>
|
<MenuItem onClick={handleMenuClose}>
|
||||||
<Share sx={{ mr: 1 }} /> 공유하기
|
<Share sx={{ mr: 2 }} /> 공유하기
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={handleMenuClose}>
|
<MenuItem onClick={handleMenuClose}>
|
||||||
<Download sx={{ mr: 1 }} /> 데이터 다운로드
|
<Download sx={{ mr: 2 }} /> 데이터 다운로드
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Divider />
|
<Divider />
|
||||||
<MenuItem onClick={handleMenuClose} sx={{ color: 'error.main' }}>
|
<MenuItem onClick={handleMenuClose} sx={{ color: 'error.main' }}>
|
||||||
@ -146,35 +282,99 @@ export default function EventDetailPage() {
|
|||||||
</Menu>
|
</Menu>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 2 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, flexWrap: 'wrap', mb: 4 }}>
|
||||||
<Chip label={getStatusText(event.status)} color={getStatusColor(event.status) as any} size="small" />
|
<Chip
|
||||||
|
label={getStatusText(event.status)}
|
||||||
|
color={getStatusColor(event.status) as any}
|
||||||
|
size="medium"
|
||||||
|
/>
|
||||||
{event.isAIRecommended && (
|
{event.isAIRecommended && (
|
||||||
|
<Chip label="AI 추천" size="medium" sx={{ bgcolor: colors.purpleLight, color: colors.purple }} />
|
||||||
|
)}
|
||||||
|
{event.isUrgent && (
|
||||||
<Chip
|
<Chip
|
||||||
label="AI 추천"
|
icon={<Warning />}
|
||||||
size="small"
|
label="마감임박"
|
||||||
sx={{ bgcolor: 'rgba(0, 102, 255, 0.1)', color: 'info.main' }}
|
size="medium"
|
||||||
|
sx={{ bgcolor: '#FEF3C7', color: '#92400E' }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{event.isPopular && (
|
||||||
|
<Chip
|
||||||
|
icon={<LocalFireDepartment />}
|
||||||
|
label="인기"
|
||||||
|
size="medium"
|
||||||
|
sx={{ bgcolor: '#FEE2E2', color: '#991B1B' }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{event.isHighROI && (
|
||||||
|
<Chip
|
||||||
|
icon={<Star />}
|
||||||
|
label="높은 ROI"
|
||||||
|
size="medium"
|
||||||
|
sx={{ bgcolor: '#DCFCE7', color: '#166534' }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{event.isNew && (
|
||||||
|
<Chip
|
||||||
|
icon={<NewReleases />}
|
||||||
|
label="신규"
|
||||||
|
size="medium"
|
||||||
|
sx={{ bgcolor: '#DBEAFE', color: '#1E40AF' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Typography variant="body1" color="text.secondary">
|
<Typography variant="body1" color="text.secondary" sx={{ fontSize: '1rem', mb: 4 }}>
|
||||||
{event.startDate} ~ {event.endDate}
|
📅 {event.startDate} ~ {event.endDate}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
|
{/* 진행률 바 (진행중인 이벤트만) */}
|
||||||
|
{event.status === 'active' && (
|
||||||
|
<Box>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}>
|
||||||
|
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||||
|
이벤트 진행률
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||||
|
{Math.round(calculateProgress(event))}%
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<LinearProgress
|
||||||
|
variant="determinate"
|
||||||
|
value={calculateProgress(event)}
|
||||||
|
sx={{
|
||||||
|
height: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
bgcolor: colors.gray[100],
|
||||||
|
'& .MuiLinearProgress-bar': {
|
||||||
|
background: `linear-gradient(90deg, ${colors.mint} 0%, ${colors.blue} 100%)`,
|
||||||
|
borderRadius: 5,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Real-time KPIs */}
|
{/* Real-time KPIs */}
|
||||||
<Box sx={{ mb: 5 }}>
|
<Box sx={{ mb: 10 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 3 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 6 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, fontSize: '1.5rem' }}>
|
||||||
실시간 현황
|
실시간 현황
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, color: 'success.main' }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, color: 'success.main' }}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: 8,
|
width: 10,
|
||||||
height: 8,
|
height: 10,
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
bgcolor: 'success.main',
|
bgcolor: 'success.main',
|
||||||
|
animation: 'pulse 2s infinite',
|
||||||
|
'@keyframes pulse': {
|
||||||
|
'0%, 100%': { opacity: 1 },
|
||||||
|
'50%': { opacity: 0.5 },
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||||
@ -183,56 +383,86 @@ export default function EventDetailPage() {
|
|||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={6}>
|
||||||
<Grid item xs={6} md={3}>
|
<Grid item xs={6} md={3}>
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
<Card
|
||||||
<CardContent sx={{ textAlign: 'center', py: 3 }}>
|
elevation={0}
|
||||||
<Group color="primary" sx={{ fontSize: 32, mb: 1 }} />
|
sx={{
|
||||||
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
|
borderRadius: 4,
|
||||||
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.purpleLight} 100%)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent sx={{ textAlign: 'center', py: 6, px: 4 }}>
|
||||||
|
<Group sx={{ fontSize: 40, mb: 2, color: 'white' }} />
|
||||||
|
<Typography variant="caption" display="block" sx={{ mb: 2, color: 'rgba(255,255,255,0.9)' }}>
|
||||||
참여자
|
참여자
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
{event.participants}명
|
{event.participants}명
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Typography variant="caption" sx={{ color: 'rgba(255,255,255,0.8)', mt: 1, display: 'block' }}>
|
||||||
|
목표: {event.targetParticipants}명 (
|
||||||
|
{Math.round((event.participants / event.targetParticipants) * 100)}%)
|
||||||
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6} md={3}>
|
<Grid item xs={6} md={3}>
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
<Card
|
||||||
<CardContent sx={{ textAlign: 'center', py: 3 }}>
|
elevation={0}
|
||||||
<Visibility color="info" sx={{ fontSize: 32, mb: 1 }} />
|
sx={{
|
||||||
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
|
borderRadius: 4,
|
||||||
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
|
background: `linear-gradient(135deg, ${colors.blue} 0%, #93C5FD 100%)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent sx={{ textAlign: 'center', py: 6, px: 4 }}>
|
||||||
|
<Visibility sx={{ fontSize: 40, mb: 2, color: 'white' }} />
|
||||||
|
<Typography variant="caption" display="block" sx={{ mb: 2, color: 'rgba(255,255,255,0.9)' }}>
|
||||||
조회수
|
조회수
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
{event.views}
|
{event.views}
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6} md={3}>
|
<Grid item xs={6} md={3}>
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
<Card
|
||||||
<CardContent sx={{ textAlign: 'center', py: 3 }}>
|
elevation={0}
|
||||||
<TrendingUp color="success" sx={{ fontSize: 32, mb: 1 }} />
|
sx={{
|
||||||
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
|
borderRadius: 4,
|
||||||
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
|
background: `linear-gradient(135deg, ${colors.mint} 0%, #6EE7B7 100%)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent sx={{ textAlign: 'center', py: 6, px: 4 }}>
|
||||||
|
<TrendingUp sx={{ fontSize: 40, mb: 2, color: 'white' }} />
|
||||||
|
<Typography variant="caption" display="block" sx={{ mb: 2, color: 'rgba(255,255,255,0.9)' }}>
|
||||||
ROI
|
ROI
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h5" sx={{ fontWeight: 700, color: 'success.main' }}>
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
{event.roi}%
|
{event.roi}%
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6} md={3}>
|
<Grid item xs={6} md={3}>
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
<Card
|
||||||
<CardContent sx={{ textAlign: 'center', py: 3 }}>
|
elevation={0}
|
||||||
<span className="material-icons" style={{ fontSize: 32, marginBottom: 8, color: '#1976d2' }}>
|
sx={{
|
||||||
conversion_path
|
borderRadius: 4,
|
||||||
</span>
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
|
background: `linear-gradient(135deg, ${colors.orange} 0%, #FCD34D 100%)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent sx={{ textAlign: 'center', py: 6, px: 4 }}>
|
||||||
|
<TrendingUp sx={{ fontSize: 40, mb: 2, color: 'white' }} />
|
||||||
|
<Typography variant="caption" display="block" sx={{ mb: 2, color: 'rgba(255,255,255,0.9)' }}>
|
||||||
전환율
|
전환율
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
{event.conversion}%
|
{event.conversion}%
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@ -241,112 +471,236 @@ export default function EventDetailPage() {
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Chart Section */}
|
{/* Chart Section - 참여 추이 */}
|
||||||
<Box sx={{ mb: 5 }}>
|
<Box sx={{ mb: 10 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, mb: 6, fontSize: '1.5rem' }}>
|
||||||
참여 추이
|
📈 참여 추이
|
||||||
</Typography>
|
</Typography>
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
<CardContent sx={{ p: 3 }}>
|
<CardContent sx={{ p: 6 }}>
|
||||||
<Box sx={{ display: 'flex', gap: 1, mb: 3 }}>
|
<Box sx={{ display: 'flex', gap: 2, mb: 6 }}>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="medium"
|
||||||
variant={chartPeriod === '7d' ? 'contained' : 'outlined'}
|
variant={chartPeriod === '7d' ? 'contained' : 'outlined'}
|
||||||
onClick={() => setChartPeriod('7d')}
|
onClick={() => setChartPeriod('7d')}
|
||||||
|
sx={{ borderRadius: 2 }}
|
||||||
>
|
>
|
||||||
7일
|
7일
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="medium"
|
||||||
variant={chartPeriod === '30d' ? 'contained' : 'outlined'}
|
variant={chartPeriod === '30d' ? 'contained' : 'outlined'}
|
||||||
onClick={() => setChartPeriod('30d')}
|
onClick={() => setChartPeriod('30d')}
|
||||||
|
sx={{ borderRadius: 2 }}
|
||||||
>
|
>
|
||||||
30일
|
30일
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="medium"
|
||||||
variant={chartPeriod === 'all' ? 'contained' : 'outlined'}
|
variant={chartPeriod === 'all' ? 'contained' : 'outlined'}
|
||||||
onClick={() => setChartPeriod('all')}
|
onClick={() => setChartPeriod('all')}
|
||||||
|
sx={{ borderRadius: 2 }}
|
||||||
>
|
>
|
||||||
전체
|
전체
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box
|
<Box sx={{ height: 320 }}>
|
||||||
sx={{
|
<Line
|
||||||
height: 200,
|
data={generateParticipationTrendData(chartPeriod)}
|
||||||
bgcolor: 'grey.100',
|
options={{
|
||||||
borderRadius: 2,
|
responsive: true,
|
||||||
display: 'flex',
|
maintainAspectRatio: false,
|
||||||
alignItems: 'center',
|
plugins: {
|
||||||
justifyContent: 'center',
|
legend: {
|
||||||
flexDirection: 'column',
|
display: true,
|
||||||
}}
|
position: 'top' as const,
|
||||||
>
|
},
|
||||||
<span className="material-icons" style={{ fontSize: 48, color: '#9e9e9e' }}>
|
tooltip: {
|
||||||
show_chart
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
</span>
|
padding: 12,
|
||||||
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
|
titleFont: { size: 14, weight: 'bold' },
|
||||||
참여자 추이 차트
|
bodyFont: { size: 13 },
|
||||||
</Typography>
|
},
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(0, 0, 0, 0.05)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
grid: {
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* Chart Section - 채널별 성과 & ROI 추이 */}
|
||||||
|
<Grid container spacing={6} sx={{ mb: 10 }}>
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Typography variant="h5" sx={{ fontWeight: 700, mb: 6, fontSize: '1.5rem' }}>
|
||||||
|
📊 채널별 참여자
|
||||||
|
</Typography>
|
||||||
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
|
<CardContent sx={{ p: 6 }}>
|
||||||
|
<Box sx={{ height: 320 }}>
|
||||||
|
<Bar
|
||||||
|
data={channelPerformanceData}
|
||||||
|
options={{
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
padding: 12,
|
||||||
|
titleFont: { size: 14, weight: 'bold' },
|
||||||
|
bodyFont: { size: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(0, 0, 0, 0.05)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
grid: {
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={12} md={6}>
|
||||||
|
<Typography variant="h5" sx={{ fontWeight: 700, mb: 6, fontSize: '1.5rem' }}>
|
||||||
|
💰 ROI 추이
|
||||||
|
</Typography>
|
||||||
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
|
<CardContent sx={{ p: 6 }}>
|
||||||
|
<Box sx={{ height: 320 }}>
|
||||||
|
<Line
|
||||||
|
data={roiTrendData}
|
||||||
|
options={{
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: true,
|
||||||
|
position: 'top' as const,
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
padding: 12,
|
||||||
|
titleFont: { size: 14, weight: 'bold' },
|
||||||
|
bodyFont: { size: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(0, 0, 0, 0.05)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
grid: {
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
{/* Event Details */}
|
{/* Event Details */}
|
||||||
<Box sx={{ mb: 5 }}>
|
<Box sx={{ mb: 10 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, mb: 6, fontSize: '1.5rem' }}>
|
||||||
이벤트 정보
|
🎯 이벤트 정보
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
<CardContent sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
|
<CardContent sx={{ display: 'flex', alignItems: 'flex-start', gap: 3, p: 4 }}>
|
||||||
<CardGiftcard color="error" />
|
<CardGiftcard sx={{ fontSize: 28, color: colors.pink }} />
|
||||||
<Box sx={{ flex: 1 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 0.5 }}>
|
|
||||||
경품
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body1">{event.prize}</Typography>
|
|
||||||
</Box>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
|
||||||
<CardContent sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
|
|
||||||
<HowToReg color="error" />
|
|
||||||
<Box sx={{ flex: 1 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 0.5 }}>
|
|
||||||
참여 방법
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body1">{event.method}</Typography>
|
|
||||||
</Box>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
|
||||||
<CardContent sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
|
|
||||||
<AttachMoney color="error" />
|
|
||||||
<Box sx={{ flex: 1 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 0.5 }}>
|
|
||||||
예상 비용
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body1">{event.cost.toLocaleString()}원</Typography>
|
|
||||||
</Box>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
|
||||||
<CardContent sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
|
|
||||||
<Share color="error" />
|
|
||||||
<Box sx={{ flex: 1 }}>
|
<Box sx={{ flex: 1 }}>
|
||||||
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
|
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
|
||||||
|
경품
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h6" sx={{ fontWeight: 600 }}>
|
||||||
|
{event.prize}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
|
<CardContent sx={{ display: 'flex', alignItems: 'flex-start', gap: 3, p: 4 }}>
|
||||||
|
{getMethodIcon(event.method)}
|
||||||
|
<Box sx={{ flex: 1 }}>
|
||||||
|
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
|
||||||
|
참여 방법
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h6" sx={{ fontWeight: 600 }}>
|
||||||
|
{event.method}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
|
<CardContent sx={{ display: 'flex', alignItems: 'flex-start', gap: 3, p: 4 }}>
|
||||||
|
<AttachMoney sx={{ fontSize: 28, color: colors.mint }} />
|
||||||
|
<Box sx={{ flex: 1 }}>
|
||||||
|
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 1 }}>
|
||||||
|
예상 비용
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h6" sx={{ fontWeight: 600 }}>
|
||||||
|
{event.cost.toLocaleString()}원
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
|
<CardContent sx={{ display: 'flex', alignItems: 'flex-start', gap: 3, p: 4 }}>
|
||||||
|
<Share sx={{ fontSize: 28, color: colors.blue }} />
|
||||||
|
<Box sx={{ flex: 1 }}>
|
||||||
|
<Typography variant="caption" color="text.secondary" display="block" sx={{ mb: 2 }}>
|
||||||
배포 채널
|
배포 채널
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2 }}>
|
||||||
{event.channels.map((channel) => (
|
{event.channels.map((channel) => (
|
||||||
<Chip key={channel} label={channel} size="small" color="success" />
|
<Chip
|
||||||
|
key={channel}
|
||||||
|
label={channel}
|
||||||
|
size="medium"
|
||||||
|
sx={{
|
||||||
|
bgcolor: colors.purpleLight,
|
||||||
|
color: colors.purple,
|
||||||
|
fontWeight: 600,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@ -356,29 +710,31 @@ export default function EventDetailPage() {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Quick Actions */}
|
{/* Quick Actions */}
|
||||||
<Box sx={{ mb: 5 }}>
|
<Box sx={{ mb: 10 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, mb: 6, fontSize: '1.5rem' }}>
|
||||||
빠른 작업
|
⚡ 빠른 작업
|
||||||
</Typography>
|
</Typography>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={4}>
|
||||||
<Grid item xs={6} md={3}>
|
<Grid item xs={6} md={3}>
|
||||||
<Card
|
<Card
|
||||||
elevation={0}
|
elevation={0}
|
||||||
sx={{
|
sx={{
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
borderRadius: 3,
|
borderRadius: 4,
|
||||||
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
transition: 'all 0.2s',
|
transition: 'all 0.2s',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
||||||
transform: 'translateY(-2px)',
|
transform: 'translateY(-4px)',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onClick={() => router.push(`/events/${eventId}/participants`)}
|
onClick={() => router.push(`/events/${eventId}/participants`)}
|
||||||
>
|
>
|
||||||
<CardContent sx={{ textAlign: 'center', py: 3 }}>
|
<CardContent sx={{ textAlign: 'center', py: 5 }}>
|
||||||
<People color="error" sx={{ fontSize: 32, mb: 1 }} />
|
<People sx={{ fontSize: 40, mb: 2, color: colors.pink }} />
|
||||||
<Typography variant="body2">참여자 목록</Typography>
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
참여자 목록
|
||||||
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -387,18 +743,20 @@ export default function EventDetailPage() {
|
|||||||
elevation={0}
|
elevation={0}
|
||||||
sx={{
|
sx={{
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
borderRadius: 3,
|
borderRadius: 4,
|
||||||
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
transition: 'all 0.2s',
|
transition: 'all 0.2s',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
||||||
transform: 'translateY(-2px)',
|
transform: 'translateY(-4px)',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CardContent sx={{ textAlign: 'center', py: 3 }}>
|
<CardContent sx={{ textAlign: 'center', py: 5 }}>
|
||||||
<Edit color="info" sx={{ fontSize: 32, mb: 1 }} />
|
<Edit sx={{ fontSize: 40, mb: 2, color: colors.blue }} />
|
||||||
<Typography variant="body2">이벤트 수정</Typography>
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
이벤트 수정
|
||||||
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -407,18 +765,20 @@ export default function EventDetailPage() {
|
|||||||
elevation={0}
|
elevation={0}
|
||||||
sx={{
|
sx={{
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
borderRadius: 3,
|
borderRadius: 4,
|
||||||
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
transition: 'all 0.2s',
|
transition: 'all 0.2s',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
||||||
transform: 'translateY(-2px)',
|
transform: 'translateY(-4px)',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CardContent sx={{ textAlign: 'center', py: 3 }}>
|
<CardContent sx={{ textAlign: 'center', py: 5 }}>
|
||||||
<Share sx={{ fontSize: 32, mb: 1, color: 'text.secondary' }} />
|
<Share sx={{ fontSize: 40, mb: 2, color: colors.purple }} />
|
||||||
<Typography variant="body2">공유하기</Typography>
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
공유하기
|
||||||
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -427,18 +787,20 @@ export default function EventDetailPage() {
|
|||||||
elevation={0}
|
elevation={0}
|
||||||
sx={{
|
sx={{
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
borderRadius: 3,
|
borderRadius: 4,
|
||||||
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
transition: 'all 0.2s',
|
transition: 'all 0.2s',
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
||||||
transform: 'translateY(-2px)',
|
transform: 'translateY(-4px)',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CardContent sx={{ textAlign: 'center', py: 3 }}>
|
<CardContent sx={{ textAlign: 'center', py: 5 }}>
|
||||||
<Download sx={{ fontSize: 32, mb: 1, color: 'text.secondary' }} />
|
<Download sx={{ fontSize: 40, mb: 2, color: colors.mint }} />
|
||||||
<Typography variant="body2">데이터 다운</Typography>
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
데이터 다운
|
||||||
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -446,51 +808,51 @@ export default function EventDetailPage() {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Recent Participants */}
|
{/* Recent Participants */}
|
||||||
<Box sx={{ mb: 5 }}>
|
<Box sx={{ mb: 10 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 3 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 6 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, fontSize: '1.5rem' }}>
|
||||||
최근 참여자
|
👥 최근 참여자
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="medium"
|
||||||
endIcon={<span className="material-icons" style={{ fontSize: 16 }}>chevron_right</span>}
|
endIcon={<span className="material-icons" style={{ fontSize: 18 }}>chevron_right</span>}
|
||||||
onClick={() => router.push(`/events/${eventId}/participants`)}
|
onClick={() => router.push(`/events/${eventId}/participants`)}
|
||||||
sx={{ color: 'error.main', fontWeight: 600 }}
|
sx={{ color: colors.pink, fontWeight: 600 }}
|
||||||
>
|
>
|
||||||
전체보기
|
전체보기
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Card elevation={0} sx={{ borderRadius: 3, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)' }}>
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
<CardContent sx={{ p: 3 }}>
|
<CardContent sx={{ p: 6 }}>
|
||||||
{recentParticipants.map((participant, index) => (
|
{recentParticipants.map((participant, index) => (
|
||||||
<Box key={index}>
|
<Box key={index}>
|
||||||
{index > 0 && <Divider sx={{ my: 2 }} />}
|
{index > 0 && <Divider sx={{ my: 4 }} />}
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3 }}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: 40,
|
width: 48,
|
||||||
height: 40,
|
height: 48,
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
bgcolor: 'grey.200',
|
bgcolor: colors.purpleLight,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Person sx={{ color: 'text.secondary' }} />
|
<Person sx={{ color: colors.purple, fontSize: 24 }} />
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
<Typography variant="body1" sx={{ fontWeight: 600, mb: 0.5 }}>
|
||||||
{participant.name}
|
{participant.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Typography variant="body2" color="text.secondary">
|
||||||
{participant.phone}
|
{participant.phone}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Typography variant="body2" color="text.secondary">
|
||||||
{participant.time}
|
{participant.time}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user