60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
|
|
import { Button } from '../button';
|
||
|
|
import { AlertTriangle, RefreshCw } from 'lucide-react';
|
||
|
|
|
||
|
|
export interface LazyErrorFallbackProps {
|
||
|
|
pageName: string;
|
||
|
|
error?: Error;
|
||
|
|
onRetry?: () => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getErrorMessage(error: Error | undefined): string {
|
||
|
|
try {
|
||
|
|
if (!error)
|
||
|
|
return 'Currently unable to access this component. Please check your connection.';
|
||
|
|
if (typeof error === 'string') return error;
|
||
|
|
if (error instanceof Error) return error.message;
|
||
|
|
return String(error);
|
||
|
|
} catch {
|
||
|
|
return 'An unknown error occurred.';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function LazyErrorFallback({
|
||
|
|
pageName,
|
||
|
|
error,
|
||
|
|
onRetry,
|
||
|
|
}: LazyErrorFallbackProps) {
|
||
|
|
return (
|
||
|
|
<div className="flex flex-col items-center justify-center min-h-layout-page-sm p-8 text-center animate-in fade-in zoom-in duration-300">
|
||
|
|
<div className="bg-kodo-ink/50 border border-kodo-steel/30 rounded-xl p-8 max-w-md w-full shadow-lg backdrop-blur-sm">
|
||
|
|
<div className="w-16 h-16 bg-kodo-red/10 rounded-full flex items-center justify-center mx-auto mb-6">
|
||
|
|
<AlertTriangle className="h-8 w-8 text-kodo-red" />
|
||
|
|
</div>
|
||
|
|
<h2 className="text-xl font-bold mb-2">Failed to load {pageName}</h2>
|
||
|
|
<p className="text-kodo-content-dim mb-6 text-sm">
|
||
|
|
{getErrorMessage(error)}
|
||
|
|
</p>
|
||
|
|
<div className="flex flex-col gap-3">
|
||
|
|
{onRetry && (
|
||
|
|
<Button
|
||
|
|
onClick={onRetry}
|
||
|
|
variant="outline"
|
||
|
|
className="w-full flex items-center justify-center gap-2"
|
||
|
|
>
|
||
|
|
<RefreshCw className="h-4 w-4" />
|
||
|
|
Try Again
|
||
|
|
</Button>
|
||
|
|
)}
|
||
|
|
<Button
|
||
|
|
onClick={() => window.location.reload()}
|
||
|
|
variant="default"
|
||
|
|
className="w-full flex items-center justify-center gap-2"
|
||
|
|
>
|
||
|
|
Refresh Page
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|