Files
thrilltrack-explorer/src/components/admin/ProfileAuditLog.tsx
2025-10-21 16:01:45 +00:00

87 lines
2.7 KiB
TypeScript

import { useState, useEffect } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { Badge } from '@/components/ui/badge';
import { Loader2 } from 'lucide-react';
import { format } from 'date-fns';
import { handleError } from '@/lib/errorHandler';
import { AuditLogEntry } from '@/types/database';
export function ProfileAuditLog() {
const [logs, setLogs] = useState<AuditLogEntry[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchAuditLogs();
}, []);
const fetchAuditLogs = async () => {
try {
const { data, error } = await supabase
.from('profile_audit_log')
.select(`
*,
profiles!user_id(username, display_name)
`)
.order('created_at', { ascending: false })
.limit(50);
if (error) throw error;
setLogs((data || []) as AuditLogEntry[]);
} catch (error: unknown) {
handleError(error, { action: 'Load audit logs' });
} finally {
setLoading(false);
}
};
if (loading) {
return (
<Card>
<CardContent className="flex items-center justify-center py-8">
<Loader2 className="w-6 h-6 animate-spin" />
</CardContent>
</Card>
);
}
return (
<Card>
<CardHeader>
<CardTitle>Profile Audit Log</CardTitle>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>User</TableHead>
<TableHead>Action</TableHead>
<TableHead>Changes</TableHead>
<TableHead>Date</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{logs.map((log) => (
<TableRow key={log.id}>
<TableCell>
{(log as { profiles?: { display_name?: string; username?: string } }).profiles?.display_name || (log as { profiles?: { username?: string } }).profiles?.username || 'Unknown'}
</TableCell>
<TableCell>
<Badge variant="secondary">{log.action}</Badge>
</TableCell>
<TableCell>
<pre className="text-xs">{JSON.stringify(log.changes || {}, null, 2)}</pre>
</TableCell>
<TableCell className="text-sm text-muted-foreground">
{format(new Date(log.created_at), 'PPpp')}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
);
}