참고 디자인을 기반으로 전면 리디자인 완료

## 주요 변경사항

### 디자인 시스템 개선
- 새로운 색상 팔레트 적용 (민트, 보라, 파랑 기반)
- Tailwind CSS 스타일 그림자 시스템
- 개선된 카드 스타일 (1px 테두리, 큰 border-radius)
- 부드러운 애니메이션 (cubic-bezier)
- 타이포그래피 개선 (letter-spacing, 색상 계층)

### 메인 대시보드 리디자인
- KPI 카드: 그라디언트 배경, 원형 아이콘 컨테이너, 큰 숫자
- 빠른 시작: 개선된 아이콘 크기와 그림자
- 진행 중인 이벤트: 깔끔한 레이아웃, 민트 배지
- 최근 활동: 그라디언트 아이콘, 더 큰 간격
- FAB 버튼: 보라색 글로우 효과

### 레이아웃 개선
- 더 넓은 여백과 간격 (mb: 6, spacing: 4)
- 밝은 회색 배경 적용
- 화이트 카드 배경
- 개선된 반응형 패딩

### Header 오버레이 수정
- 모든 페이지에 적절한 상단 패딩 추가
- containerStyles.page에 pt 추가

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
cherry2250 2025-10-27 11:42:44 +09:00
parent edcd0cd559
commit 01a77fe7a8
7 changed files with 419 additions and 173 deletions

View File

@ -21,6 +21,7 @@ import {
import { Visibility, VisibilityOff, Email, Lock, ChatBubble } from '@mui/icons-material';
import { useAuthStore } from '@/stores/authStore';
import { useUIStore } from '@/stores/uiStore';
import { getGradientButtonStyle, responsiveText } from '@/shared/lib/button-styles';
// 유효성 검사 스키마
const loginSchema = z.object({
@ -132,7 +133,7 @@ export default function LoginPage() {
>
<Typography sx={{ fontSize: 32 }}>🎉</Typography>
</Box>
<Typography variant="h4" sx={{ fontWeight: 700, mb: 1 }}>
<Typography variant="h4" sx={{ ...responsiveText.h2, mb: 1 }}>
KT AI
</Typography>
<Typography variant="body2" color="text.secondary">
@ -227,9 +228,9 @@ export default function LoginPage() {
size="large"
sx={{
mb: 2,
py: 1.5,
fontSize: 16,
fontWeight: 600,
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
...getGradientButtonStyle('primary'),
}}
>

View File

@ -27,6 +27,7 @@ import { ArrowBack, Visibility, VisibilityOff, CheckCircle } from '@mui/icons-ma
import { useState, useEffect, Suspense } from 'react';
import { useUIStore } from '@/stores/uiStore';
import { useAuthStore } from '@/stores/authStore';
import { getGradientButtonStyle, responsiveText } from '@/shared/lib/button-styles';
// 각 단계별 유효성 검사 스키마
const step1Schema = z
@ -289,7 +290,7 @@ function RegisterForm() {
{/* Step 1: 계정정보 */}
{currentStep === 1 && (
<Box>
<Typography variant="h5" sx={{ fontWeight: 700, mb: 1 }}>
<Typography variant="h5" sx={{ ...responsiveText.h3, mb: 1 }}>
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 4 }}>
@ -359,7 +360,12 @@ function RegisterForm() {
variant="contained"
size="large"
onClick={handleNext}
sx={{ mt: 2, py: 1.5, fontSize: 16, fontWeight: 600 }}
sx={{
mt: 2,
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
...getGradientButtonStyle('primary'),
}}
>
</Button>
@ -383,7 +389,7 @@ function RegisterForm() {
{/* Step 2: 개인정보 */}
{currentStep === 2 && (
<Box>
<Typography variant="h5" sx={{ fontWeight: 700, mb: 1 }}>
<Typography variant="h5" sx={{ ...responsiveText.h3, mb: 1 }}>
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 4 }}>
@ -421,7 +427,13 @@ function RegisterForm() {
variant="outlined"
size="large"
onClick={handleBack}
sx={{ flex: 1, py: 1.5, fontSize: 16, fontWeight: 600 }}
sx={{
flex: 1,
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
fontWeight: 600,
borderWidth: 2,
}}
>
</Button>
@ -429,7 +441,12 @@ function RegisterForm() {
variant="contained"
size="large"
onClick={handleNext}
sx={{ flex: 1, py: 1.5, fontSize: 16, fontWeight: 600 }}
sx={{
flex: 1,
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
...getGradientButtonStyle('primary'),
}}
>
</Button>
@ -441,7 +458,7 @@ function RegisterForm() {
{/* Step 3: 사업장정보 */}
{currentStep === 3 && (
<Box>
<Typography variant="h5" sx={{ fontWeight: 700, mb: 1 }}>
<Typography variant="h5" sx={{ ...responsiveText.h3, mb: 1 }}>
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 4 }}>
@ -627,7 +644,13 @@ function RegisterForm() {
variant="outlined"
size="large"
onClick={handleBack}
sx={{ flex: 1, py: 1.5, fontSize: 16, fontWeight: 600 }}
sx={{
flex: 1,
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
fontWeight: 600,
borderWidth: 2,
}}
>
</Button>
@ -635,7 +658,12 @@ function RegisterForm() {
variant="contained"
size="large"
onClick={handleNext}
sx={{ flex: 1, py: 1.5, fontSize: 16, fontWeight: 600 }}
sx={{
flex: 1,
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
...getGradientButtonStyle('success'),
}}
>
</Button>
@ -665,7 +693,12 @@ function RegisterForm() {
variant="contained"
size="large"
onClick={handleSuccessDialogClose}
sx={{ minWidth: 200, py: 1.5, fontSize: 16, fontWeight: 600 }}
sx={{
minWidth: 200,
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
...getGradientButtonStyle('success'),
}}
>
</Button>

View File

@ -98,7 +98,7 @@ export default function AnalyticsPage() {
return (
<>
<Header title="성과 분석" showBack={true} showMenu={false} showProfile={true} />
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 10 }}>
<Box sx={{ pt: { xs: 7, sm: 8 }, minHeight: '100vh', bgcolor: 'background.default', pb: 10 }}>
<Container maxWidth="lg" sx={{ pt: 4, pb: 4, px: { xs: 3, sm: 3, md: 4 } }}>
{/* Title with Real-time Indicator */}
<Box

View File

@ -143,7 +143,7 @@ export default function EventsPage() {
return (
<>
<Header title="이벤트 목록" showBack={true} showMenu={false} showProfile={true} />
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 10 }}>
<Box sx={{ pt: { xs: 7, sm: 8 }, minHeight: '100vh', bgcolor: 'background.default', pb: 10 }}>
<Container maxWidth="lg" sx={{ pt: 4, pb: 4, px: { xs: 3, sm: 3, md: 4 } }}>
{/* Search Section */}
<Box sx={{ mb: 3 }}>

View File

@ -22,6 +22,7 @@ import {
CheckCircle,
} from '@mui/icons-material';
import Header from '@/shared/ui/Header';
import { getGradientButtonStyle, responsiveText, cardStyles, colors } from '@/shared/lib/button-styles';
// Mock 사용자 데이터 (API 연동 전까지 임시 사용)
const mockUser = {
@ -84,98 +85,137 @@ export default function HomePage() {
<Header title="대시보드" showBack={false} showMenu={false} showProfile={true} />
<Box
sx={{
pt: { xs: 7, sm: 8 },
pb: 10,
bgcolor: 'background.default',
bgcolor: colors.gray[50],
minHeight: '100vh',
}}
>
<Container maxWidth="lg" sx={{ pt: 4, pb: 4, px: { xs: 3, sm: 3, md: 4 } }}>
<Container maxWidth="lg" sx={{ pt: 5, pb: 4, px: { xs: 3, sm: 4, md: 5 } }}>
{/* Welcome Section */}
<Box sx={{ mb: 5 }}>
<Box sx={{ mb: 6 }}>
<Typography
variant="h4"
variant="h3"
sx={{
fontWeight: 700,
mb: 1,
color: 'text.primary',
...responsiveText.h2,
mb: 2,
}}
>
, {mockUser.name}!
, {mockUser.name}! 👋
</Typography>
<Typography variant="body1" sx={{ color: 'text.secondary', fontWeight: 500 }}>
<Typography variant="body1" sx={{ ...responsiveText.body1 }}>
</Typography>
</Box>
{/* KPI Cards */}
<Grid container spacing={3} sx={{ mb: 5 }}>
<Grid item xs={4}>
<Grid container spacing={4} sx={{ mb: 6 }}>
<Grid item xs={12} sm={4}>
<Card
elevation={0}
sx={{
bgcolor: 'primary.main',
borderRadius: 3,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
...cardStyles.default,
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.purpleLight} 100%)`,
borderColor: 'transparent',
}}
>
<CardContent sx={{ textAlign: 'center', py: 3, px: 2 }}>
<Celebration sx={{ fontSize: 40, mb: 1.5, color: 'white' }} />
<Typography
variant="caption"
display="block"
sx={{ mb: 0.5, color: 'white', fontWeight: 600 }}
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<Box
sx={{
width: 64,
height: 64,
borderRadius: '50%',
bgcolor: 'rgba(255, 255, 255, 0.2)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto',
mb: 2,
}}
>
<Celebration sx={{ fontSize: 32, color: 'white' }} />
</Box>
<Typography
variant="body2"
sx={{ mb: 1, color: 'rgba(255, 255, 255, 0.9)', fontWeight: 500, fontSize: '0.875rem' }}
>
</Typography>
<Typography variant="h5" sx={{ fontWeight: 700, color: 'white' }}>
{activeEvents.length}
<Typography variant="h3" sx={{ fontWeight: 700, color: 'white', fontSize: '2.5rem' }}>
{activeEvents.length}
</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={4}>
<Grid item xs={12} sm={4}>
<Card
elevation={0}
sx={{
bgcolor: 'secondary.main',
borderRadius: 3,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
...cardStyles.default,
background: `linear-gradient(135deg, ${colors.mint} 0%, ${colors.mintLight} 100%)`,
borderColor: 'transparent',
}}
>
<CardContent sx={{ textAlign: 'center', py: 3, px: 2 }}>
<Group sx={{ fontSize: 40, mb: 1.5, color: 'white' }} />
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<Box
sx={{
width: 64,
height: 64,
borderRadius: '50%',
bgcolor: 'rgba(255, 255, 255, 0.2)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto',
mb: 2,
}}
>
<Group sx={{ fontSize: 32, color: 'white' }} />
</Box>
<Typography
variant="caption"
display="block"
sx={{ mb: 0.5, color: 'white', fontWeight: 600 }}
variant="body2"
sx={{ mb: 1, color: 'rgba(255, 255, 255, 0.9)', fontWeight: 500, fontSize: '0.875rem' }}
>
</Typography>
<Typography variant="h5" sx={{ fontWeight: 700, color: 'white' }}>
{totalParticipants.toLocaleString()}
<Typography variant="h3" sx={{ fontWeight: 700, color: 'white', fontSize: '2.5rem' }}>
{totalParticipants.toLocaleString()}
</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={4}>
<Grid item xs={12} sm={4}>
<Card
elevation={0}
sx={{
bgcolor: 'info.main',
borderRadius: 3,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
...cardStyles.default,
background: `linear-gradient(135deg, ${colors.blue} 0%, ${colors.blueLight} 100%)`,
borderColor: 'transparent',
}}
>
<CardContent sx={{ textAlign: 'center', py: 3, px: 2 }}>
<TrendingUp sx={{ fontSize: 40, mb: 1.5, color: 'white' }} />
<CardContent sx={{ textAlign: 'center', py: 4, px: 3 }}>
<Box
sx={{
width: 64,
height: 64,
borderRadius: '50%',
bgcolor: 'rgba(255, 255, 255, 0.2)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto',
mb: 2,
}}
>
<TrendingUp sx={{ fontSize: 32, color: 'white' }} />
</Box>
<Typography
variant="caption"
display="block"
sx={{ mb: 0.5, color: 'white', fontWeight: 600 }}
variant="body2"
sx={{ mb: 1, color: 'rgba(255, 255, 255, 0.9)', fontWeight: 500, fontSize: '0.875rem' }}
>
ROI
</Typography>
<Typography variant="h5" sx={{ fontWeight: 700, color: 'white' }}>
<Typography variant="h3" sx={{ fontWeight: 700, color: 'white', fontSize: '2.5rem' }}>
{avgROI}%
</Typography>
</CardContent>
@ -184,81 +224,69 @@ export default function HomePage() {
</Grid>
{/* Quick Actions */}
<Box sx={{ mb: 5 }}>
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3, color: 'text.primary' }}>
<Box sx={{ mb: 6 }}>
<Typography variant="h5" sx={{ ...responsiveText.h3, mb: 4 }}>
</Typography>
<Grid container spacing={3}>
<Grid item xs={6}>
<Grid container spacing={4}>
<Grid item xs={6} sm={6}>
<Card
elevation={0}
sx={{
cursor: 'pointer',
borderRadius: 3,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
transition: 'all 0.2s ease',
'&:hover': {
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
transform: 'translateY(-2px)',
},
...cardStyles.clickable,
}}
onClick={handleCreateEvent}
>
<CardContent sx={{ textAlign: 'center', py: 4 }}>
<CardContent sx={{ textAlign: 'center', py: 5 }}>
<Box
sx={{
width: 56,
height: 56,
borderRadius: '16px',
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
width: 72,
height: 72,
borderRadius: '20px',
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.blue} 100%)`,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto',
mb: 2,
mb: 2.5,
boxShadow: '0 4px 14px 0 rgba(167, 139, 250, 0.39)',
}}
>
<Add sx={{ fontSize: 32, color: 'white' }} />
<Add sx={{ fontSize: 36, color: 'white' }} />
</Box>
<Typography variant="body2" sx={{ fontWeight: 600, color: 'text.primary' }}>
<Typography variant="body1" sx={{ fontWeight: 600, color: colors.gray[900] }}>
</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={6}>
<Grid item xs={6} sm={6}>
<Card
elevation={0}
sx={{
cursor: 'pointer',
borderRadius: 3,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
transition: 'all 0.2s ease',
'&:hover': {
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
transform: 'translateY(-2px)',
},
...cardStyles.clickable,
}}
onClick={handleViewAnalytics}
>
<CardContent sx={{ textAlign: 'center', py: 4 }}>
<CardContent sx={{ textAlign: 'center', py: 5 }}>
<Box
sx={{
width: 56,
height: 56,
borderRadius: '16px',
background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
width: 72,
height: 72,
borderRadius: '20px',
background: `linear-gradient(135deg, ${colors.blue} 0%, ${colors.mint} 100%)`,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto',
mb: 2,
mb: 2.5,
boxShadow: '0 4px 14px 0 rgba(96, 165, 250, 0.39)',
}}
>
<Analytics sx={{ fontSize: 32, color: 'white' }} />
<Analytics sx={{ fontSize: 36, color: 'white' }} />
</Box>
<Typography variant="body2" sx={{ fontWeight: 600, color: 'text.primary' }}>
<Typography variant="body1" sx={{ fontWeight: 600, color: colors.gray[900] }}>
</Typography>
</CardContent>
</Card>
@ -267,19 +295,19 @@ export default function HomePage() {
</Box>
{/* Active Events */}
<Box sx={{ mb: 5 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
<Typography variant="h6" sx={{ fontWeight: 700, color: 'text.primary' }}>
<Box sx={{ mb: 6 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 4 }}>
<Typography variant="h5" sx={{ ...responsiveText.h3 }}>
</Typography>
<Button
size="small"
size="medium"
endIcon={<span className="material-icons">chevron_right</span>}
onClick={() => router.push('/events')}
sx={{
color: 'primary.main',
color: colors.purple,
fontWeight: 600,
'&:hover': { background: 'rgba(102, 126, 234, 0.08)' },
'&:hover': { bgcolor: 'rgba(167, 139, 250, 0.08)' },
}}
>
@ -290,28 +318,30 @@ export default function HomePage() {
<Card
elevation={0}
sx={{
borderRadius: 3,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
...cardStyles.default,
}}
>
<CardContent sx={{ textAlign: 'center', py: 8 }}>
<Box sx={{ color: 'text.disabled', mb: 2 }}>
<span className="material-icons" style={{ fontSize: 64 }}>
<CardContent sx={{ textAlign: 'center', py: 10 }}>
<Box sx={{ color: colors.gray[300], mb: 3 }}>
<span className="material-icons" style={{ fontSize: 72 }}>
event_busy
</span>
</Box>
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
<Typography variant="h6" sx={{ mb: 2, color: colors.gray[700] }}>
</Typography>
<Typography variant="body2" sx={{ mb: 4, color: colors.gray[500] }}>
</Typography>
<Button
variant="contained"
startIcon={<Add />}
onClick={handleCreateEvent}
sx={{
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
'&:hover': {
background: 'linear-gradient(135deg, #5568d3 0%, #65408b 100%)',
},
py: { xs: 1.5, sm: 1.75 },
px: { xs: 3, sm: 4 },
fontSize: { xs: 15, sm: 16 },
...getGradientButtonStyle('primary'),
}}
>
@ -319,59 +349,56 @@ export default function HomePage() {
</CardContent>
</Card>
) : (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
{activeEvents.map((event) => (
<Card
key={event.id}
elevation={0}
sx={{
cursor: 'pointer',
borderRadius: 3,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
transition: 'all 0.2s ease',
'&:hover': {
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
transform: 'translateY(-2px)',
},
...cardStyles.clickable,
}}
onClick={() => handleEventClick(event.id)}
>
<CardContent sx={{ p: 4 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}>
<Typography variant="subtitle1" sx={{ fontWeight: 700, color: 'text.primary' }}>
<CardContent sx={{ p: { xs: 3, sm: 4 } }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'start', mb: 3 }}>
<Typography variant="h6" sx={{ fontWeight: 700, color: colors.gray[900] }}>
{event.title}
</Typography>
<Box
sx={{
px: 2,
py: 0.5,
bgcolor: 'success.main',
px: 2.5,
py: 0.75,
bgcolor: colors.mint,
color: 'white',
borderRadius: 2,
fontSize: '0.75rem',
fontWeight: 700,
fontSize: '0.875rem',
fontWeight: 600,
}}
>
{event.status}
</Box>
</Box>
<Typography variant="body2" color="text.secondary" sx={{ mb: 2.5, fontWeight: 500 }}>
📅 {event.startDate} ~ {event.endDate}
<Typography variant="body2" sx={{ mb: 3, color: colors.gray[600], display: 'flex', alignItems: 'center', gap: 1 }}>
<span>📅</span>
<span>{event.startDate} ~ {event.endDate}</span>
</Typography>
<Box sx={{ display: 'flex', gap: 5 }}>
<Box sx={{ display: 'flex', gap: 6 }}>
<Box>
<Typography variant="caption" color="text.secondary" sx={{ fontWeight: 600 }}>
<Typography variant="body2" sx={{ mb: 0.5, color: colors.gray[600], fontWeight: 500 }}>
</Typography>
<Typography variant="h6" sx={{ fontWeight: 700, color: 'text.primary' }}>
{event.participants.toLocaleString()}
<Typography variant="h5" sx={{ fontWeight: 700, color: colors.gray[900] }}>
{event.participants.toLocaleString()}
<Typography component="span" variant="body2" sx={{ ml: 0.5, color: colors.gray[600] }}>
</Typography>
</Typography>
</Box>
<Box>
<Typography variant="caption" color="text.secondary" sx={{ fontWeight: 600 }}>
<Typography variant="body2" sx={{ mb: 0.5, color: colors.gray[600], fontWeight: 500 }}>
ROI
</Typography>
<Typography variant="h6" sx={{ fontWeight: 700, color: 'success.main' }}>
<Typography variant="h5" sx={{ fontWeight: 700, color: colors.mint }}>
{event.roi}%
</Typography>
</Box>
@ -384,49 +411,48 @@ export default function HomePage() {
</Box>
{/* Recent Activity */}
<Box sx={{ mb: 5 }}>
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3, color: 'text.primary' }}>
<Box sx={{ mb: 6 }}>
<Typography variant="h5" sx={{ ...responsiveText.h3, mb: 4 }}>
</Typography>
<Card
elevation={0}
sx={{
borderRadius: 3,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
...cardStyles.default,
}}
>
<CardContent sx={{ p: 4 }}>
<CardContent sx={{ p: { xs: 3, sm: 4 } }}>
{mockActivities.map((activity, index) => (
<Box
key={index}
sx={{
display: 'flex',
gap: 2.5,
pt: index > 0 ? 3 : 0,
mt: index > 0 ? 3 : 0,
gap: 3,
pt: index > 0 ? 3.5 : 0,
mt: index > 0 ? 3.5 : 0,
borderTop: index > 0 ? 1 : 0,
borderColor: 'divider',
borderColor: colors.gray[200],
}}
>
<Box
sx={{
width: 40,
height: 40,
borderRadius: '12px',
bgcolor: 'primary.main',
width: 48,
height: 48,
borderRadius: '14px',
background: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.purpleLight} 100%)`,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
}}
>
<activity.icon sx={{ fontSize: 20, color: 'white' }} />
<activity.icon sx={{ fontSize: 24, color: 'white' }} />
</Box>
<Box sx={{ flex: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 600, color: 'text.primary', mb: 0.5 }}>
<Typography variant="body1" sx={{ fontWeight: 600, color: colors.gray[900], mb: 0.5 }}>
{activity.text}
</Typography>
<Typography variant="caption" sx={{ color: 'text.secondary', fontWeight: 500 }}>
<Typography variant="body2" sx={{ color: colors.gray[500] }}>
{activity.time}
</Typography>
</Box>
@ -441,17 +467,19 @@ export default function HomePage() {
<Fab
sx={{
position: 'fixed',
bottom: 80,
right: 16,
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
transition: 'all 0.2s ease',
bottom: { xs: 80, sm: 90 },
right: { xs: 20, sm: 32 },
width: { xs: 64, sm: 72 },
height: { xs: 64, sm: 72 },
...getGradientButtonStyle('primary'),
boxShadow: '0 10px 25px -5px rgba(167, 139, 250, 0.5), 0 8px 10px -6px rgba(167, 139, 250, 0.5)',
'&:hover': {
background: 'linear-gradient(135deg, #5568d3 0%, #65408b 100%)',
boxShadow: '0 20px 35px -5px rgba(167, 139, 250, 0.6), 0 12px 15px -6px rgba(167, 139, 250, 0.6)',
},
}}
onClick={handleCreateEvent}
>
<Add sx={{ color: 'white' }} />
<Add sx={{ color: 'white', fontSize: { xs: 28, sm: 32 } }} />
</Fab>
</Box>
</>

View File

@ -26,6 +26,7 @@ import {
import { Person, Visibility, VisibilityOff, CheckCircle } from '@mui/icons-material';
import { useAuthStore } from '@/stores/authStore';
import { useUIStore } from '@/stores/uiStore';
import { getGradientButtonStyle, responsiveText, containerStyles } from '@/shared/lib/button-styles';
// 기본 정보 스키마
const basicInfoSchema = z.object({
@ -185,8 +186,8 @@ export default function ProfilePage() {
};
return (
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default', pb: 10 }}>
<Box sx={{ maxWidth: 600, mx: 'auto', px: 3, py: 4 }}>
<Box sx={{ ...containerStyles.page }}>
<Box sx={{ maxWidth: 600, mx: 'auto', px: { xs: 3, sm: 4 }, py: { xs: 3, sm: 4 } }}>
{/* 사용자 정보 섹션 */}
<Paper elevation={0} sx={{ p: 4, mb: 3, textAlign: 'center' }}>
<Avatar
@ -201,7 +202,7 @@ export default function ProfilePage() {
>
<Person sx={{ fontSize: 48 }} />
</Avatar>
<Typography variant="h5" sx={{ fontWeight: 700, mb: 0.5 }}>
<Typography variant="h5" sx={{ ...responsiveText.h3, mb: 0.5 }}>
{user?.name}
</Typography>
<Typography variant="body2" color="text.secondary">
@ -211,7 +212,7 @@ export default function ProfilePage() {
{/* 기본 정보 */}
<Paper elevation={0} sx={{ p: 4, mb: 3 }}>
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, mb: 3 }}>
</Typography>
@ -267,7 +268,7 @@ export default function ProfilePage() {
{/* 매장 정보 */}
<Paper elevation={0} sx={{ p: 4, mb: 3 }}>
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, mb: 3 }}>
</Typography>
@ -336,7 +337,7 @@ export default function ProfilePage() {
{/* 비밀번호 변경 */}
<Paper elevation={0} sx={{ p: 4, mb: 3 }}>
<Typography variant="h6" sx={{ fontWeight: 700, mb: 3 }}>
<Typography variant="h6" sx={{ ...responsiveText.h4, mb: 3 }}>
</Typography>
@ -430,7 +431,13 @@ export default function ProfilePage() {
variant="outlined"
size="large"
onClick={handlePasswordSubmit(onChangePassword)}
sx={{ mt: 1 }}
sx={{
mt: 1,
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
fontWeight: 600,
borderWidth: 2,
}}
>
</Button>
@ -444,7 +451,11 @@ export default function ProfilePage() {
variant="contained"
size="large"
onClick={handleSave}
sx={{ py: 1.5 }}
sx={{
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
...getGradientButtonStyle('primary'),
}}
>
</Button>
@ -454,7 +465,11 @@ export default function ProfilePage() {
size="large"
color="error"
onClick={() => setLogoutDialogOpen(true)}
sx={{ py: 1.5 }}
sx={{
py: { xs: 1.5, sm: 1.75 },
fontSize: { xs: 15, sm: 16 },
fontWeight: 600,
}}
>
</Button>
@ -479,7 +494,11 @@ export default function ProfilePage() {
setSuccessDialogOpen(false);
window.location.reload();
}}
sx={{ minWidth: 120 }}
sx={{
minWidth: 120,
py: { xs: 1.25, sm: 1.5 },
...getGradientButtonStyle('success'),
}}
>
</Button>
@ -495,8 +514,17 @@ export default function ProfilePage() {
</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setLogoutDialogOpen(false)}></Button>
<Button variant="contained" onClick={handleLogout}>
<Button
onClick={() => setLogoutDialogOpen(false)}
sx={{ fontWeight: 600 }}
>
</Button>
<Button
variant="contained"
onClick={handleLogout}
sx={{ ...getGradientButtonStyle('error') }}
>
</Button>
</DialogActions>

View File

@ -0,0 +1,156 @@
// 새로운 디자인 시스템 색상 (참고 이미지 기반)
export const colors = {
mint: '#4DD6D3',
mintLight: '#7EE7E4',
purple: '#A78BFA',
purpleLight: '#C4B5FD',
blue: '#60A5FA',
blueLight: '#93C5FD',
pink: '#F472B6',
pinkLight: '#F9A8D4',
orange: '#FB923C',
orangeLight: '#FDBA74',
gray: {
50: '#F9FAFB',
100: '#F3F4F6',
200: '#E5E7EB',
300: '#D1D5DB',
400: '#9CA3AF',
500: '#6B7280',
600: '#4B5563',
700: '#374151',
800: '#1F2937',
900: '#111827',
},
};
// 공통 버튼 그라디언트 스타일
export const buttonGradients = {
primary: `linear-gradient(135deg, ${colors.purple} 0%, ${colors.blue} 100%)`,
primaryHover: `linear-gradient(135deg, ${colors.purpleLight} 0%, ${colors.blueLight} 100%)`,
secondary: `linear-gradient(135deg, ${colors.mint} 0%, ${colors.blue} 100%)`,
secondaryHover: `linear-gradient(135deg, ${colors.mintLight} 0%, ${colors.blueLight} 100%)`,
success: `linear-gradient(135deg, ${colors.mint} 0%, #34D399 100%)`,
successHover: `linear-gradient(135deg, ${colors.mintLight} 0%, #6EE7B7 100%)`,
error: `linear-gradient(135deg, #EF4444 0%, ${colors.pink} 100%)`,
errorHover: `linear-gradient(135deg, #F87171 0%, ${colors.pinkLight} 100%)`,
warning: `linear-gradient(135deg, ${colors.orange} 0%, #FBBF24 100%)`,
warningHover: `linear-gradient(135deg, ${colors.orangeLight} 0%, #FCD34D 100%)`,
info: `linear-gradient(135deg, ${colors.blue} 0%, ${colors.mint} 100%)`,
infoHover: `linear-gradient(135deg, ${colors.blueLight} 0%, ${colors.mintLight} 100%)`,
};
// 공통 버튼 스타일
export const getGradientButtonStyle = (variant: keyof typeof buttonGradients = 'primary') => ({
background: buttonGradients[variant],
color: 'white',
fontWeight: 600,
borderRadius: 3,
textTransform: 'none' as const,
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
'&:hover': {
background: buttonGradients[`${variant}Hover` as keyof typeof buttonGradients],
transform: 'translateY(-2px)',
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
},
'&:active': {
transform: 'translateY(0)',
},
});
// 공통 카드 스타일
export const cardStyles = {
default: {
borderRadius: 4,
bgcolor: 'white',
boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
border: '1px solid',
borderColor: colors.gray[100],
},
hover: {
'&:hover': {
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
transform: 'translateY(-4px)',
borderColor: colors.gray[200],
},
},
clickable: {
cursor: 'pointer',
borderRadius: 4,
bgcolor: 'white',
boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
border: '1px solid',
borderColor: colors.gray[100],
'&:hover': {
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
transform: 'translateY(-4px)',
borderColor: colors.gray[200],
},
},
};
// 공통 컨테이너 스타일
export const containerStyles = {
page: {
pt: { xs: 7, sm: 8 },
minHeight: '100vh',
bgcolor: colors.gray[50],
pb: 10,
},
section: {
maxWidth: 'lg',
mx: 'auto',
px: { xs: 3, sm: 4, md: 5 },
py: { xs: 4, sm: 5 },
},
centeredForm: {
minHeight: '100vh',
display: 'flex',
flexDirection: 'column' as const,
justifyContent: 'center',
alignItems: 'center',
px: 3,
py: 8,
bgcolor: colors.gray[50],
},
};
// 공통 반응형 텍스트 스타일
export const responsiveText = {
h1: {
fontSize: { xs: '1.875rem', sm: '2.25rem', md: '3rem' },
fontWeight: 700,
color: colors.gray[900],
letterSpacing: '-0.025em',
},
h2: {
fontSize: { xs: '1.5rem', sm: '1.875rem', md: '2.25rem' },
fontWeight: 700,
color: colors.gray[900],
letterSpacing: '-0.025em',
},
h3: {
fontSize: { xs: '1.25rem', sm: '1.5rem', md: '1.875rem' },
fontWeight: 600,
color: colors.gray[900],
letterSpacing: '-0.025em',
},
h4: {
fontSize: { xs: '1.125rem', sm: '1.25rem', md: '1.5rem' },
fontWeight: 600,
color: colors.gray[800],
},
body1: {
fontSize: { xs: '0.875rem', sm: '1rem' },
color: colors.gray[700],
lineHeight: 1.6,
},
body2: {
fontSize: { xs: '0.8125rem', sm: '0.875rem' },
color: colors.gray[600],
lineHeight: 1.5,
},
};