mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 11:36:24 +00:00
ApprovalStep 디자인을 events/dashboard 기준으로 통일
- 페이지 배경을 gray[50]으로 변경하여 일관성 확보
- 이벤트 요약을 4개의 gradient 통계 카드로 재구성 (Purple, Blue, Orange, Mint)
- cardStyles.default와 responsiveText 시스템 적용
- 모든 카드에 일관된 패딩과 간격 적용 (p: {xs: 6, sm: 8})
- 버튼 텍스트 크기를 1rem으로 통일
- 다이얼로그 스타일링 개선 및 borderRadius 추가
- 채널 Chips를 purple 배경으로 변경
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8e2376dc57
commit
56d3071b19
@ -17,26 +17,9 @@ import {
|
||||
DialogActions,
|
||||
Link,
|
||||
} from '@mui/material';
|
||||
import { ArrowBack, CheckCircle, Edit, RocketLaunch, Save } from '@mui/icons-material';
|
||||
import { ArrowBack, CheckCircle, Edit, RocketLaunch, Save, People, AttachMoney, TrendingUp } from '@mui/icons-material';
|
||||
import { EventData } from '../page';
|
||||
|
||||
// 디자인 시스템 색상
|
||||
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',
|
||||
},
|
||||
};
|
||||
import { cardStyles, colors, responsiveText } from '@/shared/lib/button-styles';
|
||||
|
||||
interface ApprovalStepProps {
|
||||
eventData: EventData;
|
||||
@ -79,91 +62,144 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 20 }}>
|
||||
<Container maxWidth="md" sx={{ pt: 8, pb: 8, px: { xs: 6, sm: 6, md: 8 } }}>
|
||||
<Box sx={{ minHeight: '100vh', bgcolor: colors.gray[50], pt: { xs: 7, sm: 8 }, pb: 10 }}>
|
||||
<Container maxWidth="lg" sx={{ pt: 8, pb: 6, px: { xs: 6, sm: 8, md: 10 } }}>
|
||||
{/* Header */}
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, mb: 8 }}>
|
||||
<IconButton onClick={onBack}>
|
||||
<ArrowBack />
|
||||
</IconButton>
|
||||
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
||||
<Typography variant="h5" sx={{ ...responsiveText.h3, 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 }}>
|
||||
<Box sx={{ textAlign: 'center', mb: 10 }}>
|
||||
<CheckCircle sx={{ fontSize: 64, color: colors.purple, mb: 2 }} />
|
||||
<Typography variant="h5" sx={{ ...responsiveText.h3, fontWeight: 700, mb: 2 }}>
|
||||
이벤트를 확인해주세요
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary">
|
||||
<Typography variant="body1" color="text.secondary" sx={{ ...responsiveText.body1 }}>
|
||||
모든 정보를 검토한 후 배포하세요
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{/* Event Summary Card */}
|
||||
<Card elevation={0} sx={{ mb: 4, borderRadius: 4 }}>
|
||||
<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">
|
||||
이벤트 기간
|
||||
{/* Event Summary Statistics */}
|
||||
<Grid container spacing={4} sx={{ mb: 10 }}>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<Card
|
||||
elevation={0}
|
||||
sx={{
|
||||
...cardStyles.default,
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.purpleLight} 100%)`,
|
||||
borderColor: 'transparent',
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
|
||||
<CheckCircle sx={{ fontSize: 32, color: 'white', mb: 1 }} />
|
||||
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem', mb: 1 }}>
|
||||
이벤트 제목
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||
2025.02.01 ~ 2025.02.28
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ fontWeight: 700, color: 'white', fontSize: '1rem' }}
|
||||
>
|
||||
{eventData.recommendation?.title || '이벤트 제목'}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<Card
|
||||
elevation={0}
|
||||
sx={{
|
||||
...cardStyles.default,
|
||||
background: `linear-gradient(135deg, ${colors.blue} 0%, ${colors.blueLight} 100%)`,
|
||||
borderColor: 'transparent',
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
|
||||
<People sx={{ fontSize: 32, color: 'white', mb: 1 }} />
|
||||
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem', mb: 1 }}>
|
||||
목표 참여자
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||
{eventData.recommendation?.expectedParticipants || 0}명
|
||||
<Typography
|
||||
variant="h4"
|
||||
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}
|
||||
>
|
||||
{eventData.recommendation?.expectedParticipants || 0}
|
||||
<Typography component="span" sx={{ fontSize: '1rem', ml: 0.5 }}>
|
||||
명
|
||||
</Typography>
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<Card
|
||||
elevation={0}
|
||||
sx={{
|
||||
...cardStyles.default,
|
||||
background: `linear-gradient(135deg, ${colors.orange} 0%, ${colors.orangeLight} 100%)`,
|
||||
borderColor: 'transparent',
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
|
||||
<AttachMoney sx={{ fontSize: 32, color: 'white', mb: 1 }} />
|
||||
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem', mb: 1 }}>
|
||||
예상 비용
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||
{eventData.recommendation?.estimatedCost.toLocaleString() || 0}원
|
||||
<Typography
|
||||
variant="h4"
|
||||
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}
|
||||
>
|
||||
{((eventData.recommendation?.estimatedCost || 0) / 10000).toFixed(0)}
|
||||
<Typography component="span" sx={{ fontSize: '1rem', ml: 0.5 }}>
|
||||
만원
|
||||
</Typography>
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<Card
|
||||
elevation={0}
|
||||
sx={{
|
||||
...cardStyles.default,
|
||||
background: `linear-gradient(135deg, ${colors.mint} 0%, ${colors.mintLight} 100%)`,
|
||||
borderColor: 'transparent',
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
|
||||
<TrendingUp sx={{ fontSize: 32, color: 'white', mb: 1 }} />
|
||||
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem', mb: 1 }}>
|
||||
예상 ROI
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: 'error.main' }}>
|
||||
<Typography
|
||||
variant="h4"
|
||||
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}
|
||||
>
|
||||
{eventData.recommendation?.roi || 0}%
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Event Details */}
|
||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}>
|
||||
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 6 }}>
|
||||
이벤트 상세
|
||||
</Typography>
|
||||
|
||||
<Card elevation={0} sx={{ mb: 2, borderRadius: 4 }}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Card elevation={0} sx={{ ...cardStyles.default, mb: 4 }}>
|
||||
<CardContent sx={{ p: { xs: 6, sm: 8 } }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
<Typography variant="caption" color="text.secondary" sx={{ ...responsiveText.body2, fontSize: '0.875rem' }}>
|
||||
이벤트 제목
|
||||
</Typography>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||
<Typography variant="body1" sx={{ ...responsiveText.body1, fontWeight: 600, mt: 1 }}>
|
||||
{eventData.recommendation?.title}
|
||||
</Typography>
|
||||
</Box>
|
||||
@ -174,14 +210,14 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card elevation={0} sx={{ mb: 2, borderRadius: 4 }}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Card elevation={0} sx={{ ...cardStyles.default, mb: 4 }}>
|
||||
<CardContent sx={{ p: { xs: 6, sm: 8 } }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
<Typography variant="caption" color="text.secondary" sx={{ ...responsiveText.body2, fontSize: '0.875rem' }}>
|
||||
경품
|
||||
</Typography>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||
<Typography variant="body1" sx={{ ...responsiveText.body1, fontWeight: 600, mt: 1 }}>
|
||||
{eventData.recommendation?.prize}
|
||||
</Typography>
|
||||
</Box>
|
||||
@ -192,14 +228,14 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card elevation={0} sx={{ mb: 2, borderRadius: 4 }}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Card elevation={0} sx={{ ...cardStyles.default, mb: 10 }}>
|
||||
<CardContent sx={{ p: { xs: 6, sm: 8 } }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
<Typography variant="caption" color="text.secondary" sx={{ ...responsiveText.body2, fontSize: '0.875rem' }}>
|
||||
참여 방법
|
||||
</Typography>
|
||||
<Typography variant="body1" sx={{ fontWeight: 600 }}>
|
||||
<Typography variant="body1" sx={{ ...responsiveText.body1, fontWeight: 600, mt: 1 }}>
|
||||
{eventData.recommendation?.participationMethod}
|
||||
</Typography>
|
||||
</Box>
|
||||
@ -208,21 +244,36 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
</Card>
|
||||
|
||||
{/* Distribution Channels */}
|
||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3, mt: 4 }}>
|
||||
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 6 }}>
|
||||
배포 채널
|
||||
</Typography>
|
||||
|
||||
<Card elevation={0} sx={{ mb: 4, borderRadius: 4 }}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mb: 2 }}>
|
||||
<Card elevation={0} sx={{ ...cardStyles.default, mb: 10 }}>
|
||||
<CardContent sx={{ p: { xs: 6, sm: 8 } }}>
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 4 }}>
|
||||
{getChannelNames(eventData.channels).map((channel) => (
|
||||
<Chip key={channel} label={channel} color="primary" variant="outlined" />
|
||||
<Chip
|
||||
key={channel}
|
||||
label={channel}
|
||||
sx={{
|
||||
bgcolor: colors.purple,
|
||||
color: 'white',
|
||||
fontWeight: 600,
|
||||
fontSize: '0.875rem',
|
||||
px: 2,
|
||||
py: 2.5,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
<Button
|
||||
size="small"
|
||||
startIcon={<Edit />}
|
||||
sx={{ color: 'primary.main' }}
|
||||
sx={{
|
||||
...responsiveText.body2,
|
||||
fontWeight: 600,
|
||||
color: colors.purple,
|
||||
}}
|
||||
>
|
||||
채널 수정하기
|
||||
</Button>
|
||||
@ -230,19 +281,27 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
</Card>
|
||||
|
||||
{/* Terms Agreement */}
|
||||
<Card elevation={0} sx={{ mb: 5, borderRadius: 4, bgcolor: 'grey.50' }}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Card elevation={0} sx={{ ...cardStyles.default, bgcolor: colors.gray[50], mb: 10 }}>
|
||||
<CardContent sx={{ p: { xs: 6, sm: 8 } }}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={agreeTerms}
|
||||
onChange={(e) => setAgreeTerms(e.target.checked)}
|
||||
sx={{
|
||||
color: colors.purple,
|
||||
'&.Mui-checked': {
|
||||
color: colors.purple,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography variant="body2">
|
||||
<Typography variant="body2" sx={{ ...responsiveText.body1 }}>
|
||||
이벤트 약관 및 개인정보 처리방침에 동의합니다{' '}
|
||||
<span style={{ color: 'red' }}>(필수)</span>
|
||||
<Typography component="span" sx={{ color: colors.orange, fontWeight: 600 }}>
|
||||
(필수)
|
||||
</Typography>
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
@ -250,7 +309,7 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
component="button"
|
||||
variant="body2"
|
||||
onClick={() => setTermsDialogOpen(true)}
|
||||
sx={{ color: 'error.main', ml: 4, mt: 1 }}
|
||||
sx={{ ...responsiveText.body2, ml: 4, mt: 2, fontWeight: 600, color: colors.purple }}
|
||||
>
|
||||
약관 보기
|
||||
</Link>
|
||||
@ -258,7 +317,7 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
</Card>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
@ -266,7 +325,20 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
disabled={!agreeTerms || isDeploying}
|
||||
onClick={handleApprove}
|
||||
startIcon={isDeploying ? null : <RocketLaunch />}
|
||||
sx={{ py: 1.5 }}
|
||||
sx={{
|
||||
py: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||
'&:hover': {
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||
opacity: 0.9,
|
||||
},
|
||||
'&:disabled': {
|
||||
background: colors.gray[300],
|
||||
},
|
||||
}}
|
||||
>
|
||||
{isDeploying ? '배포 중...' : '배포하기'}
|
||||
</Button>
|
||||
@ -276,7 +348,20 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
size="large"
|
||||
onClick={handleSaveDraft}
|
||||
startIcon={<Save />}
|
||||
sx={{ py: 1.5 }}
|
||||
sx={{
|
||||
py: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 600,
|
||||
borderWidth: 2,
|
||||
borderColor: colors.gray[300],
|
||||
color: colors.gray[700],
|
||||
'&:hover': {
|
||||
borderWidth: 2,
|
||||
borderColor: colors.gray[400],
|
||||
bgcolor: colors.gray[50],
|
||||
},
|
||||
}}
|
||||
>
|
||||
임시저장
|
||||
</Button>
|
||||
@ -289,39 +374,61 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
onClose={() => setTermsDialogOpen(false)}
|
||||
maxWidth="sm"
|
||||
fullWidth
|
||||
PaperProps={{
|
||||
sx: {
|
||||
borderRadius: 4,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle>이벤트 약관</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography variant="h6" sx={{ mb: 2 }}>
|
||||
<DialogTitle sx={{ ...responsiveText.h3, fontWeight: 700, p: 6, pb: 4 }}>
|
||||
이벤트 약관
|
||||
</DialogTitle>
|
||||
<DialogContent sx={{ px: 6, pb: 6 }}>
|
||||
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 3 }}>
|
||||
제1조 (목적)
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ mb: 3 }}>
|
||||
<Typography variant="body2" sx={{ ...responsiveText.body1, mb: 6, color: colors.gray[700] }}>
|
||||
본 약관은 KT AI 이벤트 마케팅 서비스를 통해 진행되는 이벤트의 참여 및 개인정보 처리에 관한
|
||||
사항을 규정합니다.
|
||||
</Typography>
|
||||
|
||||
<Typography variant="h6" sx={{ mb: 2 }}>
|
||||
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 3 }}>
|
||||
제2조 (개인정보 수집 및 이용)
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ mb: 1 }}>
|
||||
<Typography variant="body2" sx={{ ...responsiveText.body1, mb: 2, color: colors.gray[700] }}>
|
||||
수집 항목: 이름, 전화번호, 이메일
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ mb: 1 }}>
|
||||
<Typography variant="body2" sx={{ ...responsiveText.body1, mb: 2, color: colors.gray[700] }}>
|
||||
이용 목적: 이벤트 참여 확인 및 경품 제공
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ mb: 3 }}>
|
||||
<Typography variant="body2" sx={{ ...responsiveText.body1, mb: 6, color: colors.gray[700] }}>
|
||||
보유 기간: 이벤트 종료 후 6개월
|
||||
</Typography>
|
||||
|
||||
<Typography variant="h6" sx={{ mb: 2 }}>
|
||||
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 3 }}>
|
||||
제3조 (당첨자 발표)
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
<Typography variant="body2" sx={{ ...responsiveText.body1, color: colors.gray[700] }}>
|
||||
당첨자는 이벤트 종료 후 7일 이내 개별 연락 드립니다.
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={() => setTermsDialogOpen(false)} variant="contained">
|
||||
<DialogActions sx={{ p: 6, pt: 4 }}>
|
||||
<Button
|
||||
fullWidth
|
||||
onClick={() => setTermsDialogOpen(false)}
|
||||
variant="contained"
|
||||
sx={{
|
||||
py: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
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>
|
||||
</DialogActions>
|
||||
@ -334,30 +441,44 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
|
||||
setSuccessDialogOpen(false);
|
||||
onApprove();
|
||||
}}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
borderRadius: 4,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<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 }}>
|
||||
<DialogContent sx={{ textAlign: 'center', py: 10, px: 8 }}>
|
||||
<CheckCircle sx={{ fontSize: 80, color: colors.purple, mb: 4 }} />
|
||||
<Typography variant="h5" sx={{ fontSize: '1.5rem', fontWeight: 700, mb: 3 }}>
|
||||
배포 완료!
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary" sx={{ mb: 4 }}>
|
||||
<Typography variant="body1" color="text.secondary" sx={{ fontSize: '1rem', mb: 8 }}>
|
||||
이벤트가 성공적으로 배포되었습니다.
|
||||
<br />
|
||||
실시간으로 참여자를 확인할 수 있습니다.
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
size="large"
|
||||
onClick={() => {
|
||||
setSuccessDialogOpen(false);
|
||||
onApprove();
|
||||
}}
|
||||
>
|
||||
대시보드로 이동
|
||||
</Button>
|
||||
</Box>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
size="large"
|
||||
onClick={() => {
|
||||
setSuccessDialogOpen(false);
|
||||
onApprove();
|
||||
}}
|
||||
sx={{
|
||||
py: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
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>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</Box>
|
||||
|
||||
@ -522,6 +522,14 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||
'&:hover': {
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||
opacity: 0.9,
|
||||
},
|
||||
'&:disabled': {
|
||||
background: colors.gray[300],
|
||||
},
|
||||
}}
|
||||
>
|
||||
다음
|
||||
|
||||
@ -163,11 +163,42 @@ export default function ContentEditStep({
|
||||
</Grid>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<Box sx={{ display: 'flex', gap: 2, mt: 5 }}>
|
||||
<Button fullWidth variant="outlined" size="large" onClick={handleSave} sx={{ py: 1.5 }}>
|
||||
<Box sx={{ display: 'flex', gap: 4, mt: 5 }}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
size="large"
|
||||
onClick={handleSave}
|
||||
sx={{
|
||||
py: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 600,
|
||||
borderWidth: 2,
|
||||
'&:hover': {
|
||||
borderWidth: 2,
|
||||
},
|
||||
}}
|
||||
>
|
||||
저장
|
||||
</Button>
|
||||
<Button fullWidth variant="contained" size="large" onClick={handleNext} sx={{ py: 1.5 }}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
size="large"
|
||||
onClick={handleNext}
|
||||
sx={{
|
||||
py: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
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>
|
||||
</Box>
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
FormControlLabel,
|
||||
IconButton,
|
||||
Dialog,
|
||||
Grid,
|
||||
} from '@mui/material';
|
||||
import { ArrowBack, ZoomIn, Psychology } from '@mui/icons-material';
|
||||
|
||||
@ -110,22 +111,22 @@ export default function ContentPreviewStep({
|
||||
if (loading) {
|
||||
return (
|
||||
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 20 }}>
|
||||
<Container maxWidth="md" sx={{ pt: 8, pb: 8, px: { xs: 6, sm: 6, md: 8 } }}>
|
||||
<Container maxWidth="lg" sx={{ pt: 8, pb: 8, px: { xs: 6, sm: 6, md: 8 } }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, mb: 8 }}>
|
||||
<IconButton onClick={onBack}>
|
||||
<ArrowBack />
|
||||
</IconButton>
|
||||
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
||||
<Typography variant="h5" sx={{ fontWeight: 700, fontSize: '1.5rem' }}>
|
||||
SNS 이미지 생성
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ textAlign: 'center', mt: 10, mb: 10 }}>
|
||||
<Box sx={{ textAlign: 'center', mt: 15, mb: 15 }}>
|
||||
<Psychology
|
||||
sx={{
|
||||
fontSize: 64,
|
||||
color: 'info.main',
|
||||
mb: 2,
|
||||
fontSize: 80,
|
||||
color: colors.purple,
|
||||
mb: 4,
|
||||
animation: 'spin 2s linear infinite',
|
||||
'@keyframes spin': {
|
||||
'0%': { transform: 'rotate(0deg)' },
|
||||
@ -133,15 +134,15 @@ export default function ContentPreviewStep({
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 1 }}>
|
||||
<Typography variant="h5" sx={{ fontWeight: 700, mb: 3, fontSize: '1.5rem' }}>
|
||||
AI 이미지 생성 중
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary" sx={{ mb: 2 }}>
|
||||
<Typography variant="body1" color="text.secondary" sx={{ mb: 3, fontSize: '1.125rem' }}>
|
||||
딥러닝 모델이 이벤트에 어울리는
|
||||
<br />
|
||||
이미지를 생성하고 있어요...
|
||||
</Typography>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
<Typography variant="body2" color="text.secondary" sx={{ fontSize: '1rem' }}>
|
||||
예상 시간: 5초
|
||||
</Typography>
|
||||
</Box>
|
||||
@ -152,133 +153,147 @@ export default function ContentPreviewStep({
|
||||
|
||||
return (
|
||||
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 20 }}>
|
||||
<Container maxWidth="md" sx={{ pt: 8, pb: 8, px: { xs: 6, sm: 6, md: 8 } }}>
|
||||
<Container maxWidth="lg" sx={{ pt: 8, pb: 8, px: { xs: 6, sm: 6, md: 8 } }}>
|
||||
{/* Header */}
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, mb: 8 }}>
|
||||
<IconButton onClick={onBack}>
|
||||
<ArrowBack />
|
||||
</IconButton>
|
||||
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
||||
<Typography variant="h5" sx={{ fontWeight: 700, fontSize: '1.5rem' }}>
|
||||
SNS 이미지 생성
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 8, textAlign: 'center', fontSize: '1rem' }}>
|
||||
이벤트에 어울리는 스타일을 선택하세요
|
||||
</Typography>
|
||||
|
||||
<RadioGroup value={selectedStyle} onChange={(e) => handleStyleSelect(e.target.value)}>
|
||||
{imageStyles.map((style) => (
|
||||
<Box key={style.id} sx={{ mb: 4 }}>
|
||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
|
||||
{style.name}
|
||||
</Typography>
|
||||
<Grid container spacing={6} sx={{ mb: 10 }}>
|
||||
{imageStyles.map((style) => (
|
||||
<Grid item xs={12} md={4} key={style.id}>
|
||||
<Card
|
||||
elevation={0}
|
||||
sx={{
|
||||
cursor: 'pointer',
|
||||
borderRadius: 4,
|
||||
border: selectedStyle === style.id ? 2 : 1,
|
||||
borderColor: selectedStyle === style.id ? colors.purple : 'divider',
|
||||
bgcolor: selectedStyle === style.id ? `${colors.purpleLight}40` : 'background.paper',
|
||||
transition: 'all 0.3s',
|
||||
position: 'relative',
|
||||
boxShadow: selectedStyle === style.id ? '0 4px 12px rgba(0, 0, 0, 0.15)' : '0 2px 8px rgba(0, 0, 0, 0.08)',
|
||||
'&:hover': {
|
||||
borderColor: colors.purple,
|
||||
transform: 'translateY(-2px)',
|
||||
boxShadow: '0 8px 16px rgba(0, 0, 0, 0.15)',
|
||||
},
|
||||
}}
|
||||
onClick={() => handleStyleSelect(style.id)}
|
||||
>
|
||||
<CardContent sx={{ p: 0 }}>
|
||||
{/* 스타일 이름 */}
|
||||
<Box sx={{ p: 4, borderBottom: 1, borderColor: 'divider', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Typography variant="h6" sx={{ fontWeight: 700, fontSize: '1.125rem' }}>
|
||||
{style.name}
|
||||
</Typography>
|
||||
<FormControlLabel
|
||||
value={style.id}
|
||||
control={<Radio sx={{ color: colors.purple, '&.Mui-checked': { color: colors.purple } }} />}
|
||||
label=""
|
||||
sx={{ m: 0 }}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Card
|
||||
elevation={0}
|
||||
sx={{
|
||||
cursor: 'pointer',
|
||||
borderRadius: 4,
|
||||
border: selectedStyle === style.id ? 3 : 1,
|
||||
borderColor: selectedStyle === style.id ? 'error.main' : 'divider',
|
||||
transition: 'all 0.3s',
|
||||
position: 'relative',
|
||||
'&:hover': {
|
||||
transform: 'translateY(-2px)',
|
||||
boxShadow: '0 8px 16px rgba(0, 0, 0, 0.1)',
|
||||
},
|
||||
}}
|
||||
onClick={() => handleStyleSelect(style.id)}
|
||||
>
|
||||
{selectedStyle === style.id && (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: 16,
|
||||
right: 16,
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: '50%',
|
||||
bgcolor: 'error.main',
|
||||
color: 'white',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
zIndex: 10,
|
||||
}}
|
||||
>
|
||||
<span className="material-icons" style={{ fontSize: 20 }}>
|
||||
check
|
||||
</span>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<CardContent sx={{ p: 0 }}>
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
aspectRatio: '1 / 1',
|
||||
background: style.gradient || '#f5f5f5',
|
||||
borderRadius: '12px 12px 0 0',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
p: 4,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="material-icons"
|
||||
style={{
|
||||
fontSize: 48,
|
||||
marginBottom: 16,
|
||||
color: style.textColor || 'inherit',
|
||||
}}
|
||||
>
|
||||
{style.icon}
|
||||
</span>
|
||||
<Typography
|
||||
variant="body1"
|
||||
{/* 이미지 프리뷰 */}
|
||||
<Box
|
||||
sx={{
|
||||
fontWeight: 600,
|
||||
mb: 1,
|
||||
color: style.textColor || 'text.primary',
|
||||
width: '100%',
|
||||
aspectRatio: '1 / 1',
|
||||
background: style.gradient || colors.gray[100],
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
p: 6,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
color: style.textColor || 'text.secondary',
|
||||
opacity: style.textColor ? 0.9 : 1,
|
||||
}}
|
||||
>
|
||||
{prize}
|
||||
</Typography>
|
||||
</Box>
|
||||
<span
|
||||
className="material-icons"
|
||||
style={{
|
||||
fontSize: 64,
|
||||
marginBottom: 24,
|
||||
color: style.textColor || colors.gray[700],
|
||||
}}
|
||||
>
|
||||
{style.icon}
|
||||
</span>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{
|
||||
fontWeight: 700,
|
||||
mb: 2,
|
||||
color: style.textColor || 'text.primary',
|
||||
fontSize: '1.25rem',
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
color: style.textColor || 'text.secondary',
|
||||
opacity: style.textColor ? 0.9 : 1,
|
||||
fontSize: '1rem',
|
||||
}}
|
||||
>
|
||||
{prize}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ p: 2, display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<Button
|
||||
size="small"
|
||||
startIcon={<ZoomIn />}
|
||||
onClick={(e) => handlePreview(style, e)}
|
||||
>
|
||||
크게보기
|
||||
</Button>
|
||||
<FormControlLabel
|
||||
value={style.id}
|
||||
control={<Radio sx={{ display: 'none' }} />}
|
||||
label=""
|
||||
sx={{ display: 'none' }}
|
||||
/>
|
||||
</Box>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Box>
|
||||
))}
|
||||
{/* 크게보기 버튼 */}
|
||||
<Box sx={{ p: 4, display: 'flex', justifyContent: 'center' }}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<ZoomIn />}
|
||||
onClick={(e) => handlePreview(style, e)}
|
||||
sx={{
|
||||
borderRadius: 2,
|
||||
py: 1.5,
|
||||
px: 4,
|
||||
fontSize: '0.875rem',
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
크게보기
|
||||
</Button>
|
||||
</Box>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</RadioGroup>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<Box sx={{ display: 'flex', gap: 2, mt: 5 }}>
|
||||
<Button fullWidth variant="outlined" size="large" onClick={onSkip} sx={{ py: 1.5 }}>
|
||||
<Box sx={{ display: 'flex', gap: 4 }}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
size="large"
|
||||
onClick={onSkip}
|
||||
sx={{
|
||||
py: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 600,
|
||||
borderWidth: 2,
|
||||
'&:hover': {
|
||||
borderWidth: 2,
|
||||
},
|
||||
}}
|
||||
>
|
||||
건너뛰기
|
||||
</Button>
|
||||
<Button
|
||||
@ -287,7 +302,20 @@ export default function ContentPreviewStep({
|
||||
size="large"
|
||||
disabled={!selectedStyle}
|
||||
onClick={handleNext}
|
||||
sx={{ py: 1.5 }}
|
||||
sx={{
|
||||
py: 3,
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||
'&:hover': {
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||
opacity: 0.9,
|
||||
},
|
||||
'&:disabled': {
|
||||
background: colors.gray[300],
|
||||
},
|
||||
}}
|
||||
>
|
||||
다음
|
||||
</Button>
|
||||
|
||||
@ -388,6 +388,14 @@ export default function RecommendationStep({ onNext, onBack }: RecommendationSte
|
||||
borderRadius: 3,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||
'&:hover': {
|
||||
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.pink} 100%)`,
|
||||
opacity: 0.9,
|
||||
},
|
||||
'&:disabled': {
|
||||
background: colors.gray[300],
|
||||
},
|
||||
}}
|
||||
>
|
||||
다음
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user