import { index as indexBanks } from '@/actions/App/Http/Controllers/Settings/BankController'; import { Button } from '@/components/ui/button'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from '@/components/ui/command'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover'; import { cn } from '@/lib/utils'; import { type Bank } from '@/types/account'; import { __ } from '@/utils/i18n'; import { Check, ChevronsUpDown, Plus } from 'lucide-react'; import { useCallback, useEffect, useState } from 'react'; interface BankComboboxProps { value: number | null; onValueChange: (value: number | null) => void; defaultBank?: Bank; onCreateCustomBank?: (searchQuery: string) => void; } const bankCache = new Map(); export function BankCombobox({ value, onValueChange, defaultBank, onCreateCustomBank, }: BankComboboxProps) { const [open, setOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [banks, setBanks] = useState( defaultBank ? [defaultBank] : [], ); const [isLoading, setIsLoading] = useState(false); const [selectedBank, setSelectedBank] = useState( defaultBank || null, ); const searchBanks = useCallback( async (query: string) => { if (query.length < 3) { setBanks(defaultBank ? [defaultBank] : []); return; } if (bankCache.has(query)) { setBanks(bankCache.get(query)!); return; } setIsLoading(true); try { const response = await fetch( indexBanks.url({ query: { search: query } }), { headers: { Accept: 'application/json', }, }, ); if (!response.ok) { throw new Error('Failed to search banks'); } const data = await response.json(); const results = data.data || data; bankCache.set(query, results); setBanks(results); } catch (error) { console.error('Failed to search banks:', error); setBanks([]); } finally { setIsLoading(false); } }, [defaultBank], ); useEffect(() => { const debounceTimer = setTimeout(() => { searchBanks(searchQuery); }, 300); return () => clearTimeout(debounceTimer); }, [searchQuery, searchBanks]); const handleSelect = (bank: Bank) => { setSelectedBank(bank); onValueChange(bank.id); setOpen(false); }; return ( 1}> {isLoading ? __('Searching...') : searchQuery.length < 3 ? __('Type at least 3 characters to search') : __('No bank found.')} {banks.map((bank) => ( handleSelect(bank)} >
{bank.logo ? ( {bank.name} ) : (
)} {bank.name}
))} {onCreateCustomBank && searchQuery.length >= 3 && !isLoading && banks.length < 3 && ( <> { onCreateCustomBank(searchQuery); setOpen(false); }} > {__('Create "')} {searchQuery}" )} ); }