'use client' import { useState } from 'react' import { Button } from '@/components/ui/button' import { formatDate } from '@/lib/utils' import { getDaysUntilExpiry, isConsentExpiringSoon } from '../lib/api-client' import Link from 'next/link' import { CreditCard, AlertTriangle, RefreshCw, Trash2, Loader2, CheckCircle, XCircle, Upload, } from 'lucide-react' import type { BankConnection } from '@/types' interface BankConnectionStatusProps { connection: BankConnection onSync: (connectionId: string) => void onDisconnect: (connectionId: string) => void onReconnect?: (bank: { name: string; country: string }) => void isSyncing?: boolean } export function BankConnectionStatus({ connection, onSync, onDisconnect, onReconnect, isSyncing = false, }: BankConnectionStatusProps) { const daysUntilExpiry = getDaysUntilExpiry(connection.consent_expires) const isExpiring = isConsentExpiringSoon(connection.consent_expires) type StatusEntry = { icon: typeof CheckCircle color: string label: string variant: 'success' | 'warning' | 'destructive' | 'secondary' } const statusConfig: Record = { active: { icon: CheckCircle, color: 'text-success', label: 'Aktiv', variant: 'success', }, pending: { icon: Loader2, color: 'text-warning', label: 'Väntar', variant: 'warning', }, expired: { icon: AlertTriangle, color: 'text-warning', label: 'Utgånget samtycke', variant: 'warning', }, error: { icon: XCircle, color: 'text-destructive', label: 'Fel', variant: 'destructive', }, revoked: { icon: XCircle, color: 'text-gray-600', label: 'Bortkopplad', variant: 'secondary', }, } const status = statusConfig[connection.status] || statusConfig.error const StatusIcon = status.icon // Parse accounts from connection const accounts = (connection.accounts_data as Array<{ uid: string iban?: string name?: string currency: string balance?: number balance_updated_at?: string }>) || [] const [now] = useState(() => Date.now()) function formatBalanceAge(updatedAt: string): string { const hoursAgo = Math.floor((now - new Date(updatedAt).getTime()) / (1000 * 60 * 60)) if (hoursAgo < 1) return 'Nyss uppdaterat' if (hoursAgo < 24) return `${hoursAgo}h sedan` const daysAgo = Math.floor(hoursAgo / 24) return `${daysAgo}d sedan` } const isConnectionExpired = connection.status === 'expired' const isConnectionError = connection.status === 'error' const errorMessage = connection.error_message ?? '' return (
{/* Header */}

{connection.bank_name}

{status.label} {connection.last_synced_at && ( <> - Synkad {formatDate(connection.last_synced_at)} )}
{isConnectionExpired && onReconnect && ( )} {isConnectionError && ( )} {connection.status === 'active' && ( )}
{/* Error message */} {isConnectionError && errorMessage && ( <>
{errorMessage}
Du kan också importera transaktioner via bankfil
)} {/* Expired consent notice */} {isConnectionExpired && ( <>
PSD2-samtycket har löpt ut. Förnya anslutningen för att återuppta synkroniseringen.
Medan du väntar kan du importera transaktioner via bankfil
)} {/* Consent expiry warning (for active connections) */} {!isConnectionExpired && isExpiring && daysUntilExpiry !== null && (
Samtycket går ut om {daysUntilExpiry} {daysUntilExpiry === 1 ? 'dag' : 'dagar'}. Förnya genom att ansluta igen.
)} {/* Accounts list */} {accounts.length > 0 && (

Konton

{accounts.map((account) => (

{account.name || account.iban || 'Okänt konto'}

{account.iban && (

{account.iban.replace(/(.{4})/g, '$1 ').trim()}

)}
{account.balance !== undefined && (

{new Intl.NumberFormat('sv-SE', { style: 'currency', currency: account.currency, }).format(account.balance)}

{account.balance_updated_at && (

{formatBalanceAge(account.balance_updated_at)}

)}
)}
))}
)}
) }