import { useState, useMemo } from 'react' import { AdminLayout } from '../Admin' import { Badge } from '../../../design-system/primitives/Badge/Badge' import { DateRangePicker } from '../../../design-system/primitives/DateRangePicker/DateRangePicker' import { Input } from '../../../design-system/primitives/Input/Input' import { Select } from '../../../design-system/primitives/Select/Select' import { MonoText } from '../../../design-system/primitives/MonoText/MonoText' import { CodeBlock } from '../../../design-system/primitives/CodeBlock/CodeBlock' import { Pagination } from '../../../design-system/primitives/Pagination/Pagination' import type { DateRange } from '../../../design-system/utils/timePresets' import { AUDIT_EVENTS, type AuditEvent } from './auditMocks' import styles from './AuditLog.module.css' const CATEGORIES = [ { value: '', label: 'All categories' }, { value: 'INFRA', label: 'INFRA' }, { value: 'AUTH', label: 'AUTH' }, { value: 'USER_MGMT', label: 'USER_MGMT' }, { value: 'CONFIG', label: 'CONFIG' }, ] const PAGE_SIZE = 10 function formatTimestamp(iso: string): string { return new Date(iso).toLocaleString('en-GB', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, }) } const now = Date.now() const INITIAL_RANGE: DateRange = { from: new Date(now - 7 * 24 * 3600_000).toISOString().slice(0, 16), to: new Date(now).toISOString().slice(0, 16), } export function AuditLog() { const [dateRange, setDateRange] = useState(INITIAL_RANGE) const [userFilter, setUserFilter] = useState('') const [categoryFilter, setCategoryFilter] = useState('') const [searchFilter, setSearchFilter] = useState('') const [page, setPage] = useState(1) const [expandedId, setExpandedId] = useState(null) const filtered = useMemo(() => { const from = new Date(dateRange.from).getTime() const to = new Date(dateRange.to).getTime() return AUDIT_EVENTS.filter((e) => { const ts = new Date(e.timestamp).getTime() if (ts < from || ts > to) return false if (userFilter && !e.username.toLowerCase().includes(userFilter.toLowerCase())) return false if (categoryFilter && e.category !== categoryFilter) return false if (searchFilter) { const q = searchFilter.toLowerCase() if (!e.action.toLowerCase().includes(q) && !e.target.toLowerCase().includes(q)) return false } return true }) }, [dateRange, userFilter, categoryFilter, searchFilter]) const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE)) const pageEvents = filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE) return (

Audit Log

{ setDateRange(r); setPage(1) }} /> { setUserFilter(e.target.value); setPage(1) }} onClear={() => { setUserFilter(''); setPage(1) }} className={styles.filterInput} /> { setSearchFilter(e.target.value); setPage(1) }} onClear={() => { setSearchFilter(''); setPage(1) }} className={styles.filterInput} />
{pageEvents.map((event) => ( setExpandedId(expandedId === event.id ? null : event.id)} /> ))} {pageEvents.length === 0 && ( )}
Timestamp User Category Action Target Result
No events match the current filters.
{totalPages > 1 && (
)}
) } function EventRow({ event, expanded, onToggle }: { event: AuditEvent; expanded: boolean; onToggle: () => void }) { return ( <> {formatTimestamp(event.timestamp)} {event.username} {event.action} {event.target} {expanded && (
IP Address {event.ipAddress}
User Agent {event.userAgent}
Detail
)} ) }