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 (
| {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 || '-'} |
{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'}