'use client'; import { useEffect, useState } from 'react'; import { Check, ChevronsUpDown } from 'lucide-react'; import { useQuery } from '@tanstack/react-query'; import { Button } from '@/components/ui/button'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '@/components/ui/command'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { useDebounce } from '@/hooks/use-debounce'; import { apiFetch } from '@/lib/api/client'; import { cn } from '@/lib/utils'; export type OwnerRef = { type: 'client' | 'company'; id: string }; interface OwnerOption { id: string; name?: string | null; fullName?: string | null; } interface OwnerPickerProps { value: OwnerRef | null; onChange: (value: OwnerRef | null) => void; /** Optional placeholder when empty */ placeholder?: string; /** Disable the component */ disabled?: boolean; } export function OwnerPicker({ value, onChange, placeholder = 'Select owner...', disabled, }: OwnerPickerProps) { const [open, setOpen] = useState(false); const [type, setType] = useState<'client' | 'company'>(value?.type ?? 'client'); const [search, setSearch] = useState(''); const debounced = useDebounce(search, 300); // Keep local `type` in sync if value.type changes externally. useEffect(() => { if (value?.type) setType(value.type); }, [value?.type]); const endpoint = type === 'client' ? `/api/v1/clients/options?search=${encodeURIComponent(debounced)}` : `/api/v1/companies/autocomplete?q=${encodeURIComponent(debounced)}`; const { data } = useQuery<{ data: OwnerOption[] }>({ queryKey: ['owner-picker', type, debounced], queryFn: () => apiFetch(endpoint), enabled: open, }); const options = data?.data ?? []; // Selected display label — show entity's name from current options if // available, otherwise a truncated id fallback. const selectedLabel = (() => { if (!value) return placeholder; const match = options.find((o) => o.id === value.id); if (match) { return type === 'client' ? (match.fullName ?? '(unnamed client)') : (match.name ?? '(unnamed company)'); } return value.type === 'client' ? `Client ${value.id.slice(0, 8)}` : `Company ${value.id.slice(0, 8)}`; })(); return ( {/* Type toggle */}
No results. {options.map((opt) => { const label = type === 'client' ? (opt.fullName ?? '(unnamed)') : (opt.name ?? '(unnamed)'); const isSelected = value?.id === opt.id && value?.type === type; return ( { onChange({ type, id: opt.id }); setOpen(false); }} > {label} ); })}
); }