'use client'; import { useEffect, useState } from 'react'; import { ScanSearch, Loader2, CheckCircle2, AlertTriangle, XCircle, HelpCircle } from 'lucide-react'; import BottomSheet from '@/components/BottomSheet'; import { cn } from '@/lib/utils'; import { checkInvoice, invoiceCheckBase, readSeen, rememberSeen, type InvoiceCheckResult, type Verdict, } from '@/lib/invoiceCheck'; interface InvoiceCheckProps { poNumber: string; /** Invoice pages already uploaded for this PO; the helper needs at least one. */ pages: number; size?: 'sm' | 'lg'; } const STYLE: Record = { green: { icon: CheckCircle2, row: 'text-[#125a3e]', label: 'Matches' }, amber: { icon: AlertTriangle, row: 'text-[#8a5a02]', label: 'Check' }, red: { icon: XCircle, row: 'text-[#cf2d56]', label: 'Mismatch' }, unchecked: { icon: HelpCircle, row: 'text-[rgba(38,37,30,0.55)]', label: 'Not checked' }, }; // Beta helper. Renders nothing unless the driver switched it on in // Settings → Beta, so the normal PO buttons are untouched. It only reads: // tapping "Check invoice" asks WFDASH to compare the photo with the lines // collected on this PO and shows the answer. It never blocks anything. export default function InvoiceCheck({ poNumber, pages, size = 'sm' }: InvoiceCheckProps) { const [enabled, setEnabled] = useState(false); const [open, setOpen] = useState(false); const [busy, setBusy] = useState(false); const [result, setResult] = useState(null); const [error, setError] = useState(''); const [seen, setSeen] = useState<'ok' | 'override' | undefined>(); useEffect(() => { setEnabled(Boolean(invoiceCheckBase())); setSeen(readSeen()[poNumber]); }, [poNumber]); if (!enabled || !poNumber || pages === 0) return null; const run = async () => { if (busy) return; setOpen(true); setBusy(true); setError(''); setResult(null); try { setResult(await checkInvoice(poNumber)); } catch (e) { setError(e instanceof Error ? e.message : 'Check failed'); } finally { setBusy(false); } }; const finish = () => { if (result) { const how = result.all_green ? 'ok' : 'override'; rememberSeen(poNumber, how); setSeen(how); } setOpen(false); }; const lg = size === 'lg'; const btn = lg ? 'h-12 w-full rounded-xl text-[15px] font-semibold flex items-center justify-center gap-2 touch-manipulation' : 'h-9 px-3 rounded-lg text-[13px] font-semibold flex items-center gap-1.5 touch-manipulation'; return ( <> {open && ( setOpen(false)}> {busy && (

)} {error && (

Couldn’t check: {error}. You can carry on as normal.

)} {result && ( <> {result.lines.length === 0 ? (

No collected lines on this PO to check yet.

) : (
    {result.lines.map((l) => { const st = STYLE[l.verdict]; const Icon = st.icon; return (
  • ); })}
)} {result.error && (

Note: {result.error}

)} )} {!busy && ( )}
)} ); }