c9fe2bd9fe
- Add servers list page and missing routes (servers, settings redirect, account security)
- Fix members page .map error (API returns { data } wrapper, not flat array)
- Fix auth store fetchUser expecting flat User but API returns { user } wrapper
- Add node token display dialog after creation
- Add allocation management UI to node detail page
- Add account security page with password change
- Add change-password API endpoint
- Add node servers and stats API endpoints
- Fix config save using PATCH instead of PUT, add api.put method
- Fix audit logs field name mismatch (userName vs username)
- Replace admin nodes page to avoid orgId dependency
- Remove duplicate sidebar nav items
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { api } from '@/lib/api';
|
|
import { Card, CardContent } from '@/components/ui/card';
|
|
import { Badge } from '@/components/ui/badge';
|
|
|
|
interface AuditLog {
|
|
id: string;
|
|
action: string;
|
|
userName: string;
|
|
ipAddress: string | null;
|
|
metadata: Record<string, unknown>;
|
|
createdAt: string;
|
|
}
|
|
|
|
interface PaginatedResponse<T> {
|
|
data: T[];
|
|
meta: { total: number };
|
|
}
|
|
|
|
export function AdminAuditLogsPage() {
|
|
const { data } = useQuery({
|
|
queryKey: ['admin-audit-logs'],
|
|
queryFn: () => api.get<PaginatedResponse<AuditLog>>('/admin/audit-logs'),
|
|
});
|
|
|
|
const logs = data?.data ?? [];
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<h1 className="text-2xl font-bold">Audit Logs</h1>
|
|
<Card>
|
|
<CardContent className="p-0">
|
|
<div className="divide-y">
|
|
{logs.map((log) => (
|
|
<div key={log.id} className="flex items-center justify-between px-4 py-3">
|
|
<div className="flex items-center gap-3">
|
|
<Badge variant="outline">{log.action}</Badge>
|
|
<span className="text-sm">
|
|
<span className="font-medium">{log.userName}</span>
|
|
{log.ipAddress && (
|
|
<span className="text-muted-foreground"> from {log.ipAddress}</span>
|
|
)}
|
|
</span>
|
|
</div>
|
|
<span className="text-xs text-muted-foreground">
|
|
{new Date(log.createdAt).toLocaleString()}
|
|
</span>
|
|
</div>
|
|
))}
|
|
{logs.length === 0 && (
|
|
<div className="py-12 text-center text-muted-foreground">No audit logs</div>
|
|
)}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|