import React, { useState, useCallback } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import ReactJsonView from 'react-json-view'; import { format } from 'date-fns'; import { X, Copy, ExternalLink, Shield, User, Clock, MapPin, AlertTriangle, CheckCircle, XCircle, Eye, EyeOff, Download, Link as LinkIcon, Code, FileText, Activity, Tag } from 'lucide-react'; import { AuditLogEntry } from '@/types/audit'; import { toast } from 'react-toastify'; interface LogDetailModalProps { log: AuditLogEntry | null; isOpen: boolean; onClose: () => void; onViewCorrelated?: (requestId: string) => void; onViewSession?: (sessionId: string) => void; } type TabType = 'overview' | 'context' | 'metadata' | 'compliance' | 'raw'; const SeverityBadge: React.FC<{ severity: AuditLogEntry['severity'] }> = ({ severity }) => { const config = { low: { icon: CheckCircle, className: 'severity-low' }, medium: { icon: AlertTriangle, className: 'severity-medium' }, high: { icon: AlertTriangle, className: 'severity-high' }, critical: { icon: XCircle, className: 'severity-critical' } }; const { icon: Icon, className } = config[severity]; return ( {severity.charAt(0).toUpperCase() + severity.slice(1)} ); }; const StatusBadge: React.FC<{ success: boolean; reason?: string }> = ({ success, reason }) => { return (
{success ? ( ) : ( )} {success ? 'Success' : 'Failed'} {reason && ( {reason} )}
); }; const ComplianceBadges: React.FC<{ compliance: AuditLogEntry['compliance'] }> = ({ compliance }) => { const frameworks = []; if (compliance.soc2Relevant) frameworks.push({ name: 'SOC2', relevant: true }); if (compliance.hipaaRelevant) frameworks.push({ name: 'HIPAA', relevant: true }); if (compliance.pciRelevant) frameworks.push({ name: 'PCI DSS', relevant: true }); if (compliance.gdprRelevant) frameworks.push({ name: 'GDPR', relevant: true }); return (
{frameworks.map(({ name }) => ( {name} ))} {frameworks.length === 0 && ( No compliance frameworks )}
); }; const CopyButton: React.FC<{ value: string; label: string }> = ({ value, label }) => { const handleCopy = useCallback(async () => { try { await navigator.clipboard.writeText(value); toast.success(`${label} copied to clipboard`); } catch (error) { toast.error(`Failed to copy ${label}`); } }, [value, label]); return ( ); }; export const LogDetailModal: React.FC = ({ log, isOpen, onClose, onViewCorrelated, onViewSession }) => { const [activeTab, setActiveTab] = useState('overview'); const [showSensitiveData, setShowSensitiveData] = useState(false); if (!log) return null; const handleExportJson = () => { const dataStr = JSON.stringify(log, null, 2); const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr); const exportFileDefaultName = `audit-log-${log.id}.json`; const linkElement = document.createElement('a'); linkElement.setAttribute('href', dataUri); linkElement.setAttribute('download', exportFileDefaultName); linkElement.click(); }; const tabs = [ { id: 'overview', label: 'Overview', icon: Eye }, { id: 'context', label: 'Context', icon: Activity }, { id: 'metadata', label: 'Metadata', icon: Tag }, { id: 'compliance', label: 'Compliance', icon: Shield }, { id: 'raw', label: 'Raw JSON', icon: Code } ] as const; return ( {isOpen && ( <> {/* Backdrop */} {/* Modal */} {/* Header */}

Audit Log Details

{format(log.timestamp, 'PPpp')} {log.user.username}
{/* Tabs */}
{/* Content */}
{activeTab === 'overview' && (
{/* Action and Status */}

Action

Type {log.action.type.replace(/_/g, ' ').toUpperCase()}
Resource {log.action.resource}
{log.action.resourceId && (
Resource ID
{log.action.resourceId}
)}
Description {log.action.description}

Result

Status
{log.result.decision && (
Decision {log.result.decision}
)}
Severity
{(log.result.errorCode || log.result.errorMessage) && (
{log.result.errorCode && (
Error Code {log.result.errorCode}
)} {log.result.errorMessage && (
Error Message

{log.result.errorMessage}

)}
)}
{/* User Information */}

User Information

Username {log.user.username}
Email {log.user.email}
User ID
{log.user.id}
Roles
{log.user.roles.map((role) => ( {role} ))}
{/* Quick Actions */}
{onViewCorrelated && ( )} {onViewSession && ( )}
)} {activeTab === 'context' && (

Request Context

Session & Request

Session ID
{log.context.sessionId}
Request ID
{log.context.requestId}
MFA Enabled {log.context.mfaEnabled ? 'Yes' : 'No'}

Network & Location

IP Address
{log.context.ipAddress}
{log.context.location && ( <>
Country {log.context.location.country}
City {log.context.location.city}
{log.context.location.coordinates && (
Coordinates {log.context.location.coordinates[0]}, {log.context.location.coordinates[1]}
)} )}

User Agent

{showSensitiveData ? log.context.userAgent : '***HIDDEN***'}
)} {activeTab === 'metadata' && (

Metadata

{/* Tags */}

Tags

{log.tags.length > 0 ? (
{log.tags.map((tag) => ( {tag} ))}
) : ( No tags )}
{/* Retention Policy */}

Retention Policy

Retention Period {log.retention.retentionPeriod} days
{log.retention.archiveDate && (
Archive Date {format(log.retention.archiveDate, 'PP')}
)} {log.retention.deletionDate && (
Deletion Date {format(log.retention.deletionDate, 'PP')}
)}
{/* Custom Metadata */} {Object.keys(log.metadata).length > 0 && (

Custom Metadata

)}
)} {activeTab === 'compliance' && (

Compliance Information

Relevant Frameworks

{/* Compliance Details */}
{log.compliance.soc2Relevant && (

SOC2 Type II

This log entry is relevant for SOC2 Type II compliance monitoring.

)} {log.compliance.hipaaRelevant && (

HIPAA

This log entry contains PHI-related activity for HIPAA compliance.

)} {log.compliance.pciRelevant && (

PCI DSS

This log entry is relevant for PCI DSS compliance requirements.

)} {log.compliance.gdprRelevant && (

GDPR

This log entry involves personal data processing under GDPR.

)}
)} {activeTab === 'raw' && (

Raw JSON Data

)}
)}
); };