'use client'; import { usePathname, useRouter } from 'next/navigation'; import { useTranslations } from 'next-intl'; import { useEffect, type ReactNode } from 'react'; import { Button, Skeleton, cn } from '@sport/ui'; import { Link } from '@/i18n/navigation'; import { routes } from '@/lib/routes'; import { useCustomer } from './customer-provider'; const NAV = [ { href: routes.account(), key: 'overview' }, { href: routes.accountOrders(), key: 'orders' }, { href: routes.accountAddresses(), key: 'addresses' }, { href: routes.accountWishlist(), key: 'wishlist' }, { href: routes.accountProfile(), key: 'profile' }, ] as const; /** * The signed-in shell around every /account page. * * Guards on the client rather than in middleware, because the session lives in * an httpOnly cookie that only the API can validate — middleware would have to * call the API on every navigation to learn anything the provider already * knows. The API re-checks every request regardless, so this is presentation: * it decides what to *show*, never what is *allowed*. */ export function AccountShell({ children }: { children: ReactNode }) { const t = useTranslations('account'); const { customer, status, signOut } = useCustomer(); const router = useRouter(); const pathname = usePathname(); useEffect(() => { if (status !== 'anonymous') return; // `next` so signing in returns them to the page they asked for, rather // than dumping everyone on the account overview. router.replace(`${routes.signIn()}?next=${encodeURIComponent(pathname)}`); }, [status, router, pathname]); if (status === 'loading') { return (
); } // The redirect above is already in flight; rendering nothing avoids a flash // of the empty account page on the way out. if (!customer) return null; return (
{children}
); }