그래디언트 배경 카드 텍스트 가독성 개선 및 입체감 추가

- 배경색이 있는 모든 카드의 흰색 글자를 검은색으로 변경하여 가독성 향상
- 아이콘과 텍스트에 그림자 효과를 추가하여 입체감 부여
- Profile 페이지 디자인 통일성 완료

변경 파일:
- src/app/(main)/page.tsx: 대시보드 KPI 카드 (3개)
- src/app/(main)/events/page.tsx: 이벤트 통계 카드 (4개)
- src/app/(main)/events/create/steps/ApprovalStep.tsx: 승인 단계 요약 카드 (4개)
- src/app/(main)/profile/page.tsx: 프로필 페이지 전체 리디자인

적용된 효과:
- 아이콘: drop-shadow(0px 2px 4px rgba(0,0,0,0.2))
- 큰 텍스트: text-shadow 0px 2px 4px rgba(0,0,0,0.15)
- 작은 텍스트: text-shadow 0px 1px 2px rgba(0,0,0,0.1)
- 아이콘 배경: rgba(0,0,0,0.05) (대시보드)
- 글자 색상: colors.gray[900] (제목), colors.gray[700] (라벨)
This commit is contained in:
cherry2250 2025-10-27 16:15:43 +09:00
parent 56d3071b19
commit 47ed0b5a7c
4 changed files with 552 additions and 323 deletions

View File

