2import { useState, useEffect } from "react";
3import { Icon } from '@/contexts/IconContext';
12 status: "success" | "error" | "warning";
15export default function AuditPage() {
16 const [auditLog, setAuditLog] = useState<AuditEntry[]>([]);
17 const [loading, setLoading] = useState(true);
18 const [filter, setFilter] = useState<string>("all");
19 const [searchTerm, setSearchTerm] = useState("");
22 // Simulate loading audit log
23 // In production, this would fetch from an API
24 const mockData: AuditEntry[] = [
27 timestamp: new Date("2024-12-24T10:30:00"),
28 user: "admin@everydaypos.com",
30 resource: "Authentication",
31 details: "User logged in successfully",
36 timestamp: new Date("2024-12-24T10:35:00"),
37 user: "admin@everydaypos.com",
38 action: "STOCK_ADJUSTMENT",
40 details: "Adjusted stock for Product ID 12345 by +10",
45 timestamp: new Date("2024-12-24T10:40:00"),
46 user: "admin@everydaypos.com",
47 action: "SALE_CREATED",
49 details: "Created sale SID 98765 for $125.50",
54 timestamp: new Date("2024-12-24T10:45:00"),
55 user: "admin@everydaypos.com",
57 resource: "Fieldpine API",
58 details: "Failed to connect to Fieldpine server - timeout",
63 timestamp: new Date("2024-12-24T10:50:00"),
64 user: "admin@everydaypos.com",
65 action: "PRODUCT_UPDATE",
67 details: "Updated price for Product ID 67890",
73 setAuditLog(mockData);
78 const filteredLog = auditLog.filter(entry => {
79 const matchesFilter = filter === "all" || entry.status === filter;
81 entry.action.toLowerCase().includes(searchTerm.toLowerCase()) ||
82 entry.resource.toLowerCase().includes(searchTerm.toLowerCase()) ||
83 entry.details.toLowerCase().includes(searchTerm.toLowerCase()) ||
84 entry.user.toLowerCase().includes(searchTerm.toLowerCase());
85 return matchesFilter && matchesSearch;
88 const getStatusColor = (status: string) => {
91 return "bg-success/10 text-success border-success/30";
93 return "bg-danger/10 text-danger border-danger/30";
95 return "bg-warn/10 text-warn border-warn/30";
97 return "bg-surface-2 text-muted border-border";
101 const getStatusIcon = (status: string) => {
115 <div className="min-h-screen bg-bg">
116 <div className="max-w-7xl mx-auto p-6">
118 <div className="mb-8">
119 <h1 className="text-3xl font-bold text-text mb-2 flex items-center gap-3">
120 <Icon name="receipt_long" size={32} />
123 <p className="text-muted">Audit trail of system activities and API transactions</p>
127 <div className="bg-surface rounded-lg shadow-sm border border-border p-4 mb-6">
128 <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
130 <label className="block text-sm font-medium text-text mb-2">
136 onChange={(e) => setSearchTerm(e.target.value)}
137 placeholder="Search actions, resources, or details..."
138 className="w-full px-3 py-2 border border-border rounded-md focus:outline-none focus:ring-2 focus:ring-brand"
142 <label className="block text-sm font-medium text-text mb-2">
147 onChange={(e) => setFilter(e.target.value)}
148 className="w-full px-3 py-2 border border-border rounded-md focus:outline-none focus:ring-2 focus:ring-brand"
150 <option value="all">All Status</option>
151 <option value="success">Success</option>
152 <option value="error">Error</option>
153 <option value="warning">Warning</option>
160 <div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
161 <div className="bg-surface rounded-lg shadow-sm border border-border p-4">
162 <div className="text-sm text-muted mb-1">Total Events</div>
163 <div className="text-2xl font-bold text-text">{auditLog.length}</div>
165 <div className="bg-green-50 rounded-lg shadow-sm border border-green-200 p-4">
166 <div className="text-sm text-green-600 mb-1">Success</div>
167 <div className="text-2xl font-bold text-green-900">
168 {auditLog.filter(e => e.status === "success").length}
171 <div className="bg-red-50 rounded-lg shadow-sm border border-red-200 p-4">
172 <div className="text-sm text-red-600 mb-1">Errors</div>
173 <div className="text-2xl font-bold text-red-900">
174 {auditLog.filter(e => e.status === "error").length}
177 <div className="bg-yellow-50 rounded-lg shadow-sm border border-yellow-200 p-4">
178 <div className="text-sm text-yellow-600 mb-1">Warnings</div>
179 <div className="text-2xl font-bold text-yellow-900">
180 {auditLog.filter(e => e.status === "warning").length}
185 {/* Audit Log Table */}
186 <div className="bg-surface rounded-lg shadow-sm border border-border overflow-hidden">
188 <div className="p-12 text-center text-muted">
191 ) : filteredLog.length === 0 ? (
192 <div className="p-12 text-center text-muted">
193 {searchTerm ? `No events match "${searchTerm}"` : "No events found"}
196 <div className="overflow-x-auto">
197 <table className="min-w-full divide-y divide-border">
198 <thead className="bg-[var(--brand)] text-surface">
200 <th className="px-6 py-3 text-left text-xs font-medium text-muted uppercase tracking-wider">
203 <th className="px-6 py-3 text-left text-xs font-medium text-muted uppercase tracking-wider">
206 <th className="px-6 py-3 text-left text-xs font-medium text-muted uppercase tracking-wider">
209 <th className="px-6 py-3 text-left text-xs font-medium text-muted uppercase tracking-wider">
212 <th className="px-6 py-3 text-left text-xs font-medium text-muted uppercase tracking-wider">
215 <th className="px-6 py-3 text-left text-xs font-medium text-muted uppercase tracking-wider">
220 <tbody className="bg-surface divide-y divide-border">
221 {filteredLog.map((entry) => (
222 <tr key={entry.id} className="hover:bg-surface-2">
223 <td className="px-6 py-4 whitespace-nowrap text-sm text-text">
224 {entry.timestamp.toLocaleString()}
226 <td className="px-6 py-4 whitespace-nowrap text-sm text-muted">
229 <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-text">
232 <td className="px-6 py-4 whitespace-nowrap text-sm text-muted">
235 <td className="px-6 py-4 text-sm text-muted">
238 <td className="px-6 py-4 whitespace-nowrap">
240 className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border ${getStatusColor(
244 <span className="mr-1">{getStatusIcon(entry.status)}</span>
245 {entry.status.toUpperCase()}
257 <div className="mt-6 bg-info/10 border border-info/30 rounded-lg p-4">
258 <h3 className="font-semibold text-info mb-2">About the Audit Log</h3>
259 <p className="text-info/90 text-sm mb-2">
260 The transaction log tracks all system activities including user actions, API calls,
261 and system events. This helps with:
263 <ul className="list-disc list-inside text-info/90 text-sm space-y-1 ml-2">
264 <li>Security monitoring and compliance</li>
265 <li>Debugging and troubleshooting</li>
266 <li>Performance analysis</li>
267 <li>User activity tracking</li>
269 <p className="text-info/80 text-xs mt-3">
270 <strong>Note:</strong> Currently showing mock data. Production will log real transactions.