import { ActivityIcon, Inbox, Lock, Scan } from "lucide-react"; import { useState, useEffect } from "react"; import { useTranslation } from 'react-i18next'; import { useAuth } from './context/AuthContext'; import { useNavigate, useLocation } from 'react-router-dom'; export default function Analysis() { const { t } = useTranslation(); const { user } = useAuth(); const navigate = useNavigate(); const location = useLocation(); const stateScan = location.state; const [displayAnalyses, setDisplayAnalyses] = useState([]); // Removed hardcoded fallback const [summaryData, setSummaryData] = useState({ avg_confidence: 0, avg_processing_time: 3.0, detected_fakes: 0, today_scans: 0 }); useEffect(() => { const fetchAnalysisData = async () => { try { const apiUrl = import.meta.env.VITE_API_URL || 'http://127.0.0.1:5000'; const token = localStorage.getItem('token'); const headers = { 'Content-Type': 'application/json', ...(token ? { 'Authorization': `Bearer ${token}` } : {}) }; // Mengambil limit=20 sesuai permintaan const [historyRes, summaryRes] = await Promise.all([ fetch(`${apiUrl}/api/statistics/history?page=1&limit=20`, { method: 'GET', headers }), fetch(`${apiUrl}/api/statistics/summary`, { method: 'GET', headers }) ]); if (summaryRes.ok) { const sumData = await summaryRes.json(); if (sumData.data) setSummaryData(sumData.data); } if (historyRes.ok) { const histData = await historyRes.json(); if (histData.data && histData.data.items) { const mappedItems = histData.data.items.map(item => ({ file: item.file_name, url: item.url_file || null, result: item.result, confidence: `${item.confidence_score}%`, date: new Date(item.created_at).toISOString().slice(0, 16).replace('T', ' ') })); setDisplayAnalyses(mappedItems); } } } catch (error) { console.error("Error fetching analysis data:", error); } }; fetchAnalysisData(); }, []); // Use values from summaryData primarily const totalScans = summaryData.today_scans; const detectedFakes = summaryData.detected_fakes; const avgConfidence = `${summaryData.avg_confidence}%`; const processingTime = summaryData.avg_processing_time ? `${summaryData.avg_processing_time}s` : '3.0s'; // 4. Build the new dynamic array for the UI const dynamicStats = [ { key: "todaysScans", value: totalScans, accent: "text-white", icon: "↗", iconColor: "text-green-400" }, { key: "detectedFakes", value: detectedFakes, accent: "text-white", icon: "⊙", iconColor: "text-red-400" }, { key: "avgConfidence", value: avgConfidence, accent: "text-blue-400", icon: null }, { key: "processingTime", value: processingTime, accent: "text-white", icon: null }, ]; return (
{/* Main */}
{/* Unauthenticated Overlay */} {!user && (

{t('analysis.lockedTitle')}

{t('analysis.lockedMessage')}

)} {/* Header */}

{t('analysis.title')}

{t('analysis.subtitle')}

{/* Stat Cards */}
{dynamicStats.map(({ key, value, accent, icon, iconColor }) => (
{t(`analysis.${key}`)} {icon && {icon}}
{value}
))}
{/* Recent Analyses Visual Layout */}

{t('analysis.recentAnalyses', 'Recent Analyses')}

{(displayAnalyses.length === 0 && !stateScan) ? (

{t('analysis.emptySession', 'No recent analyses found.')}

) : (
{/* Center / Latest Scan */} {(() => { // Determine the latest scan to show in the big center let latest = null; let others = []; if (stateScan) { latest = { file: stateScan.fileName, url: stateScan.scanImage, result: stateScan.scanResult?.result || "Unknown", confidence: `${stateScan.scanResult?.probability || 0}%`, }; others = displayAnalyses.slice(0, 4); // Take up to 4 for grid } else if (displayAnalyses.length > 0) { latest = displayAnalyses[0]; others = displayAnalyses.slice(1, 5); } if (!latest) return null; return ( <>
{latest.url ? ( {latest.file} ) : (
)}

{latest.file}

{latest.result}

{t('analysis.confidence', 'Confidence')}

{latest.confidence}

{/* 2x2 Grid for Previous Scans */} {others.length > 0 && (
{others.map((scan, index) => (
{scan.url ? ( {scan.file} ) : (
)}

{scan.file}

{scan.result} {scan.confidence}
))}
)} ); })()}
)}
{/* Help Button */}
); }