Files
sofa/app/(pages)/layout.tsx
T
jake 1328619c43 Merge MobileTabBar into nav-bar and refactor nav indicator to ResizeObserver
- Delete `components/mobile-tab-bar.tsx`; co-locate `MobileTabBar` export
  in `nav-bar.tsx` so both nav components share helpers
- Extract `isLinkActive` helper used by both desktop and mobile nav;
  fixes `/dashboard` active match when pathname is `/`
- Replace `layoutId`-based Framer Motion indicators with a
  `useActiveIndicator` hook that measures DOM rects via `ResizeObserver`,
  animating `left`/`width` directly — avoids cross-tree layout ID
  conflicts and correctly handles breakpoint visibility changes
- Add `aria-current="page"`, `aria-label="Primary"`, and
  `focus-visible` ring styles to nav links and tab bar items
- Update layout import to pull both exports from `@/components/nav-bar`
2026-03-08 12:10:28 -04:00

51 lines
1.8 KiB
TypeScript

import { redirect } from "next/navigation";
import { Suspense } from "react";
import { CommandPalette } from "@/components/command-palette";
import { MobileTabBar, NavBar } from "@/components/nav-bar";
import { ProgressProvider } from "@/components/navigation-progress";
import { UpdateToast } from "@/components/update-toast";
import { getSession } from "@/lib/auth/session";
export default function PagesLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<Suspense>
<ProgressProvider>
<AuthenticatedShell>{children}</AuthenticatedShell>
</ProgressProvider>
</Suspense>
);
}
async function AuthenticatedShell({ children }: { children: React.ReactNode }) {
const session = await getSession();
if (!session) redirect("/login");
return (
<>
<div className="relative z-0 min-h-screen pb-[calc(3.5rem+env(safe-area-inset-bottom))] sm:pb-0">
<NavBar
userName={session.user.name}
userEmail={session.user.email}
userImage={session.user.image || undefined}
userRole={session.user.role || undefined}
/>
{/* Ambient glow — smaller on mobile to add warmth without overwhelming */}
<div className="pointer-events-none fixed top-1/4 left-1/2 h-[600px] w-[800px] -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary/3 blur-[200px]" />
<main
id="main-content"
className="relative mx-auto max-w-6xl py-6 pr-[max(1rem,env(safe-area-inset-right))] pl-[max(1rem,env(safe-area-inset-left))] sm:pr-[max(1.5rem,env(safe-area-inset-right))] sm:pl-[max(1.5rem,env(safe-area-inset-left))]"
>
{children}
</main>
</div>
<MobileTabBar />
<CommandPalette />
{session.user.role === "admin" && <UpdateToast />}
</>
);
}