mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 18:11:12 -05:00
Fix frontend JSONB references
This commit is contained in:
@@ -10,8 +10,8 @@ interface Breadcrumb {
|
||||
timestamp: string;
|
||||
category: string;
|
||||
message: string;
|
||||
level: string;
|
||||
data?: Record<string, unknown>;
|
||||
level?: string;
|
||||
sequence_order?: number;
|
||||
}
|
||||
|
||||
interface ErrorDetails {
|
||||
@@ -25,7 +25,7 @@ interface ErrorDetails {
|
||||
status_code: number;
|
||||
duration_ms: number;
|
||||
user_id?: string;
|
||||
breadcrumbs?: Breadcrumb[];
|
||||
request_breadcrumbs?: Breadcrumb[];
|
||||
environment_context?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
@@ -146,26 +146,26 @@ ${error.error_stack ? `Stack Trace:\n${error.error_stack}` : ''}
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="breadcrumbs">
|
||||
{error.breadcrumbs && error.breadcrumbs.length > 0 ? (
|
||||
{error.request_breadcrumbs && error.request_breadcrumbs.length > 0 ? (
|
||||
<div className="space-y-2">
|
||||
{error.breadcrumbs.map((crumb, index) => (
|
||||
<div key={index} className="border-l-2 border-primary pl-4 py-2">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{crumb.category}
|
||||
</Badge>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{format(new Date(crumb.timestamp), 'HH:mm:ss.SSS')}
|
||||
</span>
|
||||
{error.request_breadcrumbs
|
||||
.sort((a, b) => (a.sequence_order || 0) - (b.sequence_order || 0))
|
||||
.map((crumb, index) => (
|
||||
<div key={index} className="border-l-2 border-primary pl-4 py-2">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{crumb.category}
|
||||
</Badge>
|
||||
<Badge variant={crumb.level === 'error' ? 'destructive' : 'secondary'} className="text-xs">
|
||||
{crumb.level || 'info'}
|
||||
</Badge>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{format(new Date(crumb.timestamp), 'HH:mm:ss.SSS')}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm">{crumb.message}</p>
|
||||
</div>
|
||||
<p className="text-sm">{crumb.message}</p>
|
||||
{crumb.data && (
|
||||
<pre className="text-xs text-muted-foreground mt-1">
|
||||
{JSON.stringify(crumb.data, null, 2)}
|
||||
</pre>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-muted-foreground">No breadcrumbs recorded</p>
|
||||
|
||||
@@ -8,8 +8,18 @@ import { format } from 'date-fns';
|
||||
import { handleError } from '@/lib/errorHandler';
|
||||
import { AuditLogEntry } from '@/types/database';
|
||||
|
||||
interface ProfileChangeField {
|
||||
field_name: string;
|
||||
old_value: string | null;
|
||||
new_value: string | null;
|
||||
}
|
||||
|
||||
interface ProfileAuditLogWithChanges extends Omit<AuditLogEntry, 'changes'> {
|
||||
profile_change_fields?: ProfileChangeField[];
|
||||
}
|
||||
|
||||
export function ProfileAuditLog(): React.JSX.Element {
|
||||
const [logs, setLogs] = useState<AuditLogEntry[]>([]);
|
||||
const [logs, setLogs] = useState<ProfileAuditLogWithChanges[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -22,13 +32,18 @@ export function ProfileAuditLog(): React.JSX.Element {
|
||||
.from('profile_audit_log')
|
||||
.select(`
|
||||
*,
|
||||
profiles!user_id(username, display_name)
|
||||
profiles!user_id(username, display_name),
|
||||
profile_change_fields(
|
||||
field_name,
|
||||
old_value,
|
||||
new_value
|
||||
)
|
||||
`)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(50);
|
||||
|
||||
if (error) throw error;
|
||||
setLogs((data || []) as AuditLogEntry[]);
|
||||
setLogs((data || []) as ProfileAuditLogWithChanges[]);
|
||||
} catch (error: unknown) {
|
||||
handleError(error, { action: 'Load audit logs' });
|
||||
} finally {
|
||||
@@ -71,7 +86,20 @@ export function ProfileAuditLog(): React.JSX.Element {
|
||||
<Badge variant="secondary">{log.action}</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<pre className="text-xs">{JSON.stringify(log.changes || {}, null, 2)}</pre>
|
||||
{log.profile_change_fields && log.profile_change_fields.length > 0 ? (
|
||||
<div className="space-y-1">
|
||||
{log.profile_change_fields.map((change, idx) => (
|
||||
<div key={idx} className="text-xs">
|
||||
<span className="font-medium">{change.field_name}:</span>{' '}
|
||||
<span className="text-muted-foreground">{change.old_value || 'null'}</span>
|
||||
{' → '}
|
||||
<span className="text-foreground">{change.new_value || 'null'}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-xs text-muted-foreground">No changes</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-sm text-muted-foreground">
|
||||
{format(new Date(log.created_at), 'PPpp')}
|
||||
|
||||
@@ -99,7 +99,15 @@ export function DataExportTab() {
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from('profile_audit_log')
|
||||
.select('id, action, changes, created_at, changed_by, ip_address_hash, user_agent')
|
||||
.select(`
|
||||
id,
|
||||
action,
|
||||
created_at,
|
||||
changed_by,
|
||||
ip_address_hash,
|
||||
user_agent,
|
||||
profile_change_fields(field_name, old_value, new_value)
|
||||
`)
|
||||
.eq('user_id', user.id)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(10);
|
||||
@@ -115,15 +123,27 @@ export function DataExportTab() {
|
||||
}
|
||||
|
||||
// Transform the data to match our type
|
||||
const activityData: ActivityLogEntry[] = (data || []).map(item => ({
|
||||
id: item.id,
|
||||
action: item.action,
|
||||
changes: item.changes as Record<string, any>,
|
||||
created_at: item.created_at,
|
||||
changed_by: item.changed_by,
|
||||
ip_address_hash: item.ip_address_hash || undefined,
|
||||
user_agent: item.user_agent || undefined
|
||||
}));
|
||||
const activityData: ActivityLogEntry[] = (data || []).map(item => {
|
||||
const changes: Record<string, any> = {};
|
||||
if (item.profile_change_fields) {
|
||||
for (const field of item.profile_change_fields) {
|
||||
changes[field.field_name] = {
|
||||
old: field.old_value,
|
||||
new: field.new_value
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
action: item.action,
|
||||
changes,
|
||||
created_at: item.created_at,
|
||||
changed_by: item.changed_by,
|
||||
ip_address_hash: item.ip_address_hash || undefined,
|
||||
user_agent: item.user_agent || undefined
|
||||
};
|
||||
});
|
||||
|
||||
setRecentActivity(activityData);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user