import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { CreditCard, TrendingUp, TrendingDown, Building2, RefreshCw, AlertCircle, Edit2, Check, X, } from "lucide-react"; import { apiClient } from "../lib/api"; import { formatCurrency, formatDate } from "../lib/utils"; import LoadingSpinner from "./LoadingSpinner"; import type { Account, Balance } from "../types/api"; export default function AccountsOverview() { const { data: accounts, isLoading: accountsLoading, error: accountsError, refetch: refetchAccounts, } = useQuery({ queryKey: ["accounts"], queryFn: apiClient.getAccounts, }); const { data: balances } = useQuery({ queryKey: ["balances"], queryFn: () => apiClient.getBalances(), }); const [editingAccountId, setEditingAccountId] = useState(null); const [editingName, setEditingName] = useState(""); const queryClient = useQueryClient(); const updateAccountMutation = useMutation({ mutationFn: ({ id, name }: { id: string; name: string }) => apiClient.updateAccount(id, { name }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["accounts"] }); setEditingAccountId(null); setEditingName(""); }, onError: (error) => { console.error("Failed to update account:", error); }, }); const handleEditStart = (account: Account) => { setEditingAccountId(account.id); setEditingName(account.name || ""); }; const handleEditSave = () => { if (editingAccountId && editingName.trim()) { updateAccountMutation.mutate({ id: editingAccountId, name: editingName.trim(), }); } }; const handleEditCancel = () => { setEditingAccountId(null); setEditingName(""); }; if (accountsLoading) { return (
); } if (accountsError) { return (

Failed to load accounts

Unable to connect to the Leggen API. Please check your configuration and ensure the API server is running.

); } const totalBalance = accounts?.reduce((sum, account) => { // Get the first available balance from the balances array const primaryBalance = account.balances?.[0]?.amount || 0; return sum + primaryBalance; }, 0) || 0; const totalAccounts = accounts?.length || 0; const uniqueBanks = new Set(accounts?.map((acc) => acc.institution_id) || []) .size; return (
{/* Summary Cards */}

Total Balance

{formatCurrency(totalBalance)}

Total Accounts

{totalAccounts}

Connected Banks

{uniqueBanks}

{/* Accounts List */}

Bank Accounts

Manage your connected bank accounts

{!accounts || accounts.length === 0 ? (

No accounts found

Connect your first bank account to get started with Leggen.

) : (
{accounts.map((account) => { // Get balance from account's balances array or fallback to balances query const accountBalance = account.balances?.[0]; const fallbackBalance = balances?.find( (b) => b.account_id === account.id, ); const balance = accountBalance?.amount || fallbackBalance?.balance_amount || 0; const currency = accountBalance?.currency || fallbackBalance?.currency || account.currency || "EUR"; const isPositive = balance >= 0; return (
{editingAccountId === account.id ? (
setEditingName(e.target.value)} className="flex-1 px-3 py-1 text-lg font-medium border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Account name" name="search" autoComplete="off" onKeyDown={(e) => { if (e.key === "Enter") handleEditSave(); if (e.key === "Escape") handleEditCancel(); }} autoFocus />

{account.institution_id} • {account.status}

) : (

{account.name || "Unnamed Account"}

{account.institution_id} • {account.status}

{account.iban && (

IBAN: {account.iban}

)}
)}
{isPositive ? ( ) : ( )}

{formatCurrency(balance, currency)}

Updated{" "} {formatDate(account.last_accessed || account.created)}

); })}
)}
); }