feat(mobile): show entity name in mobile topbar on detail pages

Detail pages (clients, yachts, companies, berths, invoices, expenses)
now push their entity name + a back-button toggle to the mobile
topbar via useMobileChrome, replacing the URL UUID fallback that was
rendering before.

Supporting changes:
  - useMobileChrome() no longer throws when called outside the
    MobileLayoutProvider — desktop-tree consumers get a no-op
    setChrome so callers don't have to branch on shell type.
  - setChrome is now stable across renders (useCallback) so callers'
    useEffect dependency arrays don't infinite-loop.
  - DetailPageShell now also pushes its entityName + cleans up on
    unmount, and hides its desktop-only sticky header on mobile so it
    doesn't double up with the topbar (no current callers, prep for
    Phase 4 migration).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt Ciaccio
2026-05-01 15:46:32 +02:00
parent 9eadaf035e
commit 7e8110b2ff
8 changed files with 101 additions and 20 deletions

View File

@@ -1,9 +1,11 @@
'use client';
import { useEffect } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useParams } from 'next/navigation';
import { DetailLayout } from '@/components/shared/detail-layout';
import { useMobileChrome } from '@/components/layout/mobile/mobile-layout-provider';
import { CompanyDetailHeader } from '@/components/companies/company-detail-header';
import { getCompanyTabs } from '@/components/companies/company-tabs';
import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation';
@@ -45,6 +47,13 @@ export function CompanyDetail({ companyId, currentUserId }: CompanyDetailProps)
apiFetch<{ data: CompanyData }>(`/api/v1/companies/${companyId}`).then((r) => r.data),
});
const { setChrome } = useMobileChrome();
const titleForChrome: string | null = data?.name ?? null;
useEffect(() => {
setChrome({ title: titleForChrome, showBackButton: true });
return () => setChrome({ title: null, showBackButton: false });
}, [titleForChrome, setChrome]);
useRealtimeInvalidation({
'company:updated': [['companies', companyId]],
'company:archived': [['companies', companyId]],