saas-veille / components /shared /ErrorBoundary.tsx
PrestaGhis's picture
Create shared/ErrorBoundary.tsx
3fd7788 verified
'use client'
import React, { Component, ErrorInfo, ReactNode } from 'react'
import { AlertCircle, RefreshCw, Home } from 'lucide-react'
interface Props {
children: ReactNode
name?: string
}
interface State {
hasError: boolean
error: Error | null
}
export class ErrorBoundary extends Component<Props, State> {
public state: State = {
hasError: false,
error: null
}
public static getDerivedStateFromError(error: Error): State {
return { hasError: true, error }
}
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error(`Uncaught error in ${this.props.name || 'Component'}:`, error, errorInfo)
}
public render() {
if (this.state.hasError) {
return (
<div className="p-8 rounded-3xl bg-red-500/5 border border-red-500/20 text-center space-y-4 my-4">
<div className="w-16 h-16 rounded-full bg-red-500/20 flex items-center justify-center mx-auto shadow-lg shadow-red-500/10">
<AlertCircle className="text-red-400" size={32} />
</div>
<div className="space-y-2">
<h2 className="text-xl font-black theme-title uppercase tracking-tight">Oups ! Une erreur est survenue</h2>
<p className="text-sm theme-description opacity-70 max-w-md mx-auto leading-relaxed">
L'interface a rencontré une difficulté technique (React Error #31 ou similaire).
Cela arrive souvent lors d'un changement de structure de données.
</p>
</div>
{this.state.error && (
<div className="bg-black/40 p-4 rounded-2xl border border-white/5 text-left overflow-auto max-h-40 scrollbar-thin">
<p className="text-[10px] font-mono text-red-300 whitespace-pre-wrap">
{this.state.error.toString()}
</p>
</div>
)}
<div className="flex items-center justify-center gap-3 pt-4">
<button
onClick={() => window.location.reload()}
className="flex items-center gap-2 px-6 py-2.5 bg-red-500 text-white rounded-xl text-xs font-black uppercase tracking-widest hover:bg-red-600 transition-all shadow-lg shadow-red-500/20"
>
<RefreshCw size={16} />
Recharger la page
</button>
<button
onClick={() => window.location.href = '/'}
className="flex items-center gap-2 px-6 py-2.5 bg-white/5 border border-white/10 text-white rounded-xl text-xs font-black uppercase tracking-widest hover:bg-white/10 transition-all"
>
<Home size={16} />
Retour Accueil
</button>
</div>
<p className="text-[10px] opacity-30 italic">
ID de l'erreur : {this.props.name || 'Global'} - {new Date().toLocaleTimeString()}
</p>
</div>
)
}
return this.props.children
}
}