mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 09:36:23 +00:00
추첨 페이지 디자인 개선 및 통일
- 페이지 헤더 및 요약 카드 추가 (이벤트명, 참여자 수) - 추첨 설정 카드 간격 2배 확대 및 버튼 크기 증가 - 추첨 이력 섹션 간격 확대 및 카드 디자인 개선 - 당첨자 목록 카드 디자인 개선 (순위 배지 크기 증가, 간격 확대) - 모든 액션 버튼에 그라데이션 배경 적용 - 모든 다이얼로그 컴포넌트 간격 및 디자인 통일 - 애니메이션 다이얼로그 크기 증가 - 미사용 import 제거 (EmojiEvents) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
de7726ffad
commit
28f0ebde33
@ -29,8 +29,27 @@ import {
|
|||||||
Add,
|
Add,
|
||||||
Remove,
|
Remove,
|
||||||
Info,
|
Info,
|
||||||
|
People,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
|
|
||||||
|
// 디자인 시스템 색상
|
||||||
|
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 = {
|
||||||
name: '신규고객 유치 이벤트',
|
name: '신규고객 유치 이벤트',
|
||||||
@ -163,55 +182,77 @@ export default function DrawPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 4 }}>
|
<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 } }}>
|
||||||
{/* Setup View (Before Drawing) */}
|
{/* Setup View (Before Drawing) */}
|
||||||
{!showResults && (
|
{!showResults && (
|
||||||
<>
|
<>
|
||||||
{/* Event Info */}
|
{/* Page Header */}
|
||||||
<Card sx={{ mb: 3, borderRadius: 3 }}>
|
<Box sx={{ mb: 8 }}>
|
||||||
<CardContent>
|
<Typography variant="h4" sx={{ fontWeight: 700, fontSize: '2rem', mb: 2 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 2 }}>
|
🎲 당첨자 추첨
|
||||||
<EventNote color="error" />
|
</Typography>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>
|
<Typography variant="body1" color="text.secondary">
|
||||||
이벤트 정보
|
참여자 중에서 공정하게 당첨자를 선정하세요
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
{/* Event Info Summary Cards */}
|
||||||
|
<Grid container spacing={6} sx={{ mb: 10 }}>
|
||||||
|
<Grid item xs={6} md={6}>
|
||||||
|
<Card
|
||||||
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
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 }}>
|
||||||
|
<EventNote 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="body1">{mockEventData.name}</Typography>
|
<Typography variant="h6" sx={{ fontWeight: 700, color: 'white' }}>
|
||||||
</Box>
|
{mockEventData.name}
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
|
||||||
총 참여자
|
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>
|
|
||||||
{mockEventData.totalParticipants}명
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
|
||||||
추첨 상태
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="body1">추첨 전</Typography>
|
|
||||||
</Box>
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6} md={6}>
|
||||||
|
<Card
|
||||||
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
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 }}>
|
||||||
|
<People sx={{ fontSize: 40, mb: 2, color: 'white' }} />
|
||||||
|
<Typography variant="caption" display="block" sx={{ mb: 2, color: 'rgba(255,255,255,0.9)' }}>
|
||||||
|
총 참여자
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
|
{mockEventData.totalParticipants}명
|
||||||
|
</Typography>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
{/* Drawing Settings */}
|
{/* Drawing Settings */}
|
||||||
<Card sx={{ mb: 3, borderRadius: 3 }}>
|
<Card elevation={0} sx={{ mb: 10, borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
<CardContent>
|
<CardContent sx={{ p: 6 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 3 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 6 }}>
|
||||||
<Tune color="error" />
|
<Tune sx={{ fontSize: 32, color: colors.pink }} />
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, fontSize: '1.5rem' }}>
|
||||||
추첨 설정
|
추첨 설정
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{ mb: 3 }}>
|
<Box sx={{ mb: 6 }}>
|
||||||
<Typography variant="body2" sx={{ mb: 2 }}>
|
<Typography variant="h6" sx={{ mb: 4, fontWeight: 600 }}>
|
||||||
당첨 인원
|
당첨 인원
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -219,33 +260,44 @@ export default function DrawPage() {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
gap: 2,
|
gap: 4,
|
||||||
|
p: 4,
|
||||||
|
bgcolor: colors.gray[100],
|
||||||
|
borderRadius: 3,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={handleDecrease}
|
onClick={handleDecrease}
|
||||||
sx={{
|
sx={{
|
||||||
width: 48,
|
width: 60,
|
||||||
height: 48,
|
height: 60,
|
||||||
border: '1px solid',
|
border: '2px solid',
|
||||||
borderColor: 'divider',
|
borderColor: colors.purple,
|
||||||
|
color: colors.purple,
|
||||||
|
'&:hover': {
|
||||||
|
bgcolor: colors.purpleLight,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Remove />
|
<Remove sx={{ fontSize: 28 }} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Typography variant="h3" sx={{ fontWeight: 600, width: 80, textAlign: 'center' }}>
|
<Typography variant="h2" sx={{ fontWeight: 700, width: 120, textAlign: 'center', color: colors.purple }}>
|
||||||
{winnerCount}
|
{winnerCount}
|
||||||
</Typography>
|
</Typography>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={handleIncrease}
|
onClick={handleIncrease}
|
||||||
sx={{
|
sx={{
|
||||||
width: 48,
|
width: 60,
|
||||||
height: 48,
|
height: 60,
|
||||||
border: '1px solid',
|
border: '2px solid',
|
||||||
borderColor: 'divider',
|
borderColor: colors.purple,
|
||||||
|
color: colors.purple,
|
||||||
|
'&:hover': {
|
||||||
|
bgcolor: colors.purpleLight,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Add />
|
<Add sx={{ fontSize: 28 }} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@ -255,21 +307,42 @@ export default function DrawPage() {
|
|||||||
<Checkbox
|
<Checkbox
|
||||||
checked={storeBonus}
|
checked={storeBonus}
|
||||||
onChange={(e) => setStoreBonus(e.target.checked)}
|
onChange={(e) => setStoreBonus(e.target.checked)}
|
||||||
|
sx={{
|
||||||
|
color: colors.purple,
|
||||||
|
'&.Mui-checked': {
|
||||||
|
color: colors.purple,
|
||||||
|
},
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="매장 방문 고객 가산점 (가중치: 1.5배)"
|
label={
|
||||||
sx={{ mb: 3 }}
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
매장 방문 고객 가산점 (가중치: 1.5배)
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
sx={{ mb: 6 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box sx={{ bgcolor: 'background.default', p: 2, borderRadius: 2 }}>
|
<Box
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, mb: 1 }}>
|
sx={{
|
||||||
<Info sx={{ fontSize: 16 }} color="action" />
|
bgcolor: colors.purpleLight,
|
||||||
<Typography variant="body2" color="text.secondary">
|
p: 4,
|
||||||
|
borderRadius: 3,
|
||||||
|
border: `1px solid ${colors.purple}40`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, mb: 3 }}>
|
||||||
|
<Info sx={{ fontSize: 24, color: colors.purple }} />
|
||||||
|
<Typography variant="h6" sx={{ fontWeight: 600, color: colors.purple }}>
|
||||||
추첨 방식
|
추첨 방식
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Typography variant="body2">• 난수 기반 무작위 추첨</Typography>
|
<Typography variant="body1" sx={{ mb: 2, color: colors.gray[700] }}>
|
||||||
<Typography variant="body2">• 모든 추첨 과정은 자동 기록됩니다</Typography>
|
• 난수 기반 무작위 추첨
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" sx={{ color: colors.gray[700] }}>
|
||||||
|
• 모든 추첨 과정은 자동 기록됩니다
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@ -279,45 +352,75 @@ export default function DrawPage() {
|
|||||||
fullWidth
|
fullWidth
|
||||||
variant="contained"
|
variant="contained"
|
||||||
size="large"
|
size="large"
|
||||||
startIcon={<Casino />}
|
startIcon={<Casino sx={{ fontSize: 28 }} />}
|
||||||
onClick={handleStartDrawing}
|
onClick={handleStartDrawing}
|
||||||
sx={{ mb: 3, py: 1.5, borderRadius: 2, fontWeight: 700, fontSize: '1rem' }}
|
sx={{
|
||||||
|
mb: 10,
|
||||||
|
py: 3,
|
||||||
|
borderRadius: 4,
|
||||||
|
fontWeight: 700,
|
||||||
|
fontSize: '1.25rem',
|
||||||
|
background: `linear-gradient(135deg, ${colors.pink} 0%, ${colors.purple} 100%)`,
|
||||||
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
||||||
|
'&:hover': {
|
||||||
|
background: `linear-gradient(135deg, ${colors.pink} 0%, ${colors.purple} 100%)`,
|
||||||
|
boxShadow: '0 6px 16px rgba(0, 0, 0, 0.2)',
|
||||||
|
transform: 'translateY(-2px)',
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
추첨 시작
|
추첨 시작
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{/* Drawing History */}
|
{/* Drawing History */}
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, mb: 6, fontSize: '1.5rem' }}>
|
||||||
📜 추첨 이력 (최근 3건)
|
📜 추첨 이력
|
||||||
</Typography>
|
</Typography>
|
||||||
{mockDrawingHistory.length === 0 ? (
|
{mockDrawingHistory.length === 0 ? (
|
||||||
<Card sx={{ borderRadius: 3 }}>
|
<Card elevation={0} sx={{ borderRadius: 4, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}>
|
||||||
<CardContent sx={{ textAlign: 'center', py: 4 }}>
|
<CardContent sx={{ textAlign: 'center', py: 8 }}>
|
||||||
<Typography variant="body1" color="text.secondary">
|
<ListIcon sx={{ fontSize: 64, color: colors.gray[300], mb: 2 }} />
|
||||||
|
<Typography variant="h6" color="text.secondary">
|
||||||
추첨 이력이 없습니다
|
추첨 이력이 없습니다
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
) : (
|
) : (
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||||
{mockDrawingHistory.slice(0, 3).map((history, index) => (
|
{mockDrawingHistory.slice(0, 3).map((history, index) => (
|
||||||
<Card key={index} sx={{ borderRadius: 2 }}>
|
<Card
|
||||||
<CardContent>
|
key={index}
|
||||||
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
borderRadius: 4,
|
||||||
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent sx={{ p: 5 }}>
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="body1" sx={{ mb: 0.5 }}>
|
<Typography variant="h6" sx={{ mb: 2, fontWeight: 700 }}>
|
||||||
{history.date} {history.isRedraw && '(재추첨)'}
|
{history.date} {history.isRedraw && '(재추첨)'}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body1" color="text.secondary">
|
||||||
당첨자 {history.winnerCount}명
|
당첨자 {history.winnerCount}명
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Button
|
<Button
|
||||||
variant="text"
|
variant="outlined"
|
||||||
size="small"
|
size="medium"
|
||||||
onClick={() => handleHistoryDetail(history)}
|
onClick={() => handleHistoryDetail(history)}
|
||||||
startIcon={<ListIcon />}
|
startIcon={<ListIcon />}
|
||||||
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
borderColor: colors.purple,
|
||||||
|
color: colors.purple,
|
||||||
|
'&:hover': {
|
||||||
|
borderColor: colors.purple,
|
||||||
|
bgcolor: colors.purpleLight,
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
상세보기
|
상세보기
|
||||||
</Button>
|
</Button>
|
||||||
@ -335,51 +438,59 @@ export default function DrawPage() {
|
|||||||
{showResults && (
|
{showResults && (
|
||||||
<>
|
<>
|
||||||
{/* Results Header */}
|
{/* Results Header */}
|
||||||
<Box sx={{ textAlign: 'center', mb: 4 }}>
|
<Box sx={{ textAlign: 'center', mb: 10 }}>
|
||||||
<Typography variant="h4" sx={{ fontWeight: 700, mb: 1 }}>
|
<Typography variant="h4" sx={{ fontWeight: 700, mb: 4, fontSize: '2rem' }}>
|
||||||
🎉 추첨 완료!
|
🎉 추첨 완료!
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h6">
|
<Typography variant="h6" sx={{ fontSize: '1.25rem' }}>
|
||||||
총 {mockEventData.totalParticipants}명 중 {winnerCount}명 당첨
|
총 {mockEventData.totalParticipants}명 중 {winnerCount}명 당첨
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Winner List */}
|
{/* Winner List */}
|
||||||
<Box sx={{ mb: 4 }}>
|
<Box sx={{ mb: 10 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, mb: 6, fontSize: '1.5rem' }}>
|
||||||
🏆 당첨자 목록
|
🏆 당첨자 목록
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||||
{winners.map((winner, index) => {
|
{winners.map((winner, index) => {
|
||||||
const rank = index + 1;
|
const rank = index + 1;
|
||||||
return (
|
return (
|
||||||
<Card key={winner.id} sx={{ borderRadius: 3 }}>
|
<Card
|
||||||
<CardContent>
|
key={winner.id}
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
borderRadius: 4,
|
||||||
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent sx={{ p: 5 }}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: 48,
|
width: 64,
|
||||||
height: 48,
|
height: 64,
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
background: getRankClass(rank),
|
background: getRankClass(rank),
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
color: 'white',
|
color: 'white',
|
||||||
fontWeight: 600,
|
fontWeight: 700,
|
||||||
fontSize: 18,
|
fontSize: 20,
|
||||||
|
flexShrink: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{rank}위
|
{rank}위
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ flex: 1 }}>
|
<Box sx={{ flex: 1 }}>
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Typography variant="caption" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
|
||||||
응모번호: #{winner.id}
|
응모번호: #{winner.id}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 0.5 }}>
|
<Typography variant="h6" sx={{ fontWeight: 700, mb: 2, fontSize: '1.25rem' }}>
|
||||||
{winner.name} ({winner.phone})
|
{winner.name} ({winner.phone})
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body2" color="text.secondary" sx={{ fontSize: '1rem' }}>
|
||||||
참여: {winner.channel}{' '}
|
참여: {winner.channel}{' '}
|
||||||
{winner.hasBonus && storeBonus && '🌟'}
|
{winner.hasBonus && storeBonus && '🌟'}
|
||||||
</Typography>
|
</Typography>
|
||||||
@ -391,14 +502,18 @@ export default function DrawPage() {
|
|||||||
})}
|
})}
|
||||||
</Box>
|
</Box>
|
||||||
{storeBonus && (
|
{storeBonus && (
|
||||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', textAlign: 'center', mt: 2 }}>
|
<Typography
|
||||||
|
variant="caption"
|
||||||
|
color="text.secondary"
|
||||||
|
sx={{ display: 'block', textAlign: 'center', mt: 6, fontSize: '0.875rem' }}
|
||||||
|
>
|
||||||
🌟 매장 방문 고객 가산점 적용
|
🌟 매장 방문 고객 가산점 적용
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Action Buttons */}
|
{/* Action Buttons */}
|
||||||
<Grid container spacing={2} sx={{ mb: 2 }}>
|
<Grid container spacing={4} sx={{ mb: 4 }}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Button
|
<Button
|
||||||
fullWidth
|
fullWidth
|
||||||
@ -406,7 +521,16 @@ export default function DrawPage() {
|
|||||||
size="large"
|
size="large"
|
||||||
startIcon={<Download />}
|
startIcon={<Download />}
|
||||||
onClick={handleDownload}
|
onClick={handleDownload}
|
||||||
sx={{ borderRadius: 2 }}
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
py: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
borderWidth: 2,
|
||||||
|
'&:hover': {
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
엑셀다운로드
|
엑셀다운로드
|
||||||
</Button>
|
</Button>
|
||||||
@ -418,7 +542,16 @@ export default function DrawPage() {
|
|||||||
size="large"
|
size="large"
|
||||||
startIcon={<Refresh />}
|
startIcon={<Refresh />}
|
||||||
onClick={() => setRedrawDialogOpen(true)}
|
onClick={() => setRedrawDialogOpen(true)}
|
||||||
sx={{ borderRadius: 2 }}
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
py: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
borderWidth: 2,
|
||||||
|
'&:hover': {
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
재추첨
|
재추첨
|
||||||
</Button>
|
</Button>
|
||||||
@ -431,7 +564,18 @@ export default function DrawPage() {
|
|||||||
size="large"
|
size="large"
|
||||||
startIcon={<Notifications />}
|
startIcon={<Notifications />}
|
||||||
onClick={() => setNotifyDialogOpen(true)}
|
onClick={() => setNotifyDialogOpen(true)}
|
||||||
sx={{ mb: 2, py: 1.5, borderRadius: 2, fontWeight: 700, fontSize: '1rem' }}
|
sx={{
|
||||||
|
mb: 4,
|
||||||
|
py: 3,
|
||||||
|
borderRadius: 3,
|
||||||
|
fontWeight: 700,
|
||||||
|
fontSize: '1rem',
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
'&:hover': {
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
당첨자에게 알림 전송
|
당첨자에게 알림 전송
|
||||||
</Button>
|
</Button>
|
||||||
@ -441,7 +585,12 @@ export default function DrawPage() {
|
|||||||
variant="text"
|
variant="text"
|
||||||
size="large"
|
size="large"
|
||||||
onClick={handleBackToEvents}
|
onClick={handleBackToEvents}
|
||||||
sx={{ borderRadius: 2 }}
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
py: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
이벤트 목록으로
|
이벤트 목록으로
|
||||||
</Button>
|
</Button>
|
||||||
@ -457,14 +606,15 @@ export default function DrawPage() {
|
|||||||
sx: {
|
sx: {
|
||||||
bgcolor: 'rgba(0, 0, 0, 0.9)',
|
bgcolor: 'rgba(0, 0, 0, 0.9)',
|
||||||
color: 'white',
|
color: 'white',
|
||||||
|
borderRadius: 4,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogContent sx={{ textAlign: 'center', py: 8 }}>
|
<DialogContent sx={{ textAlign: 'center', py: 16 }}>
|
||||||
<Casino
|
<Casino
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: 80,
|
fontSize: 100,
|
||||||
mb: 3,
|
mb: 6,
|
||||||
animation: 'spin 0.5s infinite',
|
animation: 'spin 0.5s infinite',
|
||||||
'@keyframes spin': {
|
'@keyframes spin': {
|
||||||
'0%, 100%': { transform: 'rotate(0deg)' },
|
'0%, 100%': { transform: 'rotate(0deg)' },
|
||||||
@ -472,95 +622,228 @@ export default function DrawPage() {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Typography variant="h4" sx={{ fontWeight: 700, mb: 1 }}>
|
<Typography variant="h4" sx={{ fontWeight: 700, mb: 2, fontSize: '2rem' }}>
|
||||||
{animationText}
|
{animationText}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" sx={{ color: 'rgba(255,255,255,0.7)' }}>
|
<Typography variant="body1" sx={{ color: 'rgba(255,255,255,0.7)', fontSize: '1.125rem' }}>
|
||||||
{animationSubtext}
|
{animationSubtext}
|
||||||
</Typography>
|
</Typography>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
{/* Confirm Dialog */}
|
{/* Confirm Dialog */}
|
||||||
<Dialog open={confirmDialogOpen} onClose={() => setConfirmDialogOpen(false)} maxWidth="xs" fullWidth>
|
<Dialog
|
||||||
<DialogTitle>추첨 확인</DialogTitle>
|
open={confirmDialogOpen}
|
||||||
<DialogContent>
|
onClose={() => setConfirmDialogOpen(false)}
|
||||||
<Typography variant="body1" sx={{ textAlign: 'center' }}>
|
maxWidth="xs"
|
||||||
|
fullWidth
|
||||||
|
PaperProps={{ sx: { borderRadius: 4 } }}
|
||||||
|
>
|
||||||
|
<DialogTitle sx={{ pt: 6, px: 6, pb: 4, fontSize: '1.5rem', fontWeight: 700 }}>
|
||||||
|
추첨 확인
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent sx={{ px: 6, pb: 4 }}>
|
||||||
|
<Typography variant="body1" sx={{ textAlign: 'center', fontSize: '1.125rem' }}>
|
||||||
총 {mockEventData.totalParticipants}명 중 {winnerCount}명을 추첨하시겠습니까?
|
총 {mockEventData.totalParticipants}명 중 {winnerCount}명을 추첨하시겠습니까?
|
||||||
</Typography>
|
</Typography>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions sx={{ px: 6, pb: 6, pt: 4, gap: 2 }}>
|
||||||
<Button onClick={() => setConfirmDialogOpen(false)}>취소</Button>
|
<Button
|
||||||
<Button onClick={executeDrawing} variant="contained">
|
onClick={() => setConfirmDialogOpen(false)}
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
py: 2,
|
||||||
|
borderRadius: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
취소
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={executeDrawing}
|
||||||
|
variant="contained"
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
py: 2,
|
||||||
|
borderRadius: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
'&:hover': {
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
확인
|
확인
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
{/* Redraw Dialog */}
|
{/* Redraw Dialog */}
|
||||||
<Dialog open={redrawDialogOpen} onClose={() => setRedrawDialogOpen(false)} maxWidth="xs" fullWidth>
|
<Dialog
|
||||||
<DialogTitle>재추첨 확인</DialogTitle>
|
open={redrawDialogOpen}
|
||||||
<DialogContent>
|
onClose={() => setRedrawDialogOpen(false)}
|
||||||
<Typography variant="body1" sx={{ mb: 2, textAlign: 'center' }}>
|
maxWidth="xs"
|
||||||
|
fullWidth
|
||||||
|
PaperProps={{ sx: { borderRadius: 4 } }}
|
||||||
|
>
|
||||||
|
<DialogTitle sx={{ pt: 6, px: 6, pb: 4, fontSize: '1.5rem', fontWeight: 700 }}>
|
||||||
|
재추첨 확인
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent sx={{ px: 6, pb: 4 }}>
|
||||||
|
<Typography variant="body1" sx={{ mb: 4, textAlign: 'center', fontSize: '1.125rem' }}>
|
||||||
재추첨 시 현재 당첨자 정보가 변경됩니다.
|
재추첨 시 현재 당첨자 정보가 변경됩니다.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" sx={{ mb: 2, textAlign: 'center' }}>
|
<Typography variant="body1" sx={{ mb: 4, textAlign: 'center', fontSize: '1.125rem' }}>
|
||||||
계속하시겠습니까?
|
계속하시겠습니까?
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', textAlign: 'center' }}>
|
<Typography
|
||||||
|
variant="caption"
|
||||||
|
color="text.secondary"
|
||||||
|
sx={{ display: 'block', textAlign: 'center', fontSize: '0.875rem' }}
|
||||||
|
>
|
||||||
이전 추첨 이력은 보관됩니다
|
이전 추첨 이력은 보관됩니다
|
||||||
</Typography>
|
</Typography>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions sx={{ px: 6, pb: 6, pt: 4, gap: 2 }}>
|
||||||
<Button onClick={() => setRedrawDialogOpen(false)}>취소</Button>
|
<Button
|
||||||
<Button onClick={handleRedraw} variant="contained">
|
onClick={() => setRedrawDialogOpen(false)}
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
py: 2,
|
||||||
|
borderRadius: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
취소
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleRedraw}
|
||||||
|
variant="contained"
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
py: 2,
|
||||||
|
borderRadius: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
'&:hover': {
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
재추첨
|
재추첨
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
{/* Notify Dialog */}
|
{/* Notify Dialog */}
|
||||||
<Dialog open={notifyDialogOpen} onClose={() => setNotifyDialogOpen(false)} maxWidth="xs" fullWidth>
|
<Dialog
|
||||||
<DialogTitle>알림 전송</DialogTitle>
|
open={notifyDialogOpen}
|
||||||
<DialogContent>
|
onClose={() => setNotifyDialogOpen(false)}
|
||||||
<Typography variant="body1" sx={{ mb: 2, textAlign: 'center' }}>
|
maxWidth="xs"
|
||||||
|
fullWidth
|
||||||
|
PaperProps={{ sx: { borderRadius: 4 } }}
|
||||||
|
>
|
||||||
|
<DialogTitle sx={{ pt: 6, px: 6, pb: 4, fontSize: '1.5rem', fontWeight: 700 }}>
|
||||||
|
알림 전송
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent sx={{ px: 6, pb: 4 }}>
|
||||||
|
<Typography variant="body1" sx={{ mb: 4, textAlign: 'center', fontSize: '1.125rem' }}>
|
||||||
{winnerCount}명의 당첨자에게 SMS 알림을 전송하시겠습니까?
|
{winnerCount}명의 당첨자에게 SMS 알림을 전송하시겠습니까?
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', textAlign: 'center' }}>
|
<Typography
|
||||||
|
variant="caption"
|
||||||
|
color="text.secondary"
|
||||||
|
sx={{ display: 'block', textAlign: 'center', fontSize: '0.875rem' }}
|
||||||
|
>
|
||||||
예상 비용: {winnerCount * 100}원 (100원/건)
|
예상 비용: {winnerCount * 100}원 (100원/건)
|
||||||
</Typography>
|
</Typography>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions sx={{ px: 6, pb: 6, pt: 4, gap: 2 }}>
|
||||||
<Button onClick={() => setNotifyDialogOpen(false)}>취소</Button>
|
<Button
|
||||||
<Button onClick={handleNotify} variant="contained">
|
onClick={() => setNotifyDialogOpen(false)}
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
py: 2,
|
||||||
|
borderRadius: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
취소
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleNotify}
|
||||||
|
variant="contained"
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
py: 2,
|
||||||
|
borderRadius: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
'&:hover': {
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
전송
|
전송
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
{/* History Detail Dialog */}
|
{/* History Detail Dialog */}
|
||||||
<Dialog open={historyDetailOpen} onClose={() => setHistoryDetailOpen(false)} maxWidth="xs" fullWidth>
|
<Dialog
|
||||||
<DialogTitle>추첨 이력 상세</DialogTitle>
|
open={historyDetailOpen}
|
||||||
<DialogContent>
|
onClose={() => setHistoryDetailOpen(false)}
|
||||||
|
maxWidth="xs"
|
||||||
|
fullWidth
|
||||||
|
PaperProps={{ sx: { borderRadius: 4 } }}
|
||||||
|
>
|
||||||
|
<DialogTitle sx={{ pt: 6, px: 6, pb: 4, fontSize: '1.5rem', fontWeight: 700 }}>
|
||||||
|
추첨 이력 상세
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent sx={{ px: 6, pb: 4 }}>
|
||||||
{selectedHistory && (
|
{selectedHistory && (
|
||||||
<Box sx={{ p: 2 }}>
|
<Box sx={{ p: 4 }}>
|
||||||
<Typography variant="body1" sx={{ mb: 1 }}>
|
<Typography variant="body1" sx={{ mb: 3, fontSize: '1.125rem' }}>
|
||||||
추첨 일시: {selectedHistory.date}
|
추첨 일시: {selectedHistory.date}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" sx={{ mb: 1 }}>
|
<Typography variant="body1" sx={{ mb: 3, fontSize: '1.125rem' }}>
|
||||||
당첨 인원: {selectedHistory.winnerCount}명
|
당첨 인원: {selectedHistory.winnerCount}명
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" sx={{ mb: 2 }}>
|
<Typography variant="body1" sx={{ mb: 4, fontSize: '1.125rem' }}>
|
||||||
재추첨 여부: {selectedHistory.isRedraw ? '예' : '아니오'}
|
재추첨 여부: {selectedHistory.isRedraw ? '예' : '아니오'}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.875rem' }}>
|
||||||
※ 당첨자 정보는 개인정보 보호를 위해 마스킹 처리됩니다
|
※ 당첨자 정보는 개인정보 보호를 위해 마스킹 처리됩니다
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions sx={{ px: 6, pb: 6, pt: 4 }}>
|
||||||
<Button onClick={() => setHistoryDetailOpen(false)} variant="contained">
|
<Button
|
||||||
|
onClick={() => setHistoryDetailOpen(false)}
|
||||||
|
variant="contained"
|
||||||
|
fullWidth
|
||||||
|
sx={{
|
||||||
|
py: 2,
|
||||||
|
borderRadius: 3,
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
'&:hover': {
|
||||||
|
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
확인
|
확인
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@ -21,14 +21,37 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
|
Grid,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import {
|
import {
|
||||||
Search,
|
Search,
|
||||||
FilterList,
|
FilterList,
|
||||||
Casino,
|
Casino,
|
||||||
Download,
|
Download,
|
||||||
|
People,
|
||||||
|
TrendingUp,
|
||||||
|
Person,
|
||||||
|
AccessTime,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
|
|
||||||
|
// 디자인 시스템 색상
|
||||||
|
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 mockParticipants = [
|
const mockParticipants = [
|
||||||
{
|
{
|
||||||
@ -150,11 +173,117 @@ export default function ParticipantsPage() {
|
|||||||
alert('엑셀 다운로드 기능은 추후 구현됩니다');
|
alert('엑셀 다운로드 기능은 추후 구현됩니다');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 통계 계산
|
||||||
|
const stats = {
|
||||||
|
total: mockParticipants.length,
|
||||||
|
waiting: mockParticipants.filter((p) => p.status === 'waiting').length,
|
||||||
|
winner: mockParticipants.filter((p) => p.status === 'winner').length,
|
||||||
|
channelDistribution: {
|
||||||
|
uriTV: mockParticipants.filter((p) => p.channelType === 'uriTV').length,
|
||||||
|
ringoBiz: mockParticipants.filter((p) => p.channelType === 'ringoBiz').length,
|
||||||
|
sns: mockParticipants.filter((p) => p.channelType === 'sns').length,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
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 } }}>
|
||||||
|
{/* Page Header */}
|
||||||
|
<Box sx={{ mb: 8 }}>
|
||||||
|
<Typography variant="h4" sx={{ fontWeight: 700, fontSize: '2rem', mb: 2 }}>
|
||||||
|
👥 참여자 목록
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" color="text.secondary">
|
||||||
|
이벤트에 참여한 사용자들의 정보를 확인하고 관리하세요
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* Statistics Cards */}
|
||||||
|
<Grid container spacing={6} sx={{ mb: 10 }}>
|
||||||
|
<Grid item xs={6} md={3}>
|
||||||
|
<Card
|
||||||
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
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 }}>
|
||||||
|
<People sx={{ fontSize: 40, mb: 2, color: 'white' }} />
|
||||||
|
<Typography variant="caption" display="block" sx={{ mb: 2, color: 'rgba(255,255,255,0.9)' }}>
|
||||||
|
전체 참여자
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
|
{stats.total}명
|
||||||
|
</Typography>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6} md={3}>
|
||||||
|
<Card
|
||||||
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
borderRadius: 4,
|
||||||
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||||
|
background: `linear-gradient(135deg, ${colors.yellow} 0%, #FCD34D 100%)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent sx={{ textAlign: 'center', py: 6, px: 4 }}>
|
||||||
|
<AccessTime sx={{ fontSize: 40, mb: 2, color: 'white' }} />
|
||||||
|
<Typography variant="caption" display="block" sx={{ mb: 2, color: 'rgba(255,255,255,0.9)' }}>
|
||||||
|
대기중
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
|
{stats.waiting}명
|
||||||
|
</Typography>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6} md={3}>
|
||||||
|
<Card
|
||||||
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
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)' }}>
|
||||||
|
당첨자
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
|
{stats.winner}명
|
||||||
|
</Typography>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6} md={3}>
|
||||||
|
<Card
|
||||||
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
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 }}>
|
||||||
|
<Casino sx={{ fontSize: 40, mb: 2, color: 'white' }} />
|
||||||
|
<Typography variant="caption" display="block" sx={{ mb: 2, color: 'rgba(255,255,255,0.9)' }}>
|
||||||
|
당첨률
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h4" sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}>
|
||||||
|
{stats.total > 0 ? Math.round((stats.winner / stats.total) * 100) : 0}%
|
||||||
|
</Typography>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
{/* Search Section */}
|
{/* Search Section */}
|
||||||
<Box sx={{ mb: 3 }}>
|
<Box sx={{ mb: 6 }}>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="이름 또는 전화번호 검색..."
|
placeholder="이름 또는 전화번호 검색..."
|
||||||
@ -169,22 +298,24 @@ export default function ParticipantsPage() {
|
|||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
'& .MuiOutlinedInput-root': {
|
'& .MuiOutlinedInput-root': {
|
||||||
borderRadius: 2,
|
borderRadius: 3,
|
||||||
|
bgcolor: 'white',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Filters */}
|
{/* Filters */}
|
||||||
<Box sx={{ mb: 3 }}>
|
<Box sx={{ mb: 8 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, flexWrap: 'wrap' }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, flexWrap: 'wrap' }}>
|
||||||
<FilterList color="error" />
|
<FilterList sx={{ fontSize: 28, color: colors.pink }} />
|
||||||
<FormControl sx={{ flex: 1, minWidth: 140 }}>
|
<FormControl sx={{ flex: 1, minWidth: 160 }}>
|
||||||
<InputLabel>참여 경로</InputLabel>
|
<InputLabel>참여 경로</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
value={channelFilter}
|
value={channelFilter}
|
||||||
label="참여 경로"
|
label="참여 경로"
|
||||||
onChange={(e) => setChannelFilter(e.target.value as ChannelType)}
|
onChange={(e) => setChannelFilter(e.target.value as ChannelType)}
|
||||||
|
sx={{ borderRadius: 2 }}
|
||||||
>
|
>
|
||||||
<MenuItem value="all">전체 경로</MenuItem>
|
<MenuItem value="all">전체 경로</MenuItem>
|
||||||
<MenuItem value="uriTV">우리동네TV</MenuItem>
|
<MenuItem value="uriTV">우리동네TV</MenuItem>
|
||||||
@ -192,12 +323,13 @@ export default function ParticipantsPage() {
|
|||||||
<MenuItem value="sns">SNS</MenuItem>
|
<MenuItem value="sns">SNS</MenuItem>
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl sx={{ flex: 1, minWidth: 120 }}>
|
<FormControl sx={{ flex: 1, minWidth: 140 }}>
|
||||||
<InputLabel>상태</InputLabel>
|
<InputLabel>상태</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
value={statusFilter}
|
value={statusFilter}
|
||||||
label="상태"
|
label="상태"
|
||||||
onChange={(e) => setStatusFilter(e.target.value as StatusType)}
|
onChange={(e) => setStatusFilter(e.target.value as StatusType)}
|
||||||
|
sx={{ borderRadius: 2 }}
|
||||||
>
|
>
|
||||||
<MenuItem value="all">전체</MenuItem>
|
<MenuItem value="all">전체</MenuItem>
|
||||||
<MenuItem value="waiting">당첨 대기</MenuItem>
|
<MenuItem value="waiting">당첨 대기</MenuItem>
|
||||||
@ -209,77 +341,122 @@ export default function ParticipantsPage() {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Total Count & Drawing Button */}
|
{/* Total Count & Drawing Button */}
|
||||||
<Box sx={{ mb: 3 }}>
|
<Box sx={{ mb: 6 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 2 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 4 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>
|
<Typography variant="h5" sx={{ fontWeight: 700, fontSize: '1.5rem' }}>
|
||||||
총 <span style={{ color: '#e91e63' }}>{filteredParticipants.length}</span>명 참여
|
총 <span style={{ color: colors.pink }}>{filteredParticipants.length}</span>명 참여
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Box sx={{ display: 'flex', gap: 3 }}>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<Download />}
|
||||||
|
onClick={handleDownloadClick}
|
||||||
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
px: 4,
|
||||||
|
py: 1.5,
|
||||||
|
borderColor: colors.blue,
|
||||||
|
color: colors.blue,
|
||||||
|
'&:hover': {
|
||||||
|
borderColor: colors.blue,
|
||||||
|
bgcolor: `${colors.blue}10`,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
엑셀 다운로드
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
startIcon={<Casino />}
|
startIcon={<Casino />}
|
||||||
onClick={handleDrawClick}
|
onClick={handleDrawClick}
|
||||||
sx={{ borderRadius: 2 }}
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
px: 4,
|
||||||
|
py: 1.5,
|
||||||
|
background: `linear-gradient(135deg, ${colors.pink} 0%, ${colors.purple} 100%)`,
|
||||||
|
'&:hover': {
|
||||||
|
background: `linear-gradient(135deg, ${colors.pink} 0%, ${colors.purple} 100%)`,
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
당첨자 추첨
|
당첨자 추첨
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
{/* Participant List */}
|
{/* Participant List */}
|
||||||
<Box sx={{ mb: 5 }}>
|
<Box sx={{ mb: 10 }}>
|
||||||
{pageParticipants.length === 0 ? (
|
{pageParticipants.length === 0 ? (
|
||||||
<Box sx={{ textAlign: 'center', py: 8 }}>
|
<Box sx={{ textAlign: 'center', py: 16 }}>
|
||||||
<span className="material-icons" style={{ fontSize: 64, color: '#bdbdbd' }}>
|
<Person sx={{ fontSize: 80, color: colors.gray[300], mb: 3 }} />
|
||||||
people_outline
|
<Typography variant="h6" color="text.secondary" sx={{ fontWeight: 600 }}>
|
||||||
</span>
|
|
||||||
<Typography variant="body1" color="text.secondary" sx={{ mt: 2 }}>
|
|
||||||
검색 결과가 없습니다
|
검색 결과가 없습니다
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary" sx={{ mt: 2 }}>
|
||||||
|
다른 검색어나 필터를 사용해보세요
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||||
{pageParticipants.map((participant) => (
|
{pageParticipants.map((participant) => (
|
||||||
<Card
|
<Card
|
||||||
key={participant.id}
|
key={participant.id}
|
||||||
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 ease',
|
transition: 'all 0.2s ease',
|
||||||
'&: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={() => handleParticipantClick(participant)}
|
onClick={() => handleParticipantClick(participant)}
|
||||||
>
|
>
|
||||||
<CardContent sx={{ p: 3 }}>
|
<CardContent sx={{ p: 5 }}>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'flex-start',
|
alignItems: 'flex-start',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
mb: 2,
|
mb: 4,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ flex: 1 }}>
|
<Box sx={{ flex: 1, display: 'flex', alignItems: 'center', gap: 3 }}>
|
||||||
<Typography variant="caption" color="text.secondary" sx={{ mb: 0.5 }}>
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: 56,
|
||||||
|
height: 56,
|
||||||
|
borderRadius: '50%',
|
||||||
|
bgcolor: colors.purpleLight,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Person sx={{ fontSize: 32, color: colors.purple }} />
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Typography variant="caption" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
|
||||||
#{participant.id}
|
#{participant.id}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 0.5 }}>
|
<Typography variant="h6" sx={{ fontWeight: 700, mb: 1, fontSize: '1.25rem' }}>
|
||||||
{participant.name}
|
{participant.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body1" color="text.secondary">
|
||||||
{participant.phone}
|
{participant.phone}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box>
|
||||||
<Chip
|
<Chip
|
||||||
label={getStatusText(participant.status)}
|
label={getStatusText(participant.status)}
|
||||||
color={getStatusColor(participant.status) as any}
|
color={getStatusColor(participant.status) as any}
|
||||||
size="small"
|
size="medium"
|
||||||
sx={{ fontWeight: 600 }}
|
sx={{ fontWeight: 600, px: 2, py: 2.5 }}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@ -287,26 +464,34 @@ export default function ParticipantsPage() {
|
|||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
borderTop: '1px solid',
|
borderTop: '1px solid',
|
||||||
borderColor: 'divider',
|
borderColor: colors.gray[100],
|
||||||
pt: 2,
|
pt: 4,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
gap: 0.5,
|
gap: 2,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body1" color="text.secondary">
|
||||||
참여 경로
|
참여 경로
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
<Chip
|
||||||
{participant.channel}
|
label={participant.channel}
|
||||||
</Typography>
|
size="small"
|
||||||
|
sx={{
|
||||||
|
bgcolor: colors.purpleLight,
|
||||||
|
color: colors.purple,
|
||||||
|
fontWeight: 600,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
|
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body1" color="text.secondary">
|
||||||
참여 일시
|
참여 일시
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2">{participant.date}</Typography>
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
{participant.date}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@ -318,87 +503,145 @@ export default function ParticipantsPage() {
|
|||||||
|
|
||||||
{/* Pagination */}
|
{/* Pagination */}
|
||||||
{totalPages > 1 && (
|
{totalPages > 1 && (
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 5 }}>
|
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 10 }}>
|
||||||
<Pagination
|
<Pagination
|
||||||
count={totalPages}
|
count={totalPages}
|
||||||
page={currentPage}
|
page={currentPage}
|
||||||
onChange={(_, page) => setCurrentPage(page)}
|
onChange={(_, page) => setCurrentPage(page)}
|
||||||
color="primary"
|
color="primary"
|
||||||
size="large"
|
size="large"
|
||||||
|
sx={{
|
||||||
|
'& .MuiPaginationItem-root': {
|
||||||
|
fontSize: '1rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
},
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Excel Download Button (Desktop only) */}
|
|
||||||
<Box sx={{ display: { xs: 'none', md: 'block' } }}>
|
|
||||||
<Button
|
|
||||||
fullWidth
|
|
||||||
variant="outlined"
|
|
||||||
size="large"
|
|
||||||
startIcon={<Download />}
|
|
||||||
onClick={handleDownloadClick}
|
|
||||||
sx={{ borderRadius: 2 }}
|
|
||||||
>
|
|
||||||
엑셀 다운로드
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* Participant Detail Dialog */}
|
{/* Participant Detail Dialog */}
|
||||||
<Dialog
|
<Dialog
|
||||||
open={detailDialogOpen}
|
open={detailDialogOpen}
|
||||||
onClose={() => setDetailDialogOpen(false)}
|
onClose={() => setDetailDialogOpen(false)}
|
||||||
maxWidth="sm"
|
maxWidth="sm"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
PaperProps={{
|
||||||
|
sx: {
|
||||||
|
borderRadius: 4,
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<DialogTitle>참여자 상세 정보</DialogTitle>
|
<DialogTitle sx={{ p: 5, pb: 3 }}>
|
||||||
<DialogContent dividers>
|
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
||||||
{selectedParticipant && (
|
참여자 상세 정보
|
||||||
<Box sx={{ p: 2 }}>
|
|
||||||
<Box sx={{ mb: 3 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
|
||||||
응모번호
|
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>
|
</DialogTitle>
|
||||||
|
<DialogContent dividers sx={{ p: 5 }}>
|
||||||
|
{selectedParticipant && (
|
||||||
|
<Box>
|
||||||
|
<Box sx={{ mb: 4, textAlign: 'center' }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
borderRadius: '50%',
|
||||||
|
bgcolor: colors.purpleLight,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
margin: '0 auto',
|
||||||
|
mb: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Person sx={{ fontSize: 40, color: colors.purple }} />
|
||||||
|
</Box>
|
||||||
|
<Typography variant="h6" sx={{ fontWeight: 700, mb: 1 }}>
|
||||||
|
{selectedParticipant.name}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
#{selectedParticipant.id}
|
#{selectedParticipant.id}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ mb: 3 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
||||||
이름
|
<Box
|
||||||
</Typography>
|
sx={{
|
||||||
<Typography variant="body1">{selectedParticipant.name}</Typography>
|
p: 3,
|
||||||
</Box>
|
bgcolor: colors.gray[100],
|
||||||
<Box sx={{ mb: 3 }}>
|
borderRadius: 3,
|
||||||
<Typography variant="caption" color="text.secondary">
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="caption" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
|
||||||
전화번호
|
전화번호
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1">{selectedParticipant.phone}</Typography>
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
{selectedParticipant.phone}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ mb: 3 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 3,
|
||||||
|
bgcolor: colors.gray[100],
|
||||||
|
borderRadius: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="caption" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
|
||||||
참여 경로
|
참여 경로
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1">{selectedParticipant.channel}</Typography>
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
{selectedParticipant.channel}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ mb: 3 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 3,
|
||||||
|
bgcolor: colors.gray[100],
|
||||||
|
borderRadius: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="caption" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
|
||||||
참여 일시
|
참여 일시
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1">{selectedParticipant.date}</Typography>
|
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||||
|
{selectedParticipant.date}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 3,
|
||||||
|
bgcolor: colors.gray[100],
|
||||||
|
borderRadius: 3,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="caption" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
|
||||||
당첨 여부
|
당첨 여부
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1">
|
<Chip
|
||||||
{getStatusText(selectedParticipant.status)}
|
label={getStatusText(selectedParticipant.status)}
|
||||||
</Typography>
|
color={getStatusColor(selectedParticipant.status) as any}
|
||||||
|
size="medium"
|
||||||
|
sx={{ fontWeight: 600 }}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions sx={{ p: 5, pt: 3 }}>
|
||||||
<Button onClick={() => setDetailDialogOpen(false)} variant="contained">
|
<Button
|
||||||
|
onClick={() => setDetailDialogOpen(false)}
|
||||||
|
variant="contained"
|
||||||
|
fullWidth
|
||||||
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
py: 1.5,
|
||||||
|
background: `linear-gradient(135deg, ${colors.pink} 0%, ${colors.purple} 100%)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
확인
|
확인
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user