- 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
37 lines
1.4 KiB
TypeScript
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>
|
|
);
|
|
}
|