2025-10-24 15:08:50 +09:00

348 lines
12 KiB
TypeScript

import { useState } from 'react';
import {
Box,
Container,
Typography,
Card,
CardContent,
Button,
Checkbox,
FormControlLabel,
Chip,
Grid,
IconButton,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Link,
} from '@mui/material';
import { ArrowBack, CheckCircle, Edit, RocketLaunch, Save } from '@mui/icons-material';
import { EventData } from '../page';
interface ApprovalStepProps {
eventData: EventData;
onApprove: () => void;
onBack: () => void;
}
export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalStepProps) {
const [agreeTerms, setAgreeTerms] = useState(false);
const [termsDialogOpen, setTermsDialogOpen] = useState(false);
const [successDialogOpen, setSuccessDialogOpen] = useState(false);
const [isDeploying, setIsDeploying] = useState(false);
const handleApprove = () => {
if (!agreeTerms) return;
setIsDeploying(true);
// 배포 시뮬레이션
setTimeout(() => {
setIsDeploying(false);
setSuccessDialogOpen(true);
}, 2000);
};
const handleSaveDraft = () => {
// TODO: 임시저장 API 연동
alert('임시저장되었습니다');
};
const getChannelNames = (channels?: string[]) => {
const channelMap: Record<string, string> = {
uriTV: '우리동네TV',
ringoBiz: '링고비즈',
genieTV: '지니TV',
sns: 'SNS',
};
return channels?.map((ch) => channelMap[ch] || ch) || [];
};
return (
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 10 }}>
<Container maxWidth="md" sx={{ pt: 4, pb: 4, px: { xs: 3, sm: 3, md: 4 } }}>
{/* Header */}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 4 }}>
<IconButton onClick={onBack}>
<ArrowBack />
</IconButton>
<Typography variant="h5" sx={{ fontWeight: 700 }}>
</Typography>
</Box>
{/* Title Section */}
<Box sx={{ textAlign: 'center', mb: 5 }}>
<CheckCircle sx={{ fontSize: 64, color: 'success.main', mb: 2 }} />
<Typography variant="h5" sx={{ fontWeight: 700, mb: 1 }}>
</Typography>
<Typography variant="body1" color="text.secondary">
</Typography>
</Box>
{/* Event Summary Card */}
<Card elevation={0} sx={{ mb: 4, borderRadius: 3 }}>
<CardContent sx={{ p: 4 }}>
<Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
{eventData.recommendation?.title || '이벤트 제목'}
</Typography>
<Box sx={{ display: 'flex', gap: 1, mb: 3 }}>
<Chip label="배포 대기" color="warning" size="small" />
<Chip label="AI 추천" color="info" size="small" />
</Box>
<Grid container spacing={2} sx={{ pt: 2, borderTop: 1, borderColor: 'divider' }}>
<Grid item xs={6}>
<Typography variant="caption" color="text.secondary">
</Typography>
<Typography variant="body2" sx={{ fontWeight: 600 }}>
2025.02.01 ~ 2025.02.28
</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="caption" color="text.secondary">
</Typography>
<Typography variant="body2" sx={{ fontWeight: 600 }}>
{eventData.recommendation?.expectedParticipants || 0}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="caption" color="text.secondary">
</Typography>
<Typography variant="body2" sx={{ fontWeight: 600 }}>
{eventData.recommendation?.estimatedCost.toLocaleString() || 0}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="caption" color="text.secondary">
ROI
</Typography>
<Typography variant="body2" sx={{ fontWeight: 600, color: 'error.main' }}>
{eventData.recommendation?.roi || 0}%
</Typography>
</Grid>
</Grid>
</CardContent>
</Card>
{/* Event Details */}
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}>
</Typography>
<Card elevation={0} sx={{ mb: 2, borderRadius: 3 }}>
<CardContent sx={{ p: 3 }}>
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
<Box sx={{ flex: 1 }}>
<Typography variant="caption" color="text.secondary">
</Typography>
<Typography variant="body1" sx={{ fontWeight: 600 }}>
{eventData.recommendation?.title}
</Typography>
</Box>
<IconButton size="small">
<Edit fontSize="small" />
</IconButton>
</Box>
</CardContent>
</Card>
<Card elevation={0} sx={{ mb: 2, borderRadius: 3 }}>
<CardContent sx={{ p: 3 }}>
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
<Box sx={{ flex: 1 }}>
<Typography variant="caption" color="text.secondary">
</Typography>
<Typography variant="body1" sx={{ fontWeight: 600 }}>
{eventData.recommendation?.prize}
</Typography>
</Box>
<IconButton size="small">
<Edit fontSize="small" />
</IconButton>
</Box>
</CardContent>
</Card>
<Card elevation={0} sx={{ mb: 2, borderRadius: 3 }}>
<CardContent sx={{ p: 3 }}>
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
<Box sx={{ flex: 1 }}>
<Typography variant="caption" color="text.secondary">
</Typography>
<Typography variant="body1" sx={{ fontWeight: 600 }}>
{eventData.recommendation?.participationMethod}
</Typography>
</Box>
</Box>
</CardContent>
</Card>
{/* Distribution Channels */}
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3, mt: 4 }}>
</Typography>
<Card elevation={0} sx={{ mb: 4, borderRadius: 3 }}>
<CardContent sx={{ p: 3 }}>
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mb: 2 }}>
{getChannelNames(eventData.channels).map((channel) => (
<Chip key={channel} label={channel} color="primary" variant="outlined" />
))}
</Box>
<Button
size="small"
startIcon={<Edit />}
sx={{ color: 'primary.main' }}
>
</Button>
</CardContent>
</Card>
{/* Terms Agreement */}
<Card elevation={0} sx={{ mb: 5, borderRadius: 3, bgcolor: 'grey.50' }}>
<CardContent sx={{ p: 3 }}>
<FormControlLabel
control={
<Checkbox
checked={agreeTerms}
onChange={(e) => setAgreeTerms(e.target.checked)}
/>
}
label={
<Typography variant="body2">
{' '}
<span style={{ color: 'red' }}>()</span>
</Typography>
}
/>
<Link
component="button"
variant="body2"
onClick={() => setTermsDialogOpen(true)}
sx={{ color: 'error.main', ml: 4, mt: 1 }}
>
</Link>
</CardContent>
</Card>
{/* Action Buttons */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<Button
fullWidth
variant="contained"
size="large"
disabled={!agreeTerms || isDeploying}
onClick={handleApprove}
startIcon={isDeploying ? null : <RocketLaunch />}
sx={{ py: 1.5 }}
>
{isDeploying ? '배포 중...' : '배포하기'}
</Button>
<Button
fullWidth
variant="outlined"
size="large"
onClick={handleSaveDraft}
startIcon={<Save />}
sx={{ py: 1.5 }}
>
</Button>
</Box>
</Container>
{/* Terms Dialog */}
<Dialog
open={termsDialogOpen}
onClose={() => setTermsDialogOpen(false)}
maxWidth="sm"
fullWidth
>
<DialogTitle> </DialogTitle>
<DialogContent>
<Typography variant="h6" sx={{ mb: 2 }}>
1 ()
</Typography>
<Typography variant="body2" sx={{ mb: 3 }}>
KT AI
.
</Typography>
<Typography variant="h6" sx={{ mb: 2 }}>
2 ( )
</Typography>
<Typography variant="body2" sx={{ mb: 1 }}>
항목: 이름, ,
</Typography>
<Typography variant="body2" sx={{ mb: 1 }}>
목적: 이벤트
</Typography>
<Typography variant="body2" sx={{ mb: 3 }}>
기간: 이벤트 6
</Typography>
<Typography variant="h6" sx={{ mb: 2 }}>
3 ( )
</Typography>
<Typography variant="body2">
7 .
</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setTermsDialogOpen(false)} variant="contained">
</Button>
</DialogActions>
</Dialog>
{/* Success Dialog */}
<Dialog
open={successDialogOpen}
onClose={() => {
setSuccessDialogOpen(false);
onApprove();
}}
>
<DialogContent sx={{ textAlign: 'center', py: 6, px: 4 }}>
<CheckCircle sx={{ fontSize: 80, color: 'success.main', mb: 2 }} />
<Typography variant="h5" sx={{ fontWeight: 700, mb: 1 }}>
!
</Typography>
<Typography variant="body1" color="text.secondary" sx={{ mb: 4 }}>
.
<br />
.
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<Button
fullWidth
variant="contained"
size="large"
onClick={() => {
setSuccessDialogOpen(false);
onApprove();
}}
>
</Button>
</Box>
</DialogContent>
</Dialog>
</Box>
);
}