'use client' import { useCallback, useEffect, useMemo, useState } from 'react' import { Input } from '@/components/ui/input' import { Button } from '@/components/ui/button' import { Loader2, Search, RefreshCw } from 'lucide-react' import { cn } from '@/lib/utils' export interface Bank { name: string country: string logo?: string bic?: string } interface BankSelectorProps { onConnect: (bank: Bank) => void isConnecting?: boolean connectingBankName?: string | null className?: string } const POPULAR_BANK_NAMES = [ 'Nordea', 'SEB', 'Swedbank', 'Handelsbanken', 'Länsförsäkringar', 'Skandia', 'Danske Bank', ] export function BankSelector({ onConnect, isConnecting = false, connectingBankName = null, className, }: BankSelectorProps) { const [banks, setBanks] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [searchQuery, setSearchQuery] = useState('') const fetchBanks = useCallback(async () => { setLoading(true) setError(null) try { const res = await fetch('/api/extensions/ext/enable-banking/banks') if (!res.ok) throw new Error('Kunde inte hämta banklistan') const data = await res.json() setBanks(data.banks || []) } catch (e) { setError(e instanceof Error ? e.message : 'Något gick fel') } finally { setLoading(false) } }, []) useEffect(() => { fetchBanks() }, [fetchBanks]) const popularBanks = useMemo( () => POPULAR_BANK_NAMES.map((name) => banks.find((b) => b.name === name) ).filter((b): b is Bank => b !== undefined), [banks] ) const filteredBanks = useMemo(() => { if (!searchQuery.trim()) { // Show all banks except popular ones const popularSet = new Set(POPULAR_BANK_NAMES) return banks .filter((b) => !popularSet.has(b.name)) .sort((a, b) => a.name.localeCompare(b.name, 'sv')) } const q = searchQuery.toLowerCase() return banks .filter((b) => b.name.toLowerCase().includes(q)) .sort((a, b) => a.name.localeCompare(b.name, 'sv')) }, [banks, searchQuery]) if (loading) { return (
{/* Popular banks skeleton */}
{Array.from({ length: 7 }).map((_, i) => (
))}
{Array.from({ length: 4 }).map((_, i) => (
))}
) } if (error) { return (

{error}

) } return (
{/* Popular banks grid */} {popularBanks.length > 0 && !searchQuery.trim() && (
{popularBanks.map((bank) => { const connecting = isConnecting && connectingBankName === bank.name return ( ) })}
)} {/* Search */}
setSearchQuery(e.target.value)} placeholder="Sök bland alla banker..." className="pl-9 h-9" />
{/* Bank list */}
{filteredBanks.length === 0 ? (

{searchQuery.trim() ? 'Inga banker matchar sökningen' : 'Inga banker tillgängliga'}

) : ( filteredBanks.map((bank) => { const connecting = isConnecting && connectingBankName === bank.name return ( ) }) )}
) }