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:
cherry2250 2025-10-27 15:51:07 +09:00
parent 8e2376dc57
commit 56d3071b19
5 changed files with 436 additions and 240 deletions

View File

@ -17,26 +17,9 @@ import {
DialogActions, DialogActions,
Link, Link,
} from '@mui/material'; } 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'; import { EventData } from '../page';
import { cardStyles, colors, responsiveText } from '@/shared/lib/button-styles';
// 디자인 시스템 색상
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',
},
};
interface ApprovalStepProps { interface ApprovalStepProps {
eventData: EventData; eventData: EventData;
@ -79,91 +62,144 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
}; };
return ( return (
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 20 }}> <Box sx={{ minHeight: '100vh', bgcolor: colors.gray[50], pt: { xs: 7, sm: 8 }, pb: 10 }}>
<Container maxWidth="md" sx={{ pt: 8, pb: 8, px: { xs: 6, sm: 6, md: 8 } }}> <Container maxWidth="lg" sx={{ pt: 8, pb: 6, px: { xs: 6, sm: 8, md: 10 } }}>
{/* Header */} {/* Header */}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, mb: 8 }}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 3, mb: 8 }}>
<IconButton onClick={onBack}> <IconButton onClick={onBack}>
<ArrowBack /> <ArrowBack />
</IconButton> </IconButton>
<Typography variant="h5" sx={{ fontWeight: 700 }}> <Typography variant="h5" sx={{ ...responsiveText.h3, fontWeight: 700 }}>
</Typography> </Typography>
</Box> </Box>
{/* Title Section */} {/* Title Section */}
<Box sx={{ textAlign: 'center', mb: 5 }}> <Box sx={{ textAlign: 'center', mb: 10 }}>
<CheckCircle sx={{ fontSize: 64, color: 'success.main', mb: 2 }} /> <CheckCircle sx={{ fontSize: 64, color: colors.purple, mb: 2 }} />
<Typography variant="h5" sx={{ fontWeight: 700, mb: 1 }}> <Typography variant="h5" sx={{ ...responsiveText.h3, fontWeight: 700, mb: 2 }}>
</Typography> </Typography>
<Typography variant="body1" color="text.secondary"> <Typography variant="body1" color="text.secondary" sx={{ ...responsiveText.body1 }}>
</Typography> </Typography>
</Box> </Box>
{/* Event Summary Card */} {/* Event Summary Statistics */}
<Card elevation={0} sx={{ mb: 4, borderRadius: 4 }}> <Grid container spacing={4} sx={{ mb: 10 }}>
<CardContent sx={{ p: 4 }}> <Grid item xs={12} sm={6} md={3}>
<Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}> <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="h6"
sx={{ fontWeight: 700, color: 'white', fontSize: '1rem' }}
>
{eventData.recommendation?.title || '이벤트 제목'} {eventData.recommendation?.title || '이벤트 제목'}
</Typography> </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> </CardContent>
</Card> </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="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}
>
{eventData.recommendation?.expectedParticipants || 0}
<Typography component="span" sx={{ fontSize: '1rem', ml: 0.5 }}>
</Typography>
</Typography>
</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="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>
</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="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }}
>
{eventData.recommendation?.roi || 0}%
</Typography>
</CardContent>
</Card>
</Grid>
</Grid>
{/* Event Details */} {/* Event Details */}
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}> <Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 6 }}>
</Typography> </Typography>
<Card elevation={0} sx={{ mb: 2, borderRadius: 4 }}> <Card elevation={0} sx={{ ...cardStyles.default, mb: 4 }}>
<CardContent sx={{ p: 3 }}> <CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}> <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
<Box sx={{ flex: 1 }}> <Box sx={{ flex: 1 }}>
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" color="text.secondary" sx={{ ...responsiveText.body2, fontSize: '0.875rem' }}>
</Typography> </Typography>
<Typography variant="body1" sx={{ fontWeight: 600 }}> <Typography variant="body1" sx={{ ...responsiveText.body1, fontWeight: 600, mt: 1 }}>
{eventData.recommendation?.title} {eventData.recommendation?.title}
</Typography> </Typography>
</Box> </Box>
@ -174,14 +210,14 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
</CardContent> </CardContent>
</Card> </Card>
<Card elevation={0} sx={{ mb: 2, borderRadius: 4 }}> <Card elevation={0} sx={{ ...cardStyles.default, mb: 4 }}>
<CardContent sx={{ p: 3 }}> <CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}> <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
<Box sx={{ flex: 1 }}> <Box sx={{ flex: 1 }}>
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" color="text.secondary" sx={{ ...responsiveText.body2, fontSize: '0.875rem' }}>
</Typography> </Typography>
<Typography variant="body1" sx={{ fontWeight: 600 }}> <Typography variant="body1" sx={{ ...responsiveText.body1, fontWeight: 600, mt: 1 }}>
{eventData.recommendation?.prize} {eventData.recommendation?.prize}
</Typography> </Typography>
</Box> </Box>
@ -192,14 +228,14 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
</CardContent> </CardContent>
</Card> </Card>
<Card elevation={0} sx={{ mb: 2, borderRadius: 4 }}> <Card elevation={0} sx={{ ...cardStyles.default, mb: 10 }}>
<CardContent sx={{ p: 3 }}> <CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}> <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 2 }}>
<Box sx={{ flex: 1 }}> <Box sx={{ flex: 1 }}>
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" color="text.secondary" sx={{ ...responsiveText.body2, fontSize: '0.875rem' }}>
</Typography> </Typography>
<Typography variant="body1" sx={{ fontWeight: 600 }}> <Typography variant="body1" sx={{ ...responsiveText.body1, fontWeight: 600, mt: 1 }}>
{eventData.recommendation?.participationMethod} {eventData.recommendation?.participationMethod}
</Typography> </Typography>
</Box> </Box>
@ -208,21 +244,36 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
</Card> </Card>
{/* Distribution Channels */} {/* Distribution Channels */}
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3, mt: 4 }}> <Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 6 }}>
</Typography> </Typography>
<Card elevation={0} sx={{ mb: 4, borderRadius: 4 }}> <Card elevation={0} sx={{ ...cardStyles.default, mb: 10 }}>
<CardContent sx={{ p: 3 }}> <CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mb: 2 }}> <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 4 }}>
{getChannelNames(eventData.channels).map((channel) => ( {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> </Box>
<Button <Button
size="small" size="small"
startIcon={<Edit />} startIcon={<Edit />}
sx={{ color: 'primary.main' }} sx={{
...responsiveText.body2,
fontWeight: 600,
color: colors.purple,
}}
> >
</Button> </Button>
@ -230,19 +281,27 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
</Card> </Card>
{/* Terms Agreement */} {/* Terms Agreement */}
<Card elevation={0} sx={{ mb: 5, borderRadius: 4, bgcolor: 'grey.50' }}> <Card elevation={0} sx={{ ...cardStyles.default, bgcolor: colors.gray[50], mb: 10 }}>
<CardContent sx={{ p: 3 }}> <CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<FormControlLabel <FormControlLabel
control={ control={
<Checkbox <Checkbox
checked={agreeTerms} checked={agreeTerms}
onChange={(e) => setAgreeTerms(e.target.checked)} onChange={(e) => setAgreeTerms(e.target.checked)}
sx={{
color: colors.purple,
'&.Mui-checked': {
color: colors.purple,
},
}}
/> />
} }
label={ 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> </Typography>
} }
/> />
@ -250,7 +309,7 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
component="button" component="button"
variant="body2" variant="body2"
onClick={() => setTermsDialogOpen(true)} onClick={() => setTermsDialogOpen(true)}
sx={{ color: 'error.main', ml: 4, mt: 1 }} sx={{ ...responsiveText.body2, ml: 4, mt: 2, fontWeight: 600, color: colors.purple }}
> >
</Link> </Link>
@ -258,7 +317,7 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
</Card> </Card>
{/* Action Buttons */} {/* Action Buttons */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}> <Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
<Button <Button
fullWidth fullWidth
variant="contained" variant="contained"
@ -266,7 +325,20 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
disabled={!agreeTerms || isDeploying} disabled={!agreeTerms || isDeploying}
onClick={handleApprove} onClick={handleApprove}
startIcon={isDeploying ? null : <RocketLaunch />} 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 ? '배포 중...' : '배포하기'} {isDeploying ? '배포 중...' : '배포하기'}
</Button> </Button>
@ -276,7 +348,20 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
size="large" size="large"
onClick={handleSaveDraft} onClick={handleSaveDraft}
startIcon={<Save />} 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> </Button>
@ -289,39 +374,61 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
onClose={() => setTermsDialogOpen(false)} onClose={() => setTermsDialogOpen(false)}
maxWidth="sm" maxWidth="sm"
fullWidth fullWidth
PaperProps={{
sx: {
borderRadius: 4,
},
}}
> >
<DialogTitle> </DialogTitle> <DialogTitle sx={{ ...responsiveText.h3, fontWeight: 700, p: 6, pb: 4 }}>
<DialogContent>
<Typography variant="h6" sx={{ mb: 2 }}> </DialogTitle>
<DialogContent sx={{ px: 6, pb: 6 }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 3 }}>
1 () 1 ()
</Typography> </Typography>
<Typography variant="body2" sx={{ mb: 3 }}> <Typography variant="body2" sx={{ ...responsiveText.body1, mb: 6, color: colors.gray[700] }}>
KT AI KT AI
. .
</Typography> </Typography>
<Typography variant="h6" sx={{ mb: 2 }}> <Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 3 }}>
2 ( ) 2 ( )
</Typography> </Typography>
<Typography variant="body2" sx={{ mb: 1 }}> <Typography variant="body2" sx={{ ...responsiveText.body1, mb: 2, color: colors.gray[700] }}>
항목: 이름, , 항목: 이름, ,
</Typography> </Typography>
<Typography variant="body2" sx={{ mb: 1 }}> <Typography variant="body2" sx={{ ...responsiveText.body1, mb: 2, color: colors.gray[700] }}>
목적: 이벤트 목적: 이벤트
</Typography> </Typography>
<Typography variant="body2" sx={{ mb: 3 }}> <Typography variant="body2" sx={{ ...responsiveText.body1, mb: 6, color: colors.gray[700] }}>
기간: 이벤트 6 기간: 이벤트 6
</Typography> </Typography>
<Typography variant="h6" sx={{ mb: 2 }}> <Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 3 }}>
3 ( ) 3 ( )
</Typography> </Typography>
<Typography variant="body2"> <Typography variant="body2" sx={{ ...responsiveText.body1, color: colors.gray[700] }}>
7 . 7 .
</Typography> </Typography>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions sx={{ p: 6, pt: 4 }}>
<Button onClick={() => setTermsDialogOpen(false)} variant="contained"> <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> </Button>
</DialogActions> </DialogActions>
@ -334,18 +441,22 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
setSuccessDialogOpen(false); setSuccessDialogOpen(false);
onApprove(); onApprove();
}} }}
PaperProps={{
sx: {
borderRadius: 4,
},
}}
> >
<DialogContent sx={{ textAlign: 'center', py: 6, px: 4 }}> <DialogContent sx={{ textAlign: 'center', py: 10, px: 8 }}>
<CheckCircle sx={{ fontSize: 80, color: 'success.main', mb: 2 }} /> <CheckCircle sx={{ fontSize: 80, color: colors.purple, mb: 4 }} />
<Typography variant="h5" sx={{ fontWeight: 700, mb: 1 }}> <Typography variant="h5" sx={{ fontSize: '1.5rem', fontWeight: 700, mb: 3 }}>
! !
</Typography> </Typography>
<Typography variant="body1" color="text.secondary" sx={{ mb: 4 }}> <Typography variant="body1" color="text.secondary" sx={{ fontSize: '1rem', mb: 8 }}>
. .
<br /> <br />
. .
</Typography> </Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<Button <Button
fullWidth fullWidth
variant="contained" variant="contained"
@ -354,10 +465,20 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
setSuccessDialogOpen(false); setSuccessDialogOpen(false);
onApprove(); 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> </Button>
</Box>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
</Box> </Box>

