import { useEffect, useState, useMemo } from 'react'; import { bankAccountApi } from '../api/resources'; import type { BankAccount } from '../types/api'; import ConfirmDialog from '../components/ConfirmDialog'; import { useToast } from '../components/Toast'; import SortableHeader from '../components/SortableHeader'; import { useSort } from '../hooks/useSort'; type ViewMode = 'list' | 'detail' | 'edit' | 'create'; interface FormData { name: string; holder: string; iban: string; bankName: string; swiftBic: string; currency: string; isDefault: boolean; description: string; } const emptyForm = (): FormData => ({ name: '', holder: '', iban: '', bankName: '', swiftBic: '', currency: 'EUR', isDefault: false, description: '', }); function formatIban(iban: string): string { const cleaned = iban.replace(/\s+/g, '').toUpperCase(); return cleaned.replace(/(.{4})/g, '$1 ').trim(); } export default function BankAccounts() { const [viewMode, setViewMode] = useState('list'); const [items, setItems] = useState([]); const [selected, setSelected] = useState(null); const [form, setForm] = useState(emptyForm()); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [deleteTarget, setDeleteTarget] = useState(null); const { toast } = useToast(); const { sorted, sort, toggleSort } = useSort(items, 'name'); // -- Bank name autocomplete options -- const bankNames = useMemo(() => { const names = new Set(); items.forEach((item) => { if (item.bankName) names.add(item.bankName); }); return [...names].sort(); }, [items]); const loadList = () => { setLoading(true); bankAccountApi.getAll({ all: true }) .then((resp) => setItems(resp.data)) .catch(() => toast('Error al cargar cuentas bancarias', 'error')) .finally(() => setLoading(false)); }; useEffect(() => { loadList(); }, []); const goToDetail = (item: BankAccount) => { setSelected(item); setViewMode('detail'); }; const goToCreate = () => { setSelected(null); setForm(emptyForm()); setViewMode('create'); }; const goToEdit = (item: BankAccount) => { setSelected(item); setForm({ name: item.name, holder: item.holder, iban: item.iban, bankName: item.bankName ?? '', swiftBic: item.swiftBic ?? '', currency: item.currency, isDefault: item.isDefault, description: item.description ?? '', }); setViewMode('edit'); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!form.name.trim() || !form.holder.trim() || !form.iban.trim()) { toast('Completa los campos obligatorios', 'warning'); return; } setSaving(true); try { const payload: Record = { name: form.name, holder: form.holder, iban: form.iban.replace(/\s+/g, '').toUpperCase(), bankName: form.bankName || null, swiftBic: form.swiftBic || null, currency: form.currency, isDefault: form.isDefault, description: form.description || null, }; if (viewMode === 'edit' && selected) { await bankAccountApi.update(selected.id, payload as Partial); toast('Cuenta actualizada', 'success'); } else { await bankAccountApi.create(payload as Partial); toast('Cuenta creada', 'success'); } setViewMode('list'); loadList(); } catch { toast('Error al guardar la cuenta', 'error'); } finally { setSaving(false); } }; const handleDelete = async () => { if (!deleteTarget) return; try { await bankAccountApi.remove(deleteTarget.id); toast('Cuenta desactivada', 'success'); setDeleteTarget(null); loadList(); if (viewMode === 'detail') setViewMode('list'); } catch { toast('Error al eliminar la cuenta', 'error'); } }; if (viewMode === 'list') { return ( <>

Cuentas Bancarias

Gestiona las cuentas bancarias de la empresa

{loading ? (
Cargando...
) : items.length === 0 ? (

No hay cuentas bancarias

Añade una cuenta bancaria para asociarla a gastos e ingresos.

) : (
{sorted.map((acc) => ( ))}
Acciones
{acc.name} {acc.isDefault && Ppal} {acc.bankName ?? '-'} {formatIban(acc.iban)} {acc.holder} {acc.currency} {acc.active ? Activa : Inactiva}
{acc.active && ( )}
)}
setDeleteTarget(null)} /> ); } if (viewMode === 'detail' && selected) { return ( <>

{selected.name}

Nombre {selected.name}
Banco {selected.bankName ?? '-'}
IBAN {formatIban(selected.iban)}
SWIFT/BIC {selected.swiftBic ?? '-'}
Titular {selected.holder}
Divisa {selected.currency}
Por Defecto {selected.isDefault ? 'Sí' : 'No'}
Estado {selected.active ? Activa : Inactiva}
{selected.description && (
Descripción {selected.description}
)}
); } // Create / Edit form const isEdit = viewMode === 'edit'; return ( <>

{isEdit ? `Editar: ${selected?.name}` : 'Nueva Cuenta Bancaria'}

setForm({ ...form, name: e.target.value })} required placeholder="Ej: BBVA Empresas" />
setForm({ ...form, holder: e.target.value })} required placeholder="Nombre del titular" />
setForm({ ...form, iban: e.target.value })} required placeholder="ES00 0000 0000 00 0000000000" />
setForm({ ...form, bankName: e.target.value })} placeholder="Ej: Banco Santander" />
setForm({ ...form, swiftBic: e.target.value })} placeholder="Ej: BSCHESMM" />