'use client'; import React from 'react'; import { AlertCircle, RefreshCw, ArrowLeft, Home, Bug } from 'lucide-react'; import { ErrorDisplayProps } from './types'; import { ApiError } from '@/lib/api/base/ApiError'; /** * ErrorDisplay Component * * Provides consistent error state handling with multiple variants: * - full-screen: Centered error page with full viewport * - card: Compact card-style error display * - inline: Small inline error message * * Features: * - Automatic error message extraction * - Retry functionality * - Navigation options (back, home) * - Technical details toggle * - API error specific handling */ export function ErrorDisplay({ error, onRetry, variant = 'full-screen', actions = [], showRetry = true, showNavigation = true, hideTechnicalDetails = false, className = '', }: ErrorDisplayProps) { // Extract error information const getErrorInfo = () => { const isApiError = error instanceof ApiError; return { title: isApiError ? 'API Error' : 'Unexpected Error', message: error.message || 'Something went wrong', statusCode: isApiError ? error.context.statusCode : undefined, details: isApiError ? error.context.responseText : undefined, isApiError, }; }; const errorInfo = getErrorInfo(); // Default actions const defaultActions = [ ...(showRetry && onRetry ? [{ label: 'Retry', onClick: onRetry, variant: 'primary' as const }] : []), ...(showNavigation ? [ { label: 'Go Back', onClick: () => window.history.back(), variant: 'secondary' as const }, { label: 'Home', onClick: () => window.location.href = '/', variant: 'outline' as const }, ] : []), ...actions, ]; // Render different variants switch (variant) { case 'full-screen': return (
{/* Icon */}
{/* Title */}

{errorInfo.title}

{/* Message */}

{errorInfo.message}

{/* API Error Details */} {errorInfo.isApiError && errorInfo.statusCode && (
HTTP {errorInfo.statusCode} {errorInfo.details && !hideTechnicalDetails && ( - {errorInfo.details} )}
)} {/* Actions */} {defaultActions.length > 0 && (
{defaultActions.map((action, index) => ( ))}
)} {/* Technical Details Toggle (for development) */} {!hideTechnicalDetails && process.env.NODE_ENV === 'development' && error.stack && (
Technical Details
                  {error.stack}
                
)}
); case 'card': return (
{/* Icon */}
{/* Content */}

{errorInfo.title}

{errorInfo.message}

{/* API Error Details */} {errorInfo.isApiError && errorInfo.statusCode && (
HTTP {errorInfo.statusCode} {errorInfo.details && !hideTechnicalDetails && ` - ${errorInfo.details}`}
)} {/* Actions */} {defaultActions.length > 0 && (
{defaultActions.map((action, index) => ( ))}
)}
); case 'inline': return (
{errorInfo.message} {onRetry && showRetry && ( )}
); default: return null; } } /** * Convenience component for API error display */ export function ApiErrorDisplay({ error, onRetry, variant = 'full-screen', hideTechnicalDetails = false, }: { error: ApiError; onRetry?: () => void; variant?: 'full-screen' | 'card' | 'inline'; hideTechnicalDetails?: boolean; }) { return ( ); } /** * Convenience component for network error display */ export function NetworkErrorDisplay({ onRetry, variant = 'full-screen', }: { onRetry?: () => void; variant?: 'full-screen' | 'card' | 'inline'; }) { return ( ); }