fromis_9/frontend/src/components/mobile/Layout.jsx

73 lines
2.7 KiB
React
Raw Normal View History

import { NavLink, useLocation } from 'react-router-dom';
import { Home, Users, Disc3, Calendar } from 'lucide-react';
// 모바일 헤더 컴포넌트
function MobileHeader({ title }) {
return (
<header className="bg-white shadow-sm sticky top-0 z-50">
<div className="flex items-center justify-center h-14 px-4">
{title ? (
<span className="text-xl font-bold text-primary">{title}</span>
) : (
<NavLink to="/" className="text-xl font-bold text-primary">
fromis_9
</NavLink>
)}
</div>
</header>
);
}
// 모바일 하단 네비게이션
function MobileBottomNav() {
const location = useLocation();
const navItems = [
{ path: '/', label: '홈', icon: Home },
{ path: '/members', label: '멤버', icon: Users },
{ path: '/album', label: '앨범', icon: Disc3 },
{ path: '/schedule', label: '일정', icon: Calendar },
];
return (
<nav className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 z-50 safe-area-bottom">
<div className="flex items-center justify-around h-16">
{navItems.map((item) => {
const Icon = item.icon;
const isActive = location.pathname === item.path ||
(item.path !== '/' && location.pathname.startsWith(item.path));
return (
<NavLink
key={item.path}
to={item.path}
className={`flex flex-col items-center justify-center gap-1 w-full h-full transition-colors ${
isActive ? 'text-primary' : 'text-gray-400'
}`}
>
<Icon size={22} strokeWidth={isActive ? 2.5 : 2} />
<span className="text-xs font-medium">{item.label}</span>
</NavLink>
);
})}
</div>
</nav>
);
}
// 모바일 레이아웃 컴포넌트
// pageTitle: 헤더에 표시할 제목 (없으면 fromis_9)
// hideHeader: true면 헤더 숨김 (일정 페이지처럼 자체 헤더가 있는 경우)
function MobileLayout({ children, pageTitle, hideHeader = false }) {
return (
<div className="min-h-screen flex flex-col bg-gray-50">
{!hideHeader && <MobileHeader title={pageTitle} />}
<main className={`flex-1 pb-20 ${hideHeader ? 'pt-0' : ''}`}>{children}</main>
<MobileBottomNav />
</div>
);
}
export default MobileLayout;