'use client' import { useEffect, useMemo, useState } from 'react' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { useToast } from '@/components/ui/use-toast' import { Loader2 } from 'lucide-react' import type { StoredAccount } from '../types' interface AccountPickerDialogProps { open: boolean onOpenChange: (open: boolean) => void connectionId: string bankName: string accounts: StoredAccount[] // True when the connection is still in pending_selection — closing without // saving is allowed but the user is reminded that no sync runs until they // confirm. isInitialSelection: boolean onSaved: () => void } export function AccountPickerDialog({ open, onOpenChange, connectionId, bankName, accounts, isInitialSelection, onSaved, }: AccountPickerDialogProps) { const { toast } = useToast() const [selected, setSelected] = useState>(new Set()) const [isSaving, setIsSaving] = useState(false) useEffect(() => { if (open) { // Start the dialog reflecting the current state. Accounts without an // explicit enabled flag are treated as enabled (back-compat). const initial = new Set( accounts.filter(a => a.enabled !== false).map(a => a.uid) ) setSelected(initial) } }, [open, accounts]) const allSelected = accounts.length > 0 && selected.size === accounts.length const noneSelected = selected.size === 0 const sortedAccounts = useMemo( () => [...accounts].sort((a, b) => (a.name || a.iban || '').localeCompare(b.name || b.iban || '')), [accounts] ) function toggle(uid: string) { setSelected(prev => { const next = new Set(prev) if (next.has(uid)) next.delete(uid) else next.add(uid) return next }) } function selectAll() { setSelected(new Set(accounts.map(a => a.uid))) } function selectNone() { setSelected(new Set()) } async function handleSave() { if (noneSelected) { toast({ title: 'Välj minst ett konto', description: 'Avmarkera alla konton och koppla bort banken istället om inga konton ska synkas.', variant: 'destructive', }) return } setIsSaving(true) try { const response = await fetch('/api/extensions/ext/enable-banking/accounts', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ connection_id: connectionId, enabled_uids: Array.from(selected), }), }) const data = await response.json() if (!response.ok) { throw new Error(data.error || 'Kunde inte spara kontoval') } toast({ title: 'Kontoval sparat', description: `${data.enabled_count} av ${data.total_count} konton kommer synkas.`, }) onOpenChange(false) onSaved() } catch (error) { toast({ title: 'Fel', description: error instanceof Error ? error.message : 'Kunde inte spara kontoval', variant: 'destructive', }) } finally { setIsSaving(false) } } return ( Välj konton att synka — {bankName} {isInitialSelection ? 'Banken har gett åtkomst till följande konton. Avmarkera de konton du inte vill synka transaktioner från. Inga transaktioner hämtas innan du sparar.' : 'Justera vilka konton som ska synkas. Konton du avmarkerar slutar synkas från nästa körning; redan importerade transaktioner ligger kvar.'}
{selected.size} av {accounts.length} valda
·
{sortedAccounts.map(account => { const isChecked = selected.has(account.uid) return ( ) })}
) }