@ -97,13 +97,28 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
}} }}
> >
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}> <CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<CheckCircle sx={{ fontSize: 32, color: 'white', mb: 1 }} /> <CheckCircle sx={{
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem', mb: 1 }}> fontSize: 32,
color: colors.gray[900],
mb: 1,
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
<Typography variant="body2" sx={{
color: colors.gray[700],
fontSize: '0.875rem',
mb: 1,
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}}>
</Typography> </Typography>
<Typography <Typography
variant="h6" variant="h6"
sx={{ fontWeight: 700, color: 'white', fontSize: '1rem' }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '1rem',
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{eventData.recommendation?.title || '이벤트 제목'} {eventData.recommendation?.title || '이벤트 제목'}
</Typography> </Typography>
@ -120,16 +135,36 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
}} }}
> >
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}> <CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<People sx={{ fontSize: 32, color: 'white', mb: 1 }} /> <People sx={{
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem', mb: 1 }}> fontSize: 32,
color: colors.gray[900],
mb: 1,
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
<Typography variant="body2" sx={{
color: colors.gray[700],
fontSize: '0.875rem',
mb: 1,
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}}>
</Typography> </Typography>
<Typography <Typography
variant="h4" variant="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '1.75rem',
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{eventData.recommendation?.expectedParticipants || 0} {eventData.recommendation?.expectedParticipants || 0}
<Typography component="span" sx={{ fontSize: '1rem', ml: 0.5 }}> <Typography component="span" sx={{
fontSize: '1rem',
ml: 0.5,
color: colors.gray[900],
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}>
</Typography> </Typography>
</Typography> </Typography>
@ -146,16 +181,36 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
}} }}
> >
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}> <CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<AttachMoney sx={{ fontSize: 32, color: 'white', mb: 1 }} /> <AttachMoney sx={{
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem', mb: 1 }}> fontSize: 32,
color: colors.gray[900],
mb: 1,
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
<Typography variant="body2" sx={{
color: colors.gray[700],
fontSize: '0.875rem',
mb: 1,
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}}>
</Typography> </Typography>
<Typography <Typography
variant="h4" variant="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '1.75rem',
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{((eventData.recommendation?.estimatedCost || 0) / 10000).toFixed(0)} {((eventData.recommendation?.estimatedCost || 0) / 10000).toFixed(0)}
<Typography component="span" sx={{ fontSize: '1rem', ml: 0.5 }}> <Typography component="span" sx={{
fontSize: '1rem',
ml: 0.5,
color: colors.gray[900],
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}>
</Typography> </Typography>
</Typography> </Typography>
@ -172,13 +227,28 @@ export default function ApprovalStep({ eventData, onApprove, onBack }: ApprovalS
}} }}
> >
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}> <CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<TrendingUp sx={{ fontSize: 32, color: 'white', mb: 1 }} /> <TrendingUp sx={{
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem', mb: 1 }}> fontSize: 32,
color: colors.gray[900],
mb: 1,
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
<Typography variant="body2" sx={{
color: colors.gray[700],
fontSize: '0.875rem',
mb: 1,
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}}>
ROI ROI
</Typography> </Typography>
<Typography <Typography
variant="h4" variant="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem' }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '1.75rem',
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{eventData.recommendation?.roi || 0}% {eventData.recommendation?.roi || 0}%
</Typography> </Typography>

View File

@ -250,14 +250,29 @@ export default function EventsPage() {
}} }}
> >
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}> <CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<Event sx={{ fontSize: 32, color: 'white', mb: 1 }} /> <Event sx={{
fontSize: 32,
color: colors.gray[900],
mb: 1,
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
<Typography <Typography
variant="h4" variant="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem', mb: 0.5 }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '1.75rem',
mb: 0.5,
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{stats.total} {stats.total}
</Typography> </Typography>
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem' }}> <Typography variant="body2" sx={{
color: colors.gray[700],
fontSize: '0.875rem',
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}}>
</Typography> </Typography>
</CardContent> </CardContent>
@ -273,14 +288,29 @@ export default function EventsPage() {
}} }}
> >
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}> <CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<LocalFireDepartment sx={{ fontSize: 32, color: 'white', mb: 1 }} /> <LocalFireDepartment sx={{
fontSize: 32,
color: colors.gray[900],
mb: 1,
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
<Typography <Typography
variant="h4" variant="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem', mb: 0.5 }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '1.75rem',
mb: 0.5,
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{stats.active} {stats.active}
</Typography> </Typography>
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem' }}> <Typography variant="body2" sx={{
color: colors.gray[700],
fontSize: '0.875rem',
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}}>
</Typography> </Typography>
</CardContent> </CardContent>
@ -296,14 +326,29 @@ export default function EventsPage() {
}} }}
> >
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}> <CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<People sx={{ fontSize: 32, color: 'white', mb: 1 }} /> <People sx={{
fontSize: 32,
color: colors.gray[900],
mb: 1,
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
<Typography <Typography
variant="h4" variant="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem', mb: 0.5 }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '1.75rem',
mb: 0.5,
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{stats.totalParticipants} {stats.totalParticipants}
</Typography> </Typography>
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem' }}> <Typography variant="body2" sx={{
color: colors.gray[700],
fontSize: '0.875rem',
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}}>
</Typography> </Typography>
</CardContent> </CardContent>
@ -319,14 +364,29 @@ export default function EventsPage() {
}} }}
> >
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}> <CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<TrendingUp sx={{ fontSize: 32, color: 'white', mb: 1 }} /> <TrendingUp sx={{
fontSize: 32,
color: colors.gray[900],
mb: 1,
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
<Typography <Typography
variant="h4" variant="h4"
sx={{ fontWeight: 700, color: 'white', fontSize: '1.75rem', mb: 0.5 }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '1.75rem',
mb: 0.5,
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{stats.avgROI}% {stats.avgROI}%
</Typography> </Typography>
<Typography variant="body2" sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.875rem' }}> <Typography variant="body2" sx={{
color: colors.gray[700],
fontSize: '0.875rem',
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}}>
ROI ROI
</Typography> </Typography>
</CardContent> </CardContent>

View File

@ -122,7 +122,7 @@ export default function HomePage() {
width: 64, width: 64,
height: 64, height: 64,
borderRadius: '50%', borderRadius: '50%',
bgcolor: 'rgba(255, 255, 255, 0.2)', bgcolor: 'rgba(0, 0, 0, 0.05)',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
@ -130,22 +130,32 @@ export default function HomePage() {
mb: 3, mb: 3,
}} }}
> >
<Celebration sx={{ fontSize: 32, color: 'white' }} /> <Celebration sx={{
fontSize: 32,
color: colors.gray[900],
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
</Box> </Box>
<Typography <Typography
variant="body2" variant="body2"
sx={{ sx={{
mb: 1, mb: 1,
color: 'rgba(255, 255, 255, 0.9)', color: colors.gray[700],
fontWeight: 500, fontWeight: 500,
fontSize: '0.875rem', fontSize: '0.875rem',
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}} }}
> >
</Typography> </Typography>
<Typography <Typography
variant="h3" variant="h3"
sx={{ fontWeight: 700, color: 'white', fontSize: '2.25rem' }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '2.25rem',
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{activeEvents.length} {activeEvents.length}
</Typography> </Typography>
@ -167,7 +177,7 @@ export default function HomePage() {
width: 64, width: 64,
height: 64, height: 64,
borderRadius: '50%', borderRadius: '50%',
bgcolor: 'rgba(255, 255, 255, 0.2)', bgcolor: 'rgba(0, 0, 0, 0.05)',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
@ -175,22 +185,32 @@ export default function HomePage() {
mb: 3, mb: 3,
}} }}
> >
<Group sx={{ fontSize: 32, color: 'white' }} /> <Group sx={{
fontSize: 32,
color: colors.gray[900],
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
</Box> </Box>
<Typography <Typography
variant="body2" variant="body2"
sx={{ sx={{
mb: 1, mb: 1,
color: 'rgba(255, 255, 255, 0.9)', color: colors.gray[700],
fontWeight: 500, fontWeight: 500,
fontSize: '0.875rem', fontSize: '0.875rem',
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}} }}
> >
</Typography> </Typography>
<Typography <Typography
variant="h3" variant="h3"
sx={{ fontWeight: 700, color: 'white', fontSize: '2.25rem' }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '2.25rem',
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{totalParticipants.toLocaleString()} {totalParticipants.toLocaleString()}
</Typography> </Typography>
@ -212,7 +232,7 @@ export default function HomePage() {
width: 64, width: 64,
height: 64, height: 64,
borderRadius: '50%', borderRadius: '50%',
bgcolor: 'rgba(255, 255, 255, 0.2)', bgcolor: 'rgba(0, 0, 0, 0.05)',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
@ -220,22 +240,32 @@ export default function HomePage() {
mb: 3, mb: 3,
}} }}
> >
<TrendingUp sx={{ fontSize: 32, color: 'white' }} /> <TrendingUp sx={{
fontSize: 32,
color: colors.gray[900],
filter: 'drop-shadow(0px 2px 4px rgba(0,0,0,0.2))',
}} />
</Box> </Box>
<Typography <Typography
variant="body2" variant="body2"
sx={{ sx={{
mb: 1, mb: 1,
color: 'rgba(255, 255, 255, 0.9)', color: colors.gray[700],
fontWeight: 500, fontWeight: 500,
fontSize: '0.875rem', fontSize: '0.875rem',
textShadow: '0px 1px 2px rgba(0,0,0,0.1)',
}} }}
> >
ROI ROI
</Typography> </Typography>
<Typography <Typography
variant="h3" variant="h3"
sx={{ fontWeight: 700, color: 'white', fontSize: '2.25rem' }} sx={{
fontWeight: 700,
color: colors.gray[900],
fontSize: '2.25rem',
textShadow: '0px 2px 4px rgba(0,0,0,0.15)',
}}
> >
{avgROI}% {avgROI}%
</Typography> </Typography>

View File

@ -7,10 +7,12 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod'; import { z } from 'zod';
import { import {
Box, Box,
Container,
TextField, TextField,
Button, Button,
Typography, Typography,
Paper, Card,
CardContent,
Avatar, Avatar,
Select, Select,
MenuItem, MenuItem,
@ -26,7 +28,8 @@ import {
import { Person, Visibility, VisibilityOff, CheckCircle } from '@mui/icons-material'; import { Person, Visibility, VisibilityOff, CheckCircle } from '@mui/icons-material';
import { useAuthStore } from '@/stores/authStore'; import { useAuthStore } from '@/stores/authStore';
import { useUIStore } from '@/stores/uiStore'; import { useUIStore } from '@/stores/uiStore';
import { getGradientButtonStyle, responsiveText, containerStyles } from '@/shared/lib/button-styles'; import Header from '@/shared/ui/Header';
import { cardStyles, colors, responsiveText } from '@/shared/lib/button-styles';
// 기본 정보 스키마 // 기본 정보 스키마
const basicInfoSchema = z.object({ const basicInfoSchema = z.object({
@ -186,304 +189,341 @@ export default function ProfilePage() {
}; };
return ( return (
<Box sx={{ ...containerStyles.page }}> <>
<Box sx={{ maxWidth: 600, mx: 'auto', px: { xs: 3, sm: 4 }, py: { xs: 3, sm: 4 } }}> <Header title="프로필" showBack={true} showMenu={false} showProfile={false} />
{/* 사용자 정보 섹션 */} <Box
<Paper elevation={0} sx={{ p: 4, mb: 3, textAlign: 'center' }}> sx={{
<Avatar pt: { xs: 7, sm: 8 },
sx={{ pb: 10,
width: 80, bgcolor: colors.gray[50],
height: 80, minHeight: '100vh',
mx: 'auto', }}
mb: 2, >
bgcolor: 'grey.100', <Container maxWidth="lg" sx={{ pt: 8, pb: 6, px: { xs: 6, sm: 8, md: 10 } }}>
color: 'grey.400', {/* 사용자 정보 섹션 */}
}} <Card elevation={0} sx={{ ...cardStyles.default, mb: 10, textAlign: 'center' }}>
> <CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<Person sx={{ fontSize: 48 }} /> <Avatar
</Avatar> sx={{
<Typography variant="h5" sx={{ ...responsiveText.h3, mb: 0.5 }}> width: 100,
{user?.name} height: 100,
</Typography> mx: 'auto',
<Typography variant="body2" color="text.secondary"> mb: 3,
{user?.email} bgcolor: colors.purple,
</Typography> color: 'white',
</Paper> }}
>
<Person sx={{ fontSize: 56 }} />
</Avatar>
<Typography variant="h5" sx={{ ...responsiveText.h3, mb: 1 }}>
{user?.name}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ ...responsiveText.body1 }}>
{user?.email}
</Typography>
</CardContent>
</Card>
{/* 기본 정보 */} {/* 기본 정보 */}
<Paper elevation={0} sx={{ p: 4, mb: 3 }}> <Card elevation={0} sx={{ ...cardStyles.default, mb: 10 }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, mb: 3 }}> <CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 6 }}>
</Typography>
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}> <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
<Controller <Controller
name="name" name="name"
control={basicControl} control={basicControl}
render={({ field }) => ( render={({ field }) => (
<TextField <TextField
{...field} {...field}
fullWidth fullWidth
label="이름" label="이름"
error={!!basicErrors.name} error={!!basicErrors.name}
helperText={basicErrors.name?.message} helperText={basicErrors.name?.message}
/> />
)}
/>
<Controller
name="phone"
control={basicControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
label="전화번호"
onChange={(e) => {
const formatted = formatPhoneNumber(e.target.value);
field.onChange(formatted);
}}
error={!!basicErrors.phone}
helperText={basicErrors.phone?.message}
/>
)}
/>
<Controller
name="email"
control={basicControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
label="이메일"
type="email"
error={!!basicErrors.email}
helperText={basicErrors.email?.message}
/>
)}
/>
</Box>
</Paper>
{/* 매장 정보 */}
<Paper elevation={0} sx={{ p: 4, mb: 3 }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, mb: 3 }}>
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
<Controller
name="businessName"
control={businessControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
label="매장명"
error={!!businessErrors.businessName}
helperText={businessErrors.businessName?.message}
/>
)}
/>
<Controller
name="businessType"
control={businessControl}
render={({ field }) => (
<FormControl fullWidth error={!!businessErrors.businessType}>
<InputLabel></InputLabel>
<Select {...field} label="업종">
<MenuItem value="restaurant"></MenuItem>
<MenuItem value="cafe">/</MenuItem>
<MenuItem value="retail">/</MenuItem>
<MenuItem value="beauty">/</MenuItem>
<MenuItem value="fitness">/</MenuItem>
<MenuItem value="education">/</MenuItem>
<MenuItem value="service"></MenuItem>
<MenuItem value="other"></MenuItem>
</Select>
{businessErrors.businessType && (
<Typography variant="caption" color="error" sx={{ mt: 0.5, ml: 2 }}>
{businessErrors.businessType.message}
</Typography>
)} )}
</FormControl>
)}
/>
<Controller
name="businessLocation"
control={businessControl}
render={({ field }) => (
<TextField {...field} fullWidth label="주소" />
)}
/>
<Controller
name="businessHours"
control={businessControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
label="영업시간"
placeholder="예: 10:00 ~ 22:00"
/> />
)}
/>
</Box>
</Paper>
{/* 비밀번호 변경 */} <Controller
<Paper elevation={0} sx={{ p: 4, mb: 3 }}> name="phone"
<Typography variant="h6" sx={{ ...responsiveText.h4, mb: 3 }}> control={basicControl}
render={({ field }) => (
</Typography> <TextField
{...field}
fullWidth
label="전화번호"
onChange={(e) => {
const formatted = formatPhoneNumber(e.target.value);
field.onChange(formatted);
}}
error={!!basicErrors.phone}
helperText={basicErrors.phone?.message}
/>
)}
/>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}> <Controller
<Controller name="email"
name="currentPassword" control={basicControl}
control={passwordControl} render={({ field }) => (
render={({ field }) => ( <TextField
<TextField {...field}
{...field} fullWidth
label="이메일"
type="email"
error={!!basicErrors.email}
helperText={basicErrors.email?.message}
/>
)}
/>
</Box>
</CardContent>
</Card>
{/* 매장 정보 */}
<Card elevation={0} sx={{ ...cardStyles.default, mb: 10 }}>
<CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 6 }}>
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
<Controller
name="businessName"
control={businessControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
label="매장명"
error={!!businessErrors.businessName}
helperText={businessErrors.businessName?.message}
/>
)}
/>
<Controller
name="businessType"
control={businessControl}
render={({ field }) => (
<FormControl fullWidth error={!!businessErrors.businessType}>
<InputLabel></InputLabel>
<Select {...field} label="업종">
<MenuItem value="restaurant"></MenuItem>
<MenuItem value="cafe">/</MenuItem>
<MenuItem value="retail">/</MenuItem>
<MenuItem value="beauty">/</MenuItem>
<MenuItem value="fitness">/</MenuItem>
<MenuItem value="education">/</MenuItem>
<MenuItem value="service"></MenuItem>
<MenuItem value="other"></MenuItem>
</Select>
{businessErrors.businessType && (
<Typography variant="caption" color="error" sx={{ mt: 0.5, ml: 2 }}>
{businessErrors.businessType.message}
</Typography>
)}
</FormControl>
)}
/>
<Controller
name="businessLocation"
control={businessControl}
render={({ field }) => (
<TextField {...field} fullWidth label="주소" />
)}
/>
<Controller
name="businessHours"
control={businessControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
label="영업시간"
placeholder="예: 10:00 ~ 22:00"
/>
)}
/>
</Box>
</CardContent>
</Card>
{/* 비밀번호 변경 */}
<Card elevation={0} sx={{ ...cardStyles.default, mb: 10 }}>
<CardContent sx={{ p: { xs: 6, sm: 8 } }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, fontWeight: 700, mb: 6 }}>
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
<Controller
name="currentPassword"
control={passwordControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
type={showCurrentPassword ? 'text' : 'password'}
label="현재 비밀번호"
placeholder="현재 비밀번호를 입력하세요"
error={!!passwordErrors.currentPassword}
helperText={passwordErrors.currentPassword?.message}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
onClick={() => setShowCurrentPassword(!showCurrentPassword)}
edge="end"
>
{showCurrentPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}}
/>
)}
/>
<Controller
name="newPassword"
control={passwordControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
type={showNewPassword ? 'text' : 'password'}
label="새 비밀번호"
placeholder="새 비밀번호를 입력하세요"
error={!!passwordErrors.newPassword}
helperText={passwordErrors.newPassword?.message || '8자 이상, 영문과 숫자를 포함해주세요'}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
onClick={() => setShowNewPassword(!showNewPassword)}
edge="end"
>
{showNewPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}}
/>
)}
/>
<Controller
name="confirmPassword"
control={passwordControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
type={showConfirmPassword ? 'text' : 'password'}
label="비밀번호 확인"
placeholder="비밀번호를 다시 입력하세요"
error={!!passwordErrors.confirmPassword}
helperText={passwordErrors.confirmPassword?.message}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
edge="end"
>
{showConfirmPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}}
/>
)}
/>
<Button
fullWidth fullWidth
type={showCurrentPassword ? 'text' : 'password'} variant="outlined"
label="현재 비밀번호" size="large"
placeholder="현재 비밀번호를 입력하세요" onClick={handlePasswordSubmit(onChangePassword)}
error={!!passwordErrors.currentPassword} sx={{
helperText={passwordErrors.currentPassword?.message} mt: 1,
InputProps={{ py: 3,
endAdornment: ( borderRadius: 3,
<InputAdornment position="end"> fontSize: '1rem',
<IconButton fontWeight: 600,
onClick={() => setShowCurrentPassword(!showCurrentPassword)} borderWidth: 2,
edge="end" '&:hover': {
> borderWidth: 2,
{showCurrentPassword ? <VisibilityOff /> : <Visibility />} },
</IconButton>
</InputAdornment>
),
}} }}
/> >
)}
/> </Button>
</Box>
<Controller </CardContent>
name="newPassword" </Card>
control={passwordControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
type={showNewPassword ? 'text' : 'password'}
label="새 비밀번호"
placeholder="새 비밀번호를 입력하세요"
error={!!passwordErrors.newPassword}
helperText={passwordErrors.newPassword?.message || '8자 이상, 영문과 숫자를 포함해주세요'}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
onClick={() => setShowNewPassword(!showNewPassword)}
edge="end"
>
{showNewPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}}
/>
)}
/>
<Controller
name="confirmPassword"
control={passwordControl}
render={({ field }) => (
<TextField
{...field}
fullWidth
type={showConfirmPassword ? 'text' : 'password'}
label="비밀번호 확인"
placeholder="비밀번호를 다시 입력하세요"
error={!!passwordErrors.confirmPassword}
helperText={passwordErrors.confirmPassword?.message}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
edge="end"
>
{showConfirmPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}}
/>
)}
/>
{/* 액션 버튼 */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
<Button <Button
fullWidth fullWidth
variant="outlined" variant="contained"
size="large" size="large"
onClick={handlePasswordSubmit(onChangePassword)} onClick={handleSave}
sx={{ sx={{
mt: 1, py: 3,
py: { xs: 1.5, sm: 1.75 }, borderRadius: 3,
fontSize: { xs: 15, sm: 16 }, fontSize: '1rem',
fontWeight: 600, fontWeight: 700,
borderWidth: 2, 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
fullWidth
variant="text"
size="large"
color="error"
onClick={() => setLogoutDialogOpen(true)}
sx={{
py: 3,
fontSize: '1rem',
fontWeight: 600,
}}
>
</Button> </Button>
</Box> </Box>
</Paper> </Container>
{/* 액션 버튼 */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<Button
fullWidth
variant="contained"
size="large"
onClick={handleSave}
sx={{
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
...getGradientButtonStyle('primary'),
}}
>
</Button>
<Button
fullWidth
variant="text"
size="large"
color="error"
onClick={() => setLogoutDialogOpen(true)}
sx={{
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
fontWeight: 600,
}}
>
</Button>
</Box>
</Box> </Box>
{/* 저장 완료 다이얼로그 */} {/* 저장 완료 다이얼로그 */}
<Dialog open={successDialogOpen} onClose={() => setSuccessDialogOpen(false)}> <Dialog
open={successDialogOpen}
onClose={() => setSuccessDialogOpen(false)}
PaperProps={{
sx: {
borderRadius: 4,
minWidth: 300,
},
}}
>
<DialogContent sx={{ textAlign: 'center', py: 6, px: 4 }}> <DialogContent sx={{ textAlign: 'center', py: 6, px: 4 }}>
<CheckCircle sx={{ fontSize: 64, color: 'success.main', mb: 2 }} /> <CheckCircle sx={{ fontSize: 64, color: 'success.main', mb: 2 }} />
<Typography variant="h6" sx={{ fontWeight: 700, mb: 1 }}> <Typography variant="h6" sx={{ fontWeight: 700, mb: 1, fontSize: '1.25rem' }}>
</Typography> </Typography>
<Typography variant="body2" color="text.secondary"> <Typography variant="body2" color="text.secondary" sx={{ fontSize: '1rem' }}>
. .
</Typography> </Typography>
</DialogContent> </DialogContent>
@ -496,8 +536,15 @@ export default function ProfilePage() {
}} }}
sx={{ sx={{
minWidth: 120, minWidth: 120,
py: { xs: 1.25, sm: 1.5 }, py: 2,
...getGradientButtonStyle('success'), borderRadius: 2,
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,
},
}} }}
> >
@ -506,29 +553,51 @@ export default function ProfilePage() {
</Dialog> </Dialog>
{/* 로그아웃 확인 다이얼로그 */} {/* 로그아웃 확인 다이얼로그 */}
<Dialog open={logoutDialogOpen} onClose={() => setLogoutDialogOpen(false)}> <Dialog
<DialogTitle></DialogTitle> open={logoutDialogOpen}
onClose={() => setLogoutDialogOpen(false)}
PaperProps={{
sx: {
borderRadius: 4,
minWidth: 300,
},
}}
>
<DialogTitle sx={{ fontSize: '1.25rem', fontWeight: 700 }}></DialogTitle>
<DialogContent> <DialogContent>
<Typography variant="body1" sx={{ textAlign: 'center', py: 2 }}> <Typography variant="body1" sx={{ textAlign: 'center', py: 2, fontSize: '1rem' }}>
? ?
</Typography> </Typography>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions sx={{ justifyContent: 'center', gap: 2, pb: 3 }}>
<Button <Button
onClick={() => setLogoutDialogOpen(false)} onClick={() => setLogoutDialogOpen(false)}
sx={{ fontWeight: 600 }} sx={{
fontWeight: 600,
fontSize: '1rem',
py: 2,
px: 4,
borderRadius: 2,
}}
> >
</Button> </Button>
<Button <Button
variant="contained" variant="contained"
onClick={handleLogout} onClick={handleLogout}
sx={{ ...getGradientButtonStyle('error') }} color="error"
sx={{
fontWeight: 700,
fontSize: '1rem',
py: 2,
px: 4,
borderRadius: 2,
}}
> >
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</Box> </>
); );
} }