import React, { useEffect, useState } from "react"; import { FiX, FiCheckCircle, FiXCircle, FiClock, FiUser, FiCalendar, FiFileText, FiAlertTriangle, FiTruck, FiUserCheck, FiUserX, FiPackage, FiMapPin, FiEye, FiRotateCcw, FiSend, FiMail, FiActivity, FiRefreshCw, FiLock, FiUnlock, FiUserPlus, FiEdit } from "react-icons/fi"; import api from "../../config/api"; import { useParams } from "react-router-dom"; import logoRecord from '../../assets/record.svg' import LoaderUi from "../../helper/LoaderUi"; import { FaRegEyeSlash } from "react-icons/fa"; import { MdAccessTime, MdCancel } from "react-icons/md"; interface AuditModalProps { closeModal: () => void; } const AuditModal: React.FC = ({ closeModal }) => { const { accountId, transactionId } = useParams<{ accountId: string, transactionId: string }>(); if (!accountId || !transactionId) { window.location.href = "/"; return null; } let [auditStatus, setAuditStatus] = useState([]) let [loading, setLoading] = useState(false) const getAuditDetails = async () => { setLoading(true) try { let res = await api.get(`/api/accounts/${accountId}/transactions/${transactionId}/audit`) if (res?.status === 200) { // console.log(res?.data?.events) let auditResponse = res?.data?.events setAuditStatus(auditResponse) } } catch (error) { console.log(error) } finally { setLoading(false) } } useEffect(() => { if (accountId && transactionId) { getAuditDetails() } }, [accountId, transactionId]) const statusHistory = [ { "action": "SENT", "message": "Transaction Sent by John Doe ", "status": "SENT", "eventData": { "ip": "192.168.1.1", "longitude": "3.3792", "latitude": "6.5244", "timezone": "WAT" }, "timestamp": "2025-01-15T10:30:00Z", "language": "en" }, { "action": "INVITED", "message": "Invitation Sent to Jane Smith to sign documents", "status": "SENT", "eventData": { "ip": "0.0.0.0", "longitude": "11", "latitude": "12", "timezone": "" }, "timestamp": "2025-01-15T11:45:00Z", "language": "es" }, { "action": "VIEWED", "message": "Document viewed by recipient Alice Johnson ", "status": "VIEWED", "eventData": { "ip": "203.0.113.5", "longitude": "-74.0059", "latitude": "40.7128", "timezone": "EST" }, "timestamp": "2025-01-15T14:20:00Z", "language": "en" }, { "action": "SIGNED", "message": "Document signed by Bob Wilson ", "status": "COMPLETED", "eventData": { "ip": "198.51.100.10", "longitude": "-122.4194", "latitude": "37.7749", "timezone": "PST" }, "timestamp": "2025-01-15T16:10:00Z", "language": "en" } ]; const getActionIcon = (action: string) => { const icons = { 'CREATED': , 'SENT': , 'INVITED': , 'COMPLETED': , 'RE_SENT_INVITATION': , 'RE_SENT_EXPIRED_INVITATION': , 'VIEWED': , 'VIEWED_IN_PERSON': , // Slightly different eye icon 'AUTH_FAILED': , 'ACCESS_CODE_FAILED': , 'ACCESS_CODE_VALIDATED': , 'AUTH_VALIDATED': , 'SIGNED': , 'EXPIRED': , 'CANCELLED': , 'DECLINED': , 'PENDING': , 'ASSIGNED': , 'REASSIGNED': , 'EDITED': , }; return icons[action as keyof typeof icons] || ; }; const getActionColor = (action: string, status: string) => { if (status === 'COMPLETED') return 'text-green-600'; if (status === 'FAILED' || status === 'REJECTED') return 'text-red-600'; if (status === 'PENDING') return 'text-yellow-600'; const colors = { 'SENT': 'text-blue-600', 'INVITED': 'text-indigo-600', 'VIEWED': 'text-purple-600', 'SIGNED': 'text-green-600', 'REJECTED': 'text-red-600' }; return colors[action as keyof typeof colors] || 'text-gray-600'; }; const getStatusBadge = (status: string) => { const statusClasses = { 'SENT': 'bg-blue-100 text-blue-800', 'COMPLETED': 'bg-green-100 text-green-800', 'FAILED': 'bg-red-100 text-red-800', 'PENDING': 'bg-yellow-100 text-yellow-800', 'VIEWED': 'bg-purple-100 text-purple-800', 'REJECTED': 'bg-red-100 text-red-800' }; return statusClasses[status as keyof typeof statusClasses] || 'bg-gray-100 text-gray-800'; }; const formatTimestamp = (timestamp: string) => { try { const date = new Date(timestamp); if (isNaN(date.getTime())) { return timestamp; } const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffMins = Math.floor(diffMs / (1000 * 60)); const diffHours = Math.floor(diffMs / (1000 * 60 * 60)); const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); if (diffMins < 60) { return `${diffMins}m ago`; } else if (diffHours < 24) { return `${diffHours}h ago`; } else if (diffDays < 7) { return `${diffDays}d ago`; } else { return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit' }); } } catch (error) { return timestamp; } }; const extractEmailFromMessage = (message: string) => { const emailMatch = message.match(/<([^>]+)>/); return emailMatch ? emailMatch[1] : ''; }; return (
{/* Header */}

Audit Status

{/* Content */}
{/* {loading ? : ""} */} {auditStatus.length ?
{/*
TODAY
*/} {auditStatus.map((item, index) => (
{getActionIcon(item.action)}

{item.message}

Action: {item.action} {extractEmailFromMessage(item.message) && ( <> • {extractEmailFromMessage(item.message)} )}
Status: {item.status} {formatTimestamp(item.timestamp)} {item.language && ( {item.language} )}
{/* Event Data Details */} {/*
{item.eventData.ip && (
IP: {item.eventData.ip}
)} {item.eventData.timezone && (
Timezone: {item.eventData.timezone}
)} {item.eventData.latitude && item.eventData.longitude && (
Location: Lat: {item.eventData.latitude}, Lng: {item.eventData.longitude}
)}
*/}
))}
:
Record Not Found
}
{/* Footer */}
Showing {auditStatus.length} event{auditStatus.length !== 1 ? 's' : ''}
); }; export default AuditModal;