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,8 +1,10 @@
'use client';
import { useEffect } from 'react';
import { useQuery } from '@tanstack/react-query';
import { DetailLayout } from '@/components/shared/detail-layout';
import { useMobileChrome } from '@/components/layout/mobile/mobile-layout-provider';
import { apiFetch } from '@/lib/api/client';
import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation';
import { BerthDetailHeader } from './berth-detail-header';
@@ -26,6 +28,13 @@ export function BerthDetail({ berthId }: BerthDetailProps) {
'berth:statusChanged': [['berth', berthId]],
});
const { setChrome } = useMobileChrome();
const titleForChrome: string | null = data?.mooringNumber ?? null;
useEffect(() => {
setChrome({ title: titleForChrome, showBackButton: true });
return () => setChrome({ title: null, showBackButton: false });
}, [titleForChrome, setChrome]);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const berth = data as any;