wulf-pulse/app/mobile/layout.tsx
lorentz 7a095fbe53 feat(02-02): rewrite mobile layout to wire HeaderBar + BottomNav + MoreDrawer
- Replace legacy 3-tab layout with new shell components from Plan 01
- Single useState(drawerOpen) shared between avatar and More button triggers
- SHELL-05: main content padded pb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))]
- max-w-lg mx-auto container, no legacy /mobile/nav reference
2026-05-03 16:09:35 -04:00

37 lines
1.4 KiB
TypeScript

'use client';
/* Mobile shell — phase 02 (SHELL-01, SHELL-05).
*
* Header: <HeaderBar /> (sticky, brand + Bell + avatar)
* Body: <main> (scrollable, padded so content clears the bottom nav)
* Foot: <BottomNav /> (fixed, 4 tabs + More)
* Drawer: <MoreDrawer /> opened from BOTH the header avatar and the More cell.
*
* The drawer's open state lives here so a single Sheet instance is shared
* between the two triggers — no duplicate Sheets, no prop-drilling sagas. */
import { useState } from 'react';
import { HeaderBar } from '@/components/mobile/HeaderBar';
import { BottomNav } from '@/components/mobile/BottomNav';
import { MoreDrawer } from '@/components/mobile/MoreDrawer';
export default function MobileLayout({ children }: { children: React.ReactNode }) {
const [drawerOpen, setDrawerOpen] = useState(false);
return (
<div className="flex flex-col min-h-screen bg-background max-w-lg mx-auto">
<HeaderBar onAvatarClick={() => setDrawerOpen(true)} />
{/* SHELL-05: scrollable content area; bottom padding = bottom-nav (h-16
= 64px = pb-16) plus the device safe-area inset, so content never
hides under the bar. */}
<main className="flex-1 overflow-y-auto pb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))]">
{children}
</main>
<BottomNav onMoreClick={() => setDrawerOpen(true)} />
<MoreDrawer open={drawerOpen} onOpenChange={setDrawerOpen} />
</div>
);
}