mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:31:12 -05:00
87 lines
2.7 KiB
TypeScript
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>
|
|
);
|
|
}
|