import { useState, useEffect } from 'react'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Copy, ExternalLink } from 'lucide-react'; import { format } from 'date-fns'; import { toast } from 'sonner'; import { supabase } from '@/lib/supabaseClient'; interface Breadcrumb { timestamp: string; category: string; message: string; level?: string; sequence_order?: number; } interface ErrorDetails { request_id: string; created_at: string; error_type: string; error_message: string; error_stack?: string; endpoint: string; method: string; status_code: number; duration_ms: number; user_id?: string; request_breadcrumbs?: Breadcrumb[]; user_agent?: string; client_version?: string; timezone?: string; referrer?: string; ip_address_hash?: string; } interface ErrorDetailsModalProps { error: ErrorDetails; onClose: () => void; } export function ErrorDetailsModal({ error, onClose }: ErrorDetailsModalProps) { // Use breadcrumbs from error object if already fetched, otherwise they'll be empty const breadcrumbs = error.request_breadcrumbs || []; const copyErrorId = () => { navigator.clipboard.writeText(error.request_id); toast.success('Error ID copied to clipboard'); }; const copyErrorReport = () => { const report = ` Error Report ============ Request ID: ${error.request_id} Timestamp: ${format(new Date(error.created_at), 'PPpp')} Type: ${error.error_type} Endpoint: ${error.endpoint} Method: ${error.method} Status: ${error.status_code}${error.duration_ms != null ? `\nDuration: ${error.duration_ms}ms` : ''} Error Message: ${error.error_message} ${error.error_stack ? `Stack Trace:\n${error.error_stack}` : ''} `.trim(); navigator.clipboard.writeText(report); toast.success('Error report copied to clipboard'); }; return ( Error Details {error.error_type} Overview Stack Trace Breadcrumbs Environment
{error.request_id}

{format(new Date(error.created_at), 'PPpp')}

{error.endpoint}

{error.method}

{error.status_code}

{error.duration_ms != null && (

{error.duration_ms}ms

)} {error.user_id && ( )}

{error.error_message}

{error.error_stack ? (
                {error.error_stack}
              
) : (

No stack trace available

)}
{breadcrumbs && breadcrumbs.length > 0 ? (
{breadcrumbs .sort((a, b) => (a.sequence_order || 0) - (b.sequence_order || 0)) .map((crumb, index) => (
{crumb.category} {crumb.level || 'info'} {format(new Date(crumb.timestamp), 'HH:mm:ss.SSS')}

{crumb.message}

))}
) : (

No breadcrumbs recorded

)}
{error.user_agent && (

{error.user_agent}

)} {error.client_version && (

{error.client_version}

)} {error.timezone && (

{error.timezone}

)} {error.referrer && (

{error.referrer}

)} {error.ip_address_hash && (

{error.ip_address_hash}

)}
{!error.user_agent && !error.client_version && !error.timezone && !error.referrer && !error.ip_address_hash && (

No environment data available

)}
); }