'use client' import { useState } from 'react' import type { InvoiceInboxItem, Supplier } from '@/types' import type { InvoiceExtractionResult } from '@/extensions/general/invoice-inbox/types' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Separator } from '@/components/ui/separator' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table' import { Progress } from '@/components/ui/progress' import { getStatusLabel, getStatusVariant, getConfidenceLabel, } from '@/lib/extensions/invoice-inbox-utils' import { Loader2, RefreshCw, Check, X } from 'lucide-react' interface InboxDetailDialogProps { item: InvoiceInboxItem | null open: boolean onOpenChange: (open: boolean) => void onConfirm: (itemId: string, supplierId?: string) => Promise onReject: (itemId: string) => Promise onReprocess: (itemId: string) => Promise suppliers: Supplier[] } function formatSEK(amount: number | null): string { if (amount == null) return '-' return new Intl.NumberFormat('sv-SE', { style: 'currency', currency: 'SEK', minimumFractionDigits: 2, maximumFractionDigits: 2, }).format(amount) } export default function InboxDetailDialog({ item, open, onOpenChange, onConfirm, onReject, onReprocess, suppliers, }: InboxDetailDialogProps) { const [loading, setLoading] = useState<'confirm' | 'reject' | 'reprocess' | null>(null) const [selectedSupplierId, setSelectedSupplierId] = useState(undefined) if (!item) return null const extraction = item.extracted_data as unknown as InvoiceExtractionResult | null const confidence = getConfidenceLabel(item.confidence) const confidenceVariant = confidence.variant as 'default' | 'secondary' | 'destructive' | 'outline' | 'success' | 'warning' const statusVariant = getStatusVariant(item.status) as 'default' | 'secondary' | 'destructive' | 'outline' | 'success' | 'warning' const matchedSupplierName = (item.supplier as { name?: string } | undefined)?.name const supplierId = selectedSupplierId ?? item.matched_supplier_id ?? undefined const canConfirm = item.status === 'ready' && extraction != null const canReprocess = item.status !== 'confirmed' const canReject = item.status !== 'confirmed' && item.status !== 'rejected' async function handleAction(action: 'confirm' | 'reject' | 'reprocess') { setLoading(action) try { if (action === 'confirm') { await onConfirm(item!.id, supplierId) } else if (action === 'reject') { await onReject(item!.id) } else { await onReprocess(item!.id) } } finally { setLoading(null) } } return (
Granska faktura {getStatusLabel(item.status)}
{/* Confidence */} {item.confidence != null && (
AI-konfidens {confidence.label} ({Math.round(item.confidence * 100)}%)
)} {item.error_message && (
{item.error_message}
)} {extraction && ( <> {/* Supplier info */}

Leverantör

Namn

{extraction.supplier.name ?? '-'}

Org.nr

{extraction.supplier.orgNumber ?? '-'}

{extraction.supplier.bankgiro && (
Bankgiro

{extraction.supplier.bankgiro}

)} {extraction.supplier.plusgiro && (
Plusgiro

{extraction.supplier.plusgiro}

)}
{/* Supplier match override */}
{/* Invoice details */}

Fakturadetaljer

Fakturanummer

{extraction.invoice.invoiceNumber ?? '-'}

Valuta

{extraction.invoice.currency}

Fakturadatum

{extraction.invoice.invoiceDate ?? '-'}

Förfallodatum

{extraction.invoice.dueDate ?? '-'}

{extraction.invoice.paymentReference && (
Betalningsreferens

{extraction.invoice.paymentReference}

)}
{/* Line items */} {extraction.lineItems.length > 0 && ( <>

Rader

Beskrivning Antal À-pris Belopp Moms {extraction.lineItems.map((line, i) => ( {line.description} {line.quantity} {line.unitPrice != null ? formatSEK(line.unitPrice) : '-'} {formatSEK(line.lineTotal)} {line.vatRate != null ? `${line.vatRate}%` : '-'} ))}
)} {/* Totals */}
Netto {formatSEK(extraction.totals.subtotal)}
Moms {formatSEK(extraction.totals.vatAmount)}
Totalt {formatSEK(extraction.totals.total)}
)} {canReject && ( )} {canReprocess && ( )} {canConfirm && ( )}
) }