View File

@ -522,6 +522,14 @@ export default function ChannelStep({ onNext, onBack }: ChannelStepProps) {
borderRadius: 3, borderRadius: 3,
fontSize: '1rem', fontSize: '1rem',
fontWeight: 700, 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],
},
}} }}
> >

View File

@ -163,11 +163,42 @@ export default function ContentEditStep({
</Grid> </Grid>
{/* Action Buttons */} {/* Action Buttons */}
<Box sx={{ display: 'flex', gap: 2, mt: 5 }}> <Box sx={{ display: 'flex', gap: 4, mt: 5 }}>
<Button fullWidth variant="outlined" size="large" onClick={handleSave} sx={{ py: 1.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>
<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> </Button>
</Box> </Box>

View File

@ -11,6 +11,7 @@ import {
FormControlLabel, FormControlLabel,
IconButton, IconButton,
Dialog, Dialog,
Grid,
} from '@mui/material'; } from '@mui/material';
import { ArrowBack, ZoomIn, Psychology } from '@mui/icons-material'; import { ArrowBack, ZoomIn, Psychology } from '@mui/icons-material';
@ -110,22 +111,22 @@ export default function ContentPreviewStep({
if (loading) { if (loading) {
return ( return (
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 20 }}> <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 }}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 3, mb: 8 }}>
<IconButton onClick={onBack}> <IconButton onClick={onBack}>
<ArrowBack /> <ArrowBack />
</IconButton> </IconButton>
<Typography variant="h5" sx={{ fontWeight: 700 }}> <Typography variant="h5" sx={{ fontWeight: 700, fontSize: '1.5rem' }}>
SNS SNS
</Typography> </Typography>
</Box> </Box>
<Box sx={{ textAlign: 'center', mt: 10, mb: 10 }}> <Box sx={{ textAlign: 'center', mt: 15, mb: 15 }}>
<Psychology <Psychology
sx={{ sx={{
fontSize: 64, fontSize: 80,
color: 'info.main', color: colors.purple,
mb: 2, mb: 4,
animation: 'spin 2s linear infinite', animation: 'spin 2s linear infinite',
'@keyframes spin': { '@keyframes spin': {
'0%': { transform: 'rotate(0deg)' }, '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 AI
</Typography> </Typography>
<Typography variant="body1" color="text.secondary" sx={{ mb: 2 }}> <Typography variant="body1" color="text.secondary" sx={{ mb: 3, fontSize: '1.125rem' }}>
<br /> <br />
... ...
</Typography> </Typography>
<Typography variant="caption" color="text.secondary"> <Typography variant="body2" color="text.secondary" sx={{ fontSize: '1rem' }}>
시간: 5초 시간: 5초
</Typography> </Typography>
</Box> </Box>
@ -152,133 +153,147 @@ export default function ContentPreviewStep({
return ( return (
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 20 }}> <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 */} {/* Header */}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 3, mb: 8 }}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 3, mb: 8 }}>
<IconButton onClick={onBack}> <IconButton onClick={onBack}>
<ArrowBack /> <ArrowBack />
</IconButton> </IconButton>
<Typography variant="h5" sx={{ fontWeight: 700 }}> <Typography variant="h5" sx={{ fontWeight: 700, fontSize: '1.5rem' }}>
SNS SNS
</Typography> </Typography>
</Box> </Box>
<RadioGroup value={selectedStyle} onChange={(e) => handleStyleSelect(e.target.value)}> <Typography variant="body2" color="text.secondary" sx={{ mb: 8, textAlign: 'center', fontSize: '1rem' }}>
{imageStyles.map((style) => (
<Box key={style.id} sx={{ mb: 4 }}>
<Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
{style.name}
</Typography> </Typography>
<RadioGroup value={selectedStyle} onChange={(e) => handleStyleSelect(e.target.value)}>
<Grid container spacing={6} sx={{ mb: 10 }}>
{imageStyles.map((style) => (
<Grid item xs={12} md={4} key={style.id}>
<Card <Card
elevation={0} elevation={0}
sx={{ sx={{
cursor: 'pointer', cursor: 'pointer',
borderRadius: 4, borderRadius: 4,
border: selectedStyle === style.id ? 3 : 1, border: selectedStyle === style.id ? 2 : 1,
borderColor: selectedStyle === style.id ? 'error.main' : 'divider', borderColor: selectedStyle === style.id ? colors.purple : 'divider',
bgcolor: selectedStyle === style.id ? `${colors.purpleLight}40` : 'background.paper',
transition: 'all 0.3s', transition: 'all 0.3s',
position: 'relative', 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': { '&:hover': {
borderColor: colors.purple,
transform: 'translateY(-2px)', transform: 'translateY(-2px)',
boxShadow: '0 8px 16px rgba(0, 0, 0, 0.1)', boxShadow: '0 8px 16px rgba(0, 0, 0, 0.15)',
}, },
}} }}
onClick={() => handleStyleSelect(style.id)} 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 }}> <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>
{/* 이미지 프리뷰 */}
<Box <Box
sx={{ sx={{
width: '100%', width: '100%',
aspectRatio: '1 / 1', aspectRatio: '1 / 1',
background: style.gradient || '#f5f5f5', background: style.gradient || colors.gray[100],
borderRadius: '12px 12px 0 0',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
p: 4, p: 6,
textAlign: 'center', textAlign: 'center',
}} }}
> >
<span <span
className="material-icons" className="material-icons"
style={{ style={{
fontSize: 48, fontSize: 64,
marginBottom: 16, marginBottom: 24,
color: style.textColor || 'inherit', color: style.textColor || colors.gray[700],
}} }}
> >
{style.icon} {style.icon}
</span> </span>
<Typography <Typography
variant="body1" variant="h6"
sx={{ sx={{
fontWeight: 600, fontWeight: 700,
mb: 1, mb: 2,
color: style.textColor || 'text.primary', color: style.textColor || 'text.primary',
fontSize: '1.25rem',
}} }}
> >
{title} {title}
</Typography> </Typography>
<Typography <Typography
variant="caption" variant="body1"
sx={{ sx={{
color: style.textColor || 'text.secondary', color: style.textColor || 'text.secondary',
opacity: style.textColor ? 0.9 : 1, opacity: style.textColor ? 0.9 : 1,
fontSize: '1rem',
}} }}
> >
{prize} {prize}
</Typography> </Typography>
</Box> </Box>
<Box sx={{ p: 2, display: 'flex', justifyContent: 'flex-end' }}> {/* 크게보기 버튼 */}
<Box sx={{ p: 4, display: 'flex', justifyContent: 'center' }}>
<Button <Button
size="small" variant="outlined"
startIcon={<ZoomIn />} startIcon={<ZoomIn />}
onClick={(e) => handlePreview(style, e)} onClick={(e) => handlePreview(style, e)}
sx={{
borderRadius: 2,
py: 1.5,
px: 4,
fontSize: '0.875rem',
fontWeight: 600,
}}
> >
</Button> </Button>
<FormControlLabel
value={style.id}
control={<Radio sx={{ display: 'none' }} />}
label=""
sx={{ display: 'none' }}
/>
</Box> </Box>
</CardContent> </CardContent>
</Card> </Card>
</Box> </Grid>
))} ))}
</Grid>
</RadioGroup> </RadioGroup>
{/* Action Buttons */} {/* Action Buttons */}
<Box sx={{ display: 'flex', gap: 2, mt: 5 }}> <Box sx={{ display: 'flex', gap: 4 }}>
<Button fullWidth variant="outlined" size="large" onClick={onSkip} sx={{ py: 1.5 }}> <Button
fullWidth
variant="outlined"
size="large"
onClick={onSkip}
sx={{
py: 3,
borderRadius: 3,
fontSize: '1rem',
fontWeight: 600,
borderWidth: 2,
'&:hover': {
borderWidth: 2,
},
}}
>
</Button> </Button>
<Button <Button
@ -287,7 +302,20 @@ export default function ContentPreviewStep({
size="large" size="large"
disabled={!selectedStyle} disabled={!selectedStyle}
onClick={handleNext} 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> </Button>

View File

@ -388,6 +388,14 @@ export default function RecommendationStep({ onNext, onBack }: RecommendationSte
borderRadius: 3, borderRadius: 3,
fontSize: '1rem', fontSize: '1rem',
fontWeight: 700, 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],
},
}} }}
> >