diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b3dd6a3..b69c166 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import { DollarSign, CalendarDays, TrendingUp, BarChart3, Wallet, Settings } from 'lucide-react' +import { DollarSign, CalendarDays, TrendingUp, BarChart3, Wallet, Settings, Menu } from 'lucide-react' import AuthGate, { useAuth } from './components/AuthGate' import { UpdateBanner } from './components/UpdateBanner' import { useVersionCheck } from './hooks/useVersionCheck' @@ -25,13 +25,19 @@ const NAV: { id: Page; label: string; icon: React.ElementType; cap?: string }[] function Shell() { const { user } = useAuth() const [page, setPage] = useState('weekly') + const [menuOpen, setMenuOpen] = useState(false) const hotelName = import.meta.env.VITE_HOTEL_NAME || 'Hotel' const visibleNav = NAV.filter(n => !n.cap || can(user, n.cap)) + function selectPage(id: Page) { + setPage(id) + setMenuOpen(false) + } + return ( -
+
+ {menuOpen &&
setMenuOpen(false)} />} + +
+ + + Wage Costs +
+
{page === 'weekly' && } {page === 'monthly' && } @@ -62,19 +78,6 @@ function Shell() { {page === 'budgets' && } {page === 'settings' && }
- -
) } diff --git a/frontend/src/index.css b/frontend/src/index.css index f7ef6d7..93ad029 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -402,46 +402,59 @@ input[type="text"]:focus { font-size: 14px; } -/* ── Bottom nav (mobile only) ───────────────────────────────────── */ -.bottom-nav { +/* ── Top bar + burger (mobile only) ────────────────────────────── */ +.top-bar { display: none; - position: fixed; - bottom: 0; left: 0; right: 0; + height: var(--topbar-h); background: var(--navy); - border-top: 1px solid rgba(255,255,255,0.1); - z-index: 200; - height: 58px; - justify-content: space-around; - align-items: stretch; -} - -.bottom-nav-item { - display: flex; - flex-direction: column; + color: #fff; align-items: center; - justify-content: center; - gap: 3px; - color: rgba(255,255,255,0.45); - font-size: 10px; - cursor: pointer; - flex: 1; - min-width: 0; - padding: 4px 2px; - transition: color 0.15s; - user-select: none; + padding: 0 12px; + gap: 10px; + flex-shrink: 0; } -.bottom-nav-item.active { color: var(--gold); } -.bottom-nav-item:hover { color: rgba(255,255,255,0.85); } +.top-bar-title { + flex: 1; + font-size: 15px; + font-weight: 600; + color: var(--gold); +} + +.top-bar-burger { + background: none; + border: none; + color: #fff; + cursor: pointer; + display: flex; + align-items: center; + padding: 4px; + flex-shrink: 0; +} + +.menu-backdrop { + position: fixed; + inset: 0; + background: rgba(0,0,0,0.5); + z-index: 199; +} /* ── Mobile breakpoint ──────────────────────────────────────────── */ @media (max-width: 640px) { - .sidebar { display: none; } - .bottom-nav { display: flex; } + .app-shell { flex-direction: column; } + .top-bar { display: flex; } + + .sidebar { + position: fixed; + top: 0; left: 0; bottom: 0; + z-index: 200; + transform: translateX(calc(-1 * var(--sidebar-w))); + transition: transform 0.25s ease; + } + .app-shell.menu-open .sidebar { transform: translateX(0); } .content { padding: 12px; - padding-bottom: 68px; /* clear bottom nav */ } .card {