import React, { useState } from 'react'; import { FileText, Search, Download, AlertTriangle, ShieldAlert, ShieldCheck, UserX, Eye } from 'lucide-react'; export default function TransactionTable({ previewData, topSuspicious, muleAccounts, sessionId, backendUrl }) { const [activeTab, setActiveTab] = useState('preview'); const [searchTerm, setSearchTerm] = useState(''); const [riskFilter, setRiskFilter] = useState('All'); const [currentPage, setCurrentPage] = useState(1); const [selectedTx, setSelectedTx] = useState(null); // For detail modal const itemsPerPage = 15; // Filter & Search preview data const filteredPreview = (previewData || []).filter(item => { // Search matching const searchStr = `${item.F3886 || ''} ${item.F3893 || ''} ${item.F3891 || ''} ${item.Unnamed_0 || item['Unnamed: 0'] || ''}`.toLowerCase(); const matchesSearch = searchStr.includes(searchTerm.toLowerCase()); // Risk matching const matchesRisk = riskFilter === 'All' || item.risk_level === riskFilter; return matchesSearch && matchesRisk; }); // Pagination const totalPages = Math.ceil(filteredPreview.length / itemsPerPage); const paginatedData = filteredPreview.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage); const getRiskBadge = (level) => { switch (level) { case 'High': return High Risk; case 'Medium': return Medium Risk; default: return Low Risk; } }; const handleDownload = () => { if (!sessionId) return; window.open(`${backendUrl}/api/download-run/${sessionId}`, '_blank'); }; return (
{/* Header and Download */}

Analysis Logs

{sessionId && ( )}
{/* Tabs list */}
{/* SEARCH AND FILTERS (Only for preview tab) */} {activeTab === 'preview' && (
{/* Search box */}
{ setSearchTerm(e.target.value); setCurrentPage(1); }} />
{/* Filter dropdown */}
Risk Filter:
)} {/* TAB 1: ALL PREVIEW */} {activeTab === 'preview' && (
{paginatedData.length === 0 ? (
No transactions match the selected filters.
) : (
{paginatedData.map((row, idx) => { const rowId = row.Unnamed_0 || row['Unnamed: 0'] || `Row ${idx + 1}`; return ( ); })}
ID Date Account Type Channel Job Type Risk Prob Status Actions
{rowId} {row.F3888 || 'N/A'} {row.F3886 || 'N/A'} {row.F3893 || 'N/A'} {row.F3891 || 'N/A'} {Math.round(row.fraud_probability * 100)}% {getRiskBadge(row.risk_level)}
)} {/* Pagination controls */} {totalPages > 1 && (
Page {currentPage} of {totalPages}
)}
)} {/* TAB 2: TOP SUSPICIOUS ALERTS */} {activeTab === 'alerts' && (
{(!topSuspicious || topSuspicious.length === 0) ? (
No critical fraud alerts detected.
) : ( {topSuspicious.map((row, idx) => { const rowId = row.Unnamed_0 || row['Unnamed: 0'] || `Alert ${idx + 1}`; return ( ); })}
ID Risk Probability Date Account Type Channel Job Status Risk Assessment Action
{rowId} {Math.round(row.fraud_probability * 100)}% Risk {row.F3888 || 'N/A'} {row.F3886 || 'N/A'} {row.F3893 || 'N/A'} {row.F3891 || 'N/A'} High Threat
)}
)} {/* TAB 3: MULE ACCOUNT CANDIDATES */} {activeTab === 'mules' && (

Mule accounts typically act as intermediaries to circulate stolen funds. The table below lists account IDs that have multiple high-risk/suspicious transactions in this file run.

{(!muleAccounts || muleAccounts.length === 0) ? (
No repeating account-level suspicious transactions detected.
) : ( {muleAccounts.map((mule, idx) => { const avgRisk = Math.round(mule.avg_prob * 100); const threatScore = mule.suspicious_count * avgRisk; const isSevere = threatScore > 100 || mule.suspicious_count >= 3; return ( ); })}
Account ID / Value Total Transactions Suspicious Flagged Count Max Probability Avg Risk Probability Mule Account Threat Rating
{mule.F3887 || mule.F3895 || `Acc #${idx}`} {mule.tx_count} {mule.suspicious_count} {Math.round(mule.max_prob * 100)}% {avgRisk}% {isSevere ? ( CRITICAL MULE ) : ( SUSPECT MULE )}
)}
)} {/* DETAILS MODAL */} {selectedTx && (

Transaction Details & Analysis

Transaction ID

{selectedTx.Unnamed_0 || selectedTx['Unnamed: 0'] || 'N/A'}

Risk Assessment

{getRiskBadge(selectedTx.risk_level)}

Fraud Probability

{Math.round(selectedTx.fraud_probability * 100)}%

Transaction DateTime

{selectedTx.F3888 || 'N/A'}

Key Parameters Loaded

Account Type (F3886): {selectedTx.F3886 || 'N/A'}
Channel (F3893): {selectedTx.F3893 || 'N/A'}
Job Status (F3891): {selectedTx.F3891 || 'N/A'}
Gender (F3892): {selectedTx.F3892 || 'N/A'}
Account Code (F3887): {selectedTx.F3887 || 'N/A'}
Customer Code (F3889): {selectedTx.F3889 || 'N/A'}
Account State (F3890): {selectedTx.F3890 || 'N/A'}
Tx Interval (F3894): {selectedTx.F3894 || 'N/A'}
)}
); }