diff --git a/src/app/(main)/analytics/page.tsx b/src/app/(main)/analytics/page.tsx index c62f806..0a0cef5 100644 --- a/src/app/(main)/analytics/page.tsx +++ b/src/app/(main)/analytics/page.tsx @@ -15,6 +15,7 @@ import { Payments, People, } from '@mui/icons-material'; +import Header from '@/components/layout/Header'; // Mock 데이터 const mockAnalyticsData = { @@ -95,8 +96,10 @@ export default function AnalyticsPage() { mockAnalyticsData; return ( - - + <> +
+ + {/* Title with Real-time Indicator */} - + + ); } diff --git a/src/app/(main)/events/page.tsx b/src/app/(main)/events/page.tsx index d379e37..0315f45 100644 --- a/src/app/(main)/events/page.tsx +++ b/src/app/(main)/events/page.tsx @@ -19,6 +19,7 @@ import { Grid, } from '@mui/material'; import { Search, FilterList } from '@mui/icons-material'; +import Header from '@/components/layout/Header'; // Mock 데이터 const mockEvents = [ @@ -140,8 +141,10 @@ export default function EventsPage() { }; return ( - - + <> +
+ + {/* Search Section */} )} - + + ); } diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx new file mode 100644 index 0000000..3eb5704 --- /dev/null +++ b/src/app/(main)/layout.tsx @@ -0,0 +1,11 @@ +import { Box } from '@mui/material'; +import BottomNavigation from '@/components/layout/BottomNavigation'; + +export default function MainLayout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + + ); +} diff --git a/src/app/page.tsx b/src/app/(main)/page.tsx similarity index 94% rename from src/app/page.tsx rename to src/app/(main)/page.tsx index 702266a..0a21128 100644 --- a/src/app/page.tsx +++ b/src/app/(main)/page.tsx @@ -21,6 +21,7 @@ import { Edit, CheckCircle, } from '@mui/icons-material'; +import Header from '@/components/layout/Header'; // Mock 사용자 데이터 (API 연동 전까지 임시 사용) const mockUser = { @@ -79,14 +80,16 @@ export default function HomePage() { }; return ( - - + <> +
+ + {/* Welcome Section */} - - - + sx={{ + position: 'fixed', + bottom: 80, + right: 16, + background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', + transition: 'all 0.2s ease', + '&:hover': { + background: 'linear-gradient(135deg, #5568d3 0%, #65408b 100%)', + }, + }} + onClick={handleCreateEvent} + > + + + + ); } diff --git a/src/components/layout/BottomNavigation.tsx b/src/components/layout/BottomNavigation.tsx new file mode 100644 index 0000000..10e79a2 --- /dev/null +++ b/src/components/layout/BottomNavigation.tsx @@ -0,0 +1,115 @@ +'use client'; + +import { usePathname, useRouter } from 'next/navigation'; +import { BottomNavigation as MuiBottomNavigation, BottomNavigationAction, Paper } from '@mui/material'; +import { Home, Celebration, Analytics, Person } from '@mui/icons-material'; + +export default function BottomNavigation() { + const pathname = usePathname(); + const router = useRouter(); + + // Determine current value based on pathname + const getCurrentValue = () => { + if (pathname === '/' || pathname === '/dashboard') return 'home'; + if (pathname.startsWith('/events')) return 'events'; + if (pathname.startsWith('/analytics')) return 'analytics'; + if (pathname.startsWith('/profile')) return 'profile'; + return 'home'; + }; + + const value = getCurrentValue(); + + const handleChange = (_event: React.SyntheticEvent, newValue: string) => { + switch (newValue) { + case 'home': + router.push('/'); + break; + case 'events': + router.push('/events'); + break; + case 'analytics': + router.push('/analytics'); + break; + case 'profile': + router.push('/profile'); + break; + } + }; + + return ( + theme.zIndex.drawer + 1, + borderTop: '1px solid', + borderColor: 'divider', + }} + elevation={3} + > + + } + sx={{ + '& .MuiSvgIcon-root': { + fontSize: { xs: 24, sm: 28 }, + }, + }} + /> + } + sx={{ + '& .MuiSvgIcon-root': { + fontSize: { xs: 24, sm: 28 }, + }, + }} + /> + } + sx={{ + '& .MuiSvgIcon-root': { + fontSize: { xs: 24, sm: 28 }, + }, + }} + /> + } + sx={{ + '& .MuiSvgIcon-root': { + fontSize: { xs: 24, sm: 28 }, + }, + }} + /> + + + ); +} diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx new file mode 100644 index 0000000..ef0d5b7 --- /dev/null +++ b/src/components/layout/Header.tsx @@ -0,0 +1,114 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import { AppBar, Toolbar, IconButton, Typography, Box } from '@mui/material'; +import { ArrowBack, Menu, AccountCircle } from '@mui/icons-material'; + +interface HeaderProps { + title?: string; + showBack?: boolean; + showMenu?: boolean; + showProfile?: boolean; + onBackClick?: () => void; + onMenuClick?: () => void; + onProfileClick?: () => void; +} + +export default function Header({ + title = '', + showBack = true, + showMenu = false, + showProfile = true, + onBackClick, + onMenuClick, + onProfileClick, +}: HeaderProps) { + const router = useRouter(); + + const handleBackClick = () => { + if (onBackClick) { + onBackClick(); + } else { + router.back(); + } + }; + + const handleProfileClick = () => { + if (onProfileClick) { + onProfileClick(); + } else { + router.push('/profile'); + } + }; + + return ( + theme.zIndex.drawer + 1, + }} + > + + {/* Left Section */} + + {showMenu && ( + + + + )} + {showBack && ( + + + + )} + {title && ( + + {title} + + )} + + + {/* Right Section */} + {showProfile && ( + + + + )} + + + ); +}