'use client'; import { useState, useRef, useCallback } from 'react'; import { Shield, AlertTriangle, CheckCircle, Loader2, FileSearch, Upload, FileText, X, Layers } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { BackButton } from '@/components/common/BackButton'; import { extractPdfPages, formatFileSize, type PDFPagesResult } from '@/lib/pdf-extract'; import { chunkContractPages, formatChunkingSummary, type ChunkingResult, type ContractChunk } from '@/lib/contract-chunker'; interface ChunkResult { chunkIndex: number; pageRange: string; answer: string; citations: Array<{ index: number; type: string; id: number; label: string; ref: string; snippet: string; url: string }>; error?: string; } export function ContractAnalysisView() { const [pdfLoading, setPdfLoading] = useState(false); const [pdfProgress, setPdfProgress] = useState(null); const [pdfInfo, setPdfInfo] = useState(null); const [chunkingResult, setChunkingResult] = useState(null); const [analyzing, setAnalyzing] = useState(false); const [chunkResults, setChunkResults] = useState([]); const [currentChunk, setCurrentChunk] = useState(-1); const [error, setError] = useState(null); const [dragOver, setDragOver] = useState(false); const [manualText, setManualText] = useState(''); const fileInputRef = useRef(null); const handlePDFFile = useCallback(async (file: File) => { setPdfLoading(true); setError(null); setPdfProgress('กำลังโหลด PDF...'); setPdfInfo(null); setChunkingResult(null); setChunkResults([]); setManualText(''); try { const result = await extractPdfPages(file, (currentPage, totalPages) => { setPdfProgress(`กำลังอ่านหน้า ${currentPage}/${totalPages}...`); }); setPdfInfo(result); setPdfProgress(null); // Auto-chunk the pages const chunked = chunkContractPages(result.pages); setChunkingResult(chunked); } catch (err: unknown) { const message = err instanceof Error ? err.message : 'ไม่สามารถอ่าน PDF ได้'; setError(message); setPdfProgress(null); } finally { setPdfLoading(false); } }, []); const handleFileSelect = (e: React.SyntheticEvent) => { const target = e.target as HTMLInputElement; const file = target.files?.[0]; if (file) handlePDFFile(file); target.value = ''; }; const handleDrop = (e: React.SyntheticEvent) => { e.preventDefault(); setDragOver(false); const dragEvent = e as unknown as DragEvent; const file = dragEvent.dataTransfer?.files?.[0]; if (file) handlePDFFile(file); }; const handleDragOver = (e: React.SyntheticEvent) => { e.preventDefault(); setDragOver(true); }; const handleDragLeave = (e: React.SyntheticEvent) => { e.preventDefault(); setDragOver(false); }; const clearAll = () => { setPdfInfo(null); setChunkingResult(null); setChunkResults([]); setError(null); setManualText(''); }; const analyzeChunk = async (chunk: ContractChunk, totalChunks: number) => { try { const res = await fetch('/api/contracts/analyze', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ chunk: chunk.text, chunkIndex: chunk.index, totalChunks, pageRange: chunk.pageRange, }), }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const data = await res.json(); return { chunkIndex: chunk.index, pageRange: chunk.pageRange, answer: data.answer || 'ไม่สามารถวิเคราะห์ได้', citations: data.citations || [], } as ChunkResult; } catch (err: unknown) { const message = err instanceof Error ? err.message : 'Unknown error'; return { chunkIndex: chunk.index, pageRange: chunk.pageRange, answer: '', citations: [], error: message, } as ChunkResult; } }; const analyzeAllChunks = async () => { if (!chunkingResult || chunkingResult.chunks.length === 0) return; setAnalyzing(true); setChunkResults([]); setError(null); const results: ChunkResult[] = []; for (let i = 0; i < chunkingResult.chunks.length; i++) { setCurrentChunk(i); const chunk = chunkingResult.chunks[i]; const result = await analyzeChunk(chunk, chunkingResult.chunks.length); results.push(result); setChunkResults([...results]); } setCurrentChunk(-1); setAnalyzing(false); }; const analyzeManualText = async () => { if (!manualText.trim()) return; setAnalyzing(true); setError(null); setChunkResults([]); // Treat manual text as a single chunk const fakeChunk: ContractChunk = { index: 0, text: manualText, charCount: manualText.length, pageRange: 'ข้อความที่ป้อน', startPage: 1, endPage: 1, }; setCurrentChunk(0); const result = await analyzeChunk(fakeChunk, 1); setChunkResults([result]); setCurrentChunk(-1); setAnalyzing(false); }; return (

วิเคราะห์สัญญา

อัปโหลด PDF ขนาดไหนก็ได้ → ระบบแยกข้อความ + กรองหน้าไม่จำเป็น + แบ่งส่วนวิเคราะห์อัตโนมัติ

{/* Privacy notice */}

Privacy 100% — PDF ถูกประมวลผลในเบราว์เซอร์ ไม่ส่งไฟล์ไปเซิร์ฟเวอร์ ระบบแบ่งเนื้อหาเป็นส่วนๆ แล้วส่งเฉพาะข้อความไปวิเคราะห์

{/* PDF upload zone (only when no PDF loaded) */} {!pdfInfo && !pdfLoading && (

ลากไฟล์ PDF มาวางที่นี่ หรือ

ไม่จำกัดขนาดไฟล์ — ระบบแบ่งเนื้อหาอัตโนมัติ

{/* OR manual text input */}