import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { CreditCard, TrendingUp, TrendingDown, Building2, RefreshCw, AlertCircle, Edit2, Check, X, Plus, } from "lucide-react"; import { apiClient } from "../lib/api"; import { formatCurrency, formatDate } from "../lib/utils"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "./ui/card"; import { Button } from "./ui/button"; import { Alert, AlertDescription, AlertTitle } from "./ui/alert"; import AccountsSkeleton from "./AccountsSkeleton"; import type { Account, Balance } from "../types/api"; // Helper function to get status indicator color and styles const getStatusIndicator = (status: string) => { const statusLower = status.toLowerCase(); switch (statusLower) { case "ready": return { color: "bg-green-500", tooltip: "Ready", }; case "pending": return { color: "bg-amber-500", tooltip: "Pending", }; case "error": case "failed": return { color: "bg-destructive", tooltip: "Error", }; case "inactive": return { color: "bg-muted-foreground", tooltip: "Inactive", }; default: return { color: "bg-primary", tooltip: status, }; } }; export default function AccountSettings() { 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 [failedImages, setFailedImages] = useState>(new Set()); const queryClient = useQueryClient(); const updateAccountMutation = useMutation({ mutationFn: ({ id, display_name }: { id: string; display_name: string }) => apiClient.updateAccount(id, { display_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); // Use display_name if available, otherwise fall back to name setEditingName(account.display_name || account.name || ""); }; const handleEditSave = () => { if (editingAccountId && editingName.trim()) { updateAccountMutation.mutate({ id: editingAccountId, display_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.

); } return (
{/* Account Management Section */} Account Management Manage your connected bank accounts and customize their display names {!accounts || accounts.length === 0 ? (

No accounts found

Connect your first bank account to get started with Leggen.

Coming soon: Add new bank connections

) : (
{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 (
{/* Mobile layout - stack vertically */}
{account.logo && !failedImages.has(account.id) ? ( {`${account.institution_id} { console.warn( `Failed to load bank logo for ${account.institution_id}: ${account.logo}`, ); setFailedImages( (prev) => new Set([...prev, account.id]), ); }} /> ) : ( )}
{editingAccountId === account.id ? (
setEditingName(e.target.value) } className="flex-1 px-3 py-1 text-base sm:text-lg font-medium border border-input rounded-md bg-background focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring" placeholder="Custom account name" name="search" autoComplete="off" onKeyDown={(e) => { if (e.key === "Enter") handleEditSave(); if (e.key === "Escape") handleEditCancel(); }} autoFocus />

{account.institution_id}

) : (

{account.display_name || account.name || "Unnamed Account"}

{account.institution_id}

{account.iban && (

IBAN: {account.iban}

)}
)}
{/* Balance and date section */}
{/* Mobile: date/status on left, balance on right */} {/* Desktop: balance on top, date/status on bottom */} {/* Date and status indicator - left on mobile, bottom on desktop */}
{/* Tooltip */}
{getStatusIndicator(account.status).tooltip}

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

{/* Balance - right on mobile, top on desktop */}
{isPositive ? ( ) : ( )}

{formatCurrency(balance, currency)}

); })}
)}
{/* Add Bank Section (Future Feature) */} Add New Bank Account Connect additional bank accounts to track all your finances in one place

Bank connection functionality is coming soon. Stay tuned for updates!

); }