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 && (
+
+
+
+ )}
+
+
+ );
+}