import React, { useState, useEffect } from 'react'; import { ShieldAlert, UploadCloud, RefreshCw, Settings, CheckCircle, Activity, FileSpreadsheet, AlertTriangle, Zap } from 'lucide-react'; import DashboardCharts from './components/DashboardCharts'; import TransactionTable from './components/TransactionTable'; import ManualQueryForm from './components/ManualQueryForm'; const BACKEND_URL = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' ? 'http://127.0.0.1:8000' : window.location.origin; export default function App() { const [modelName, setModelName] = useState('voting'); const [threshold, setThreshold] = useState(0.30); const [file, setFile] = useState(null); const [dragActive, setDragActive] = useState(false); const [processing, setProcessing] = useState(false); const [stats, setStats] = useState(null); const [lastUsedConfig, setLastUsedConfig] = useState(null); const [backendHealth, setBackendHealth] = useState({ connected: false, loading: true }); const [activeTab, setActiveTab] = useState('csv'); // 'csv' or 'manual' // Check backend health const checkHealth = async () => { try { const res = await fetch(`${BACKEND_URL}/api/health`); const data = await res.json(); if (data.status === 'healthy') { setBackendHealth({ connected: true, loading: false }); } else { setBackendHealth({ connected: false, loading: false }); } } catch (err) { setBackendHealth({ connected: false, loading: false }); } }; useEffect(() => { checkHealth(); // Poll health every 10 seconds const interval = setInterval(checkHealth, 10000); return () => clearInterval(interval); }, []); const handleDrag = (e) => { e.preventDefault(); e.stopPropagation(); if (e.type === "dragenter" || e.type === "dragover") { setDragActive(true); } else if (e.type === "dragleave") { setDragActive(false); } }; const handleDrop = (e) => { e.preventDefault(); e.stopPropagation(); setDragActive(false); if (e.dataTransfer.files && e.dataTransfer.files[0]) { const droppedFile = e.dataTransfer.files[0]; if (droppedFile.name.endsWith('.csv')) { setFile(droppedFile); } else { alert("Only CSV files are supported!"); } } }; const handleFileChange = (e) => { if (e.target.files && e.target.files[0]) { setFile(e.target.files[0]); } }; const handleUpload = async () => { if (!file) return; setProcessing(true); setStats(null); const formData = new FormData(); formData.append("file", file); formData.append("model_name", modelName); formData.append("threshold", threshold); try { const response = await fetch(`${BACKEND_URL}/api/predict-csv`, { method: "POST", body: formData, }); if (!response.ok) { let errorMsg = "Upload analysis failed"; try { const errorData = await response.json(); errorMsg = errorData.detail || errorMsg; } catch (_) { try { errorMsg = await response.text(); } catch (_) {} } throw new Error(errorMsg); } const data = await response.json(); setStats(data); setLastUsedConfig({ modelName, threshold }); } catch (err) { console.error(err); alert(`Error running analysis: ${err.message}`); } finally { setProcessing(false); } }; // Submit manual prediction const handleManualPredict = async (dataRow) => { const response = await fetch(`${BACKEND_URL}/api/predict-single`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ data: dataRow, model_name: modelName, threshold: threshold }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.detail || "Query failed"); } return await response.json(); }; const configChanged = stats && lastUsedConfig && (lastUsedConfig.modelName !== modelName || lastUsedConfig.threshold !== threshold); return (
Suspicious Transactions & Mule Account Detection
Applying Robust Imputation, Vectorized Min-Max Scaling, and ensemble predictions. Please wait...
Transactions Analyzed
{stats.total_count.toLocaleString()}
Suspicious Flagged
{stats.suspicious_count.toLocaleString()}
Alert Rate
{Math.round(stats.suspicious_rate * 1000) / 10}%
Mule Account Leads
{stats.mule_accounts?.length || 0}
Our machine learning models evaluate suspicious proceeds based on several key operational rules derived from the training dataset: