import React, { useState } from 'react'; import { Table, Card, Typography, Space, Tag, DatePicker, Select, Input, Button, Row, Col, Alert, Timeline, } from 'antd'; import { AuditOutlined, SearchOutlined, FilterOutlined, UserOutlined, AppstoreOutlined, KeyOutlined, ClockCircleOutlined, CheckCircleOutlined, ExclamationCircleOutlined, DeleteOutlined, } from '@ant-design/icons'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; dayjs.extend(relativeTime); const { Title, Text } = Typography; const { RangePicker } = DatePicker; const { Option } = Select; interface AuditLogEntry { id: string; timestamp: string; user_id: string; action: string; resource_type: string; resource_id: string; status: 'success' | 'failure' | 'warning'; ip_address: string; user_agent: string; details: Record; } // Mock audit data for demonstration const mockAuditData: AuditLogEntry[] = [ { id: '1', timestamp: dayjs().subtract(1, 'hour').toISOString(), user_id: 'admin@example.com', action: 'CREATE_APPLICATION', resource_type: 'application', resource_id: 'com.example.newapp', status: 'success', ip_address: '192.168.1.100', user_agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', details: { app_link: 'https://newapp.example.com', owner: 'Development Team' } }, { id: '2', timestamp: dayjs().subtract(2, 'hours').toISOString(), user_id: 'user@example.com', action: 'CREATE_TOKEN', resource_type: 'token', resource_id: 'token-abc123', status: 'success', ip_address: '192.168.1.101', user_agent: 'curl/7.68.0', details: { app_id: 'com.example.app', permissions: ['repo.read', 'repo.write'] } }, { id: '3', timestamp: dayjs().subtract(3, 'hours').toISOString(), user_id: 'admin@example.com', action: 'DELETE_TOKEN', resource_type: 'token', resource_id: 'token-xyz789', status: 'success', ip_address: '192.168.1.100', user_agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', details: { app_id: 'com.example.oldapp', reason: 'Token compromised' } }, { id: '4', timestamp: dayjs().subtract(4, 'hours').toISOString(), user_id: 'user@example.com', action: 'VERIFY_TOKEN', resource_type: 'token', resource_id: 'token-def456', status: 'failure', ip_address: '192.168.1.102', user_agent: 'PostmanRuntime/7.28.4', details: { app_id: 'com.example.app', error: 'Token expired' } }, { id: '5', timestamp: dayjs().subtract(6, 'hours').toISOString(), user_id: 'admin@example.com', action: 'UPDATE_APPLICATION', resource_type: 'application', resource_id: 'com.example.app', status: 'success', ip_address: '192.168.1.100', user_agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', details: { changes: { callback_url: 'https://updated.example.com/callback' } } }, ]; const Audit: React.FC = () => { const [auditData, setAuditData] = useState(mockAuditData); const [filteredData, setFilteredData] = useState(mockAuditData); const [loading, setLoading] = useState(false); const [filters, setFilters] = useState({ dateRange: null as any, action: '', status: '', user: '', resourceType: '', }); const applyFilters = () => { let filtered = [...auditData]; if (filters.dateRange && filters.dateRange.length === 2) { const [start, end] = filters.dateRange; filtered = filtered.filter(entry => { const entryDate = dayjs(entry.timestamp); return entryDate.isAfter(start) && entryDate.isBefore(end); }); } if (filters.action) { filtered = filtered.filter(entry => entry.action === filters.action); } if (filters.status) { filtered = filtered.filter(entry => entry.status === filters.status); } if (filters.user) { filtered = filtered.filter(entry => entry.user_id.toLowerCase().includes(filters.user.toLowerCase()) ); } if (filters.resourceType) { filtered = filtered.filter(entry => entry.resource_type === filters.resourceType); } setFilteredData(filtered); }; const clearFilters = () => { setFilters({ dateRange: null, action: '', status: '', user: '', resourceType: '', }); setFilteredData(auditData); }; const getStatusIcon = (status: string) => { switch (status) { case 'success': return ; case 'failure': return ; case 'warning': return ; default: return ; } }; const getActionIcon = (action: string) => { if (action.includes('APPLICATION')) return ; if (action.includes('TOKEN')) return ; if (action.includes('USER')) return ; return ; }; const columns = [ { title: 'Timestamp', dataIndex: 'timestamp', key: 'timestamp', render: (timestamp: string) => (
{dayjs(timestamp).format('MMM DD, YYYY')}
{dayjs(timestamp).format('HH:mm:ss')}
), sorter: (a: AuditLogEntry, b: AuditLogEntry) => dayjs(a.timestamp).unix() - dayjs(b.timestamp).unix(), defaultSortOrder: 'descend' as const, }, { title: 'User', dataIndex: 'user_id', key: 'user_id', render: (userId: string) => (
{userId}
), }, { title: 'Action', dataIndex: 'action', key: 'action', render: (action: string) => (
{getActionIcon(action)} {action.replace(/_/g, ' ')}
), }, { title: 'Resource', key: 'resource', render: (_: any, record: AuditLogEntry) => (
{record.resource_type.toUpperCase()}
{record.resource_id}
), }, { title: 'Status', dataIndex: 'status', key: 'status', render: (status: string) => ( {status.toUpperCase()} ), }, { title: 'IP Address', dataIndex: 'ip_address', key: 'ip_address', render: (ip: string) => {ip}, }, ]; const expandedRowRender = (record: AuditLogEntry) => (
User Agent:
{record.user_agent}
Event ID:
{record.id}
Additional Details:
              {JSON.stringify(record.details, null, 2)}
            
); return (
Audit Log Monitor and track all system activities and security events
{/* Statistics Cards */}
{filteredData.length}
Total Events
{filteredData.filter(e => e.status === 'success').length}
Successful
{filteredData.filter(e => e.status === 'failure').length}
Failed
{new Set(filteredData.map(e => e.user_id)).size}
Unique Users
{/* Filters */}
}>
Date Range:
setFilters({ ...filters, dateRange: dates })} />
Action:
Status:
User:
setFilters({ ...filters, user: e.target.value })} allowClear />
Resource Type:
{/* Recent Activity Timeline */} {filteredData.slice(0, 5).map((entry) => (
{entry.action.replace(/_/g, ' ')}
{entry.user_id} • {dayjs(entry.timestamp).fromNow()}
{entry.resource_type} {entry.resource_id}
))}
{/* Audit Log Table */} `${range[0]}-${range[1]} of ${total} audit entries`, }} /> ); }; export default Audit;