import React, { useState, useRef } from 'react'; import { PipelineTrace, useToast } from '../components/ui/index'; export default function ScanPage() { const [imageData, setImageData] = useState(null); const [preview, setPreview] = useState(''); const [result, setResult] = useState(null); const [loading, setLoading] = useState(false); const fileRef = useRef(null); const { addToast } = useToast(); const handleFile = async (file: File) => { const buffer = await file.arrayBuffer(); setImageData(buffer); setPreview(URL.createObjectURL(file)); setResult(null); }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); const file = e.dataTransfer.files[0]; if (file && file.type.startsWith('image/')) handleFile(file); }; const process = async () => { if (!imageData) return; setLoading(true); try { if (window.solvox) { const r = await window.solvox.ai.ocrPayment(imageData); if (r.success) { setResult(r); addToast({ type: 'success', title: 'Document scanned', message: 'Payment data extracted via OCR + LLM' }); } else { addToast({ type: 'error', title: 'Scan failed', message: r.error }); } } else { setResult({ rawText: '[Dev mode] OCR requires @qvac/ocr-onnx model', extractedData: { amount: 25.50, token: 'USDT', recipient: null, memo: 'Invoice #1234', confidence: 0.85 }, pipelineSteps: [ { module: '@qvac/ocr-onnx', operation: 'Image → Text', input: 'uploaded image', output: 'Invoice text…', durationMs: 340 }, { module: '@qvac/llm-llamacpp', operation: 'Extract payment data', input: 'OCR text', output: '{"amount": 25.50}', durationMs: 210 }, ], }); } } catch (e: any) { addToast({ type: 'error', title: 'Error', message: e.message }); } setLoading(false); }; const reset = () => { setImageData(null); setPreview(''); setResult(null); }; return (

Scan & Pay

Upload an invoice, QR code, or screenshot. QVAC extracts payment data locally.

{/* Upload Area */} {!preview && (
e.preventDefault()} onClick={() => fileRef.current?.click()} className="flex flex-col items-center justify-center py-16 px-8 cursor-pointer hover:bg-surface-soft transition-colors rounded-xl" >
Drop an image or click to upload
Invoice, QR code, screenshot, receipt
@qvac/ocr-onnx → @qvac/llm-llamacpp pipeline
{ const f = e.target.files?.[0]; if (f) handleFile(f); }} />
)} {/* Preview + Process */} {preview && !result && (
Uploaded
{loading && (
Running OCR → LLM pipeline locally…
)}
)} {/* Results */} {result && (
{/* Extracted Data */}
Extracted payment data
{result.extractedData?.amount && (
Amount {result.extractedData.amount} {result.extractedData.token || '—'}
)} {result.extractedData?.recipient && (
Recipient {result.extractedData.recipient}
)} {result.extractedData?.memo && (
Memo {result.extractedData.memo}
)}
Confidence 0.7 ? 'badge-pill-green' : 'badge-pill-red'}`}> {((result.extractedData?.confidence || 0) * 100).toFixed(0)}%
{result.extractedData?.amount && ( )}
{/* Raw OCR Text */}
Raw OCR output
{result.rawText}
{/* Pipeline Trace */} {result.pipelineSteps && } {/* Preview */}
Scanned
)}
); }