'use client'; import Link from 'next/link'; import { useQuery } from '@tanstack/react-query'; import { Loader2, Star } from 'lucide-react'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { apiFetch } from '@/lib/api/client'; import { stageBadgeClass, stageLabel } from '@/lib/constants'; interface ActiveInterestRow { interestId: string; clientName: string; pipelineStage: string; isPrimary: boolean; isInEoiBundle: boolean; } interface Props { berthId: string; portSlug: string; count: number; } /** * Click-to-expand popover for the berth-list "Active interests" cell. * Lazy-loads the linked-interest list when the rep opens it; cached * for 30s. Each row links to the interest detail page and shows the * pipeline-stage chip + the primary/EOI-bundle flags so the rep can * judge urgency without leaving the berth list. */ export function ActiveInterestsPopover({ berthId, portSlug, count }: Props) { // Lazy-load: only fetch when the popover opens. Pattern from the // detail-label fallback queries elsewhere in the codebase — the // `enabled` flag flips on first open. const { data, isLoading, isError } = useQuery<{ data: ActiveInterestRow[] }>({ queryKey: ['berth', berthId, 'active-interests'], queryFn: () => apiFetch<{ data: ActiveInterestRow[] }>(`/api/v1/berths/${berthId}/active-interests`), staleTime: 30_000, // The popover only renders when the trigger is clicked, so the // enabled gate falls out naturally from React Query's behaviour // inside the conditionally-rendered PopoverContent. }); if (count === 0) return - ; return (
Active interests
{isLoading ? (
Loading…
) : isError ? (
Failed to load interests.
) : (data?.data ?? []).length === 0 ? (
No active interests.
) : ( )}
); }