'use client' import { useState } from 'react' import type { InvoiceInboxItem } from '@/types' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Separator } from '@/components/ui/separator' import { Switch } from '@/components/ui/switch' import { CheckCircle2, Receipt, LinkIcon } from 'lucide-react' interface ReceiptLineItem { id: string description: string line_total: number vat_rate: number | null is_business: boolean | null category: string | null bas_account: string | null } interface ReceiptInboxDetailProps { item: InvoiceInboxItem | null open: boolean onOpenChange: (open: boolean) => void onConfirm: () => void } function formatAmount(amount: number, currency: string = 'SEK'): string { return new Intl.NumberFormat('sv-SE', { style: 'currency', currency, minimumFractionDigits: 2, maximumFractionDigits: 2, }).format(amount) } export default function ReceiptInboxDetail({ item, open, onOpenChange, onConfirm, }: ReceiptInboxDetailProps) { const [lineItems, setLineItems] = useState([]) const [loading, setLoading] = useState(false) const [confirming, setConfirming] = useState(false) const [representationPersons, setRepresentationPersons] = useState(null) const [representationPurpose, setRepresentationPurpose] = useState('') const [representationBusinessConnection, setRepresentationBusinessConnection] = useState('') const receipt = item?.receipt as { id?: string merchant_name?: string total_amount?: number receipt_date?: string status?: string matched_transaction_id?: string } | undefined // Fetch line items when dialog opens async function fetchLineItems() { if (!item?.linked_receipt_id) return setLoading(true) try { const res = await fetch(`/api/extensions/ext/receipt-ocr/${item.linked_receipt_id}`) if (res.ok) { const { data } = await res.json() if (data?.line_items) { setLineItems(data.line_items) } } } catch { // ok } finally { setLoading(false) } } function handleOpenChange(isOpen: boolean) { if (isOpen && item?.linked_receipt_id) { fetchLineItems() } onOpenChange(isOpen) } function toggleBusiness(lineItemId: string) { setLineItems((prev) => prev.map((li) => li.id === lineItemId ? { ...li, is_business: li.is_business === true ? false : true } : li ) ) } async function handleConfirm() { if (!item?.id || !item.linked_receipt_id) return setConfirming(true) try { const body: Record = { line_items: lineItems.map((li) => ({ id: li.id, is_business: li.is_business, category: li.category, bas_account: li.bas_account, })), } if (receipt?.matched_transaction_id) { body.matched_transaction_id = receipt.matched_transaction_id } if (representationPersons != null && representationPersons > 0) { body.representation_persons = representationPersons } if (representationPurpose) { body.representation_purpose = representationPurpose } if (representationBusinessConnection) { body.representation_business_connection = representationBusinessConnection } const res = await fetch( `/api/extensions/ext/invoice-inbox/inbox/${item.id}/confirm-receipt`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), } ) if (res.ok) { onConfirm() onOpenChange(false) } } catch { // ok } finally { setConfirming(false) } } const businessTotal = lineItems .filter((li) => li.is_business === true) .reduce((sum, li) => sum + li.line_total, 0) const privateTotal = lineItems .filter((li) => li.is_business === false) .reduce((sum, li) => sum + li.line_total, 0) return ( Kvitto via e-post {receipt && (
{/* Summary */}
Handlare

{receipt.merchant_name ?? 'Okänd'}

Datum

{receipt.receipt_date ?? '-'}

Totalbelopp

{receipt.total_amount ? formatAmount(receipt.total_amount) : '-'}

Transaktionsmatch

{receipt.matched_transaction_id ? ( <> Matchad ) : ( Ingen match )}

{/* Line items with business/private toggle */}
{loading ? (

Laddar...

) : lineItems.length === 0 ? (

Inga rader extraherade

) : (
{lineItems.map((li) => (

{li.description}

{formatAmount(li.line_total)} {li.vat_rate != null && ` (${li.vat_rate}% moms)`}

Företag toggleBusiness(li.id)} />
))}
)}
{/* Totals */} {lineItems.length > 0 && (
Företag: {formatAmount(Math.round(businessTotal * 100) / 100)} Privat: {formatAmount(Math.round(privateTotal * 100) / 100)}
)} {/* Representation fields */}
setRepresentationPersons( e.target.value ? parseInt(e.target.value) : null ) } placeholder="0" />
setRepresentationPurpose(e.target.value)} placeholder="T.ex. kundmöte" />
setRepresentationBusinessConnection(e.target.value) } placeholder="T.ex. potentiell kund, pågående projekt" />
)}
) }