import React, { useState, useEffect } from 'react'; import { useTranslation } from '../../utils/tempTranslations'; const AuditLogs = () => { const { t } = useTranslation(); const [auditLogs, setAuditLogs] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [filters, setFilters] = useState({ page: 1, limit: 50, level: '', action: '', tenantId: '', userId: '', startDate: '', endDate: '', search: '' }); const [pagination, setPagination] = useState({}); const [availableActions, setAvailableActions] = useState([]); const [summary, setSummary] = useState({}); useEffect(() => { fetchAuditLogs(); fetchAvailableActions(); fetchSummary(); }, [filters]); const fetchAuditLogs = async () => { try { setLoading(true); const queryParams = new URLSearchParams(); Object.keys(filters).forEach(key => { if (filters[key]) { queryParams.append(key, filters[key]); } }); const token = localStorage.getItem('managementToken'); const response = await fetch(`/api/management/audit-logs?${queryParams}`, { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); if (!response.ok) { throw new Error('Failed to fetch audit logs'); } const data = await response.json(); setAuditLogs(data.data.auditLogs); setPagination(data.data.pagination); setError(null); } catch (err) { setError(err.message); } finally { setLoading(false); } }; const fetchAvailableActions = async () => { try { const token = localStorage.getItem('managementToken'); const response = await fetch('/api/management/audit-logs/actions', { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); if (response.ok) { const data = await response.json(); setAvailableActions(data.data); } } catch (err) { console.error('Failed to fetch available actions:', err); } }; const fetchSummary = async () => { try { const token = localStorage.getItem('managementToken'); const response = await fetch('/api/management/audit-logs/summary', { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); if (response.ok) { const data = await response.json(); setSummary(data.data); } } catch (err) { console.error('Failed to fetch summary:', err); } }; const handleFilterChange = (key, value) => { setFilters(prev => ({ ...prev, [key]: value, page: 1 // Reset to first page when filtering })); }; const handlePageChange = (newPage) => { setFilters(prev => ({ ...prev, page: newPage })); }; const formatTimestamp = (timestamp) => { return new Date(timestamp).toLocaleString(); }; const getLevelBadgeClass = (level) => { switch (level) { case 'INFO': return 'bg-blue-100 text-blue-800'; case 'WARNING': return 'bg-yellow-100 text-yellow-800'; case 'ERROR': return 'bg-red-100 text-red-800'; case 'CRITICAL': return 'bg-red-200 text-red-900 font-bold'; default: return 'bg-gray-100 text-gray-800'; } }; const getSuccessIndicator = (success) => { if (success === true) { return ; } else if (success === false) { return ; } return -; }; const clearFilters = () => { setFilters({ page: 1, limit: 50, level: '', action: '', tenantId: '', userId: '', startDate: '', endDate: '', search: '' }); }; return (
{/* Header */}

{t('management.auditLogs') || 'Security Audit Logs'}

{/* Summary Statistics */} {summary.summary && (
{t('management.totalLogs') || 'Total Logs'}
{summary.summary.totalLogs}
{t('management.successfulActions') || 'Successful'}
{summary.summary.successfulActions}
{t('management.failedActions') || 'Failed'}
{summary.summary.failedActions}
{t('management.warnings') || 'Warnings'}
{summary.summary.warningActions}
{t('management.critical') || 'Critical'}
{summary.summary.criticalActions}
)} {/* Filters */}

{t('common.filters') || 'Filters'}

{/* Search */}
handleFilterChange('search', e.target.value)} placeholder={t('management.searchPlaceholder') || 'Search logs...'} className="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500" />
{/* Level */}
{/* Action */}
{/* Date Range */}
handleFilterChange('startDate', e.target.value)} className="flex-1 border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500" /> handleFilterChange('endDate', e.target.value)} className="flex-1 border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500" />
{pagination.totalCount} {t('management.totalEntries') || 'total entries'}
{/* Audit Logs Table */}
{loading ? (
{t('common.loading') || 'Loading...'}
) : error ? (
{t('common.error') || 'Error'}: {error}
) : auditLogs.length === 0 ? (
{t('management.noAuditLogs') || 'No audit logs found'}
) : (
{auditLogs.map((log) => ( ))}
{t('management.timestamp') || 'Timestamp'} {t('management.level') || 'Level'} {t('management.action') || 'Action'} {t('management.user') || 'User'} {t('management.tenant') || 'Tenant'} {t('management.message') || 'Message'} {t('management.success') || 'Success'} {t('management.ipAddress') || 'IP Address'}
{formatTimestamp(log.timestamp)} {log.level} {log.action} {log.username || '-'} {log.tenant_slug || '-'} {log.message} {getSuccessIndicator(log.success)} {log.ip_address || '-'}
)}
{/* Pagination */} {pagination.totalPages > 1 && (

{t('common.showing') || 'Showing'}{' '} {((pagination.currentPage - 1) * pagination.limit) + 1} {' '}{t('common.to') || 'to'}{' '} {Math.min(pagination.currentPage * pagination.limit, pagination.totalCount)} {' '}{t('common.of') || 'of'}{' '} {pagination.totalCount} {' '}{t('common.results') || 'results'}

)}
); }; export default AuditLogs;