GrantForge Bot
Deploy to Hugging Face
afd56bc
import React, { Component, ErrorInfo, ReactNode } from 'react';
import { AlertTriangle, RefreshCw } from 'lucide-react';
interface Props {
children?: ReactNode;
}
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 {
// Zaktualizuj stan tak, aby następny render pokazał UI dla błędu.
return { hasError: true, error };
}
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('Nieobsłużony błąd interfejsu złapany przez ErrorBoundary:', error, errorInfo);
// Tutaj można by też wysłać log błędu do zewnętrznego serwisu np. Sentry / Datadog
}
private handleReload = () => {
window.location.reload();
};
public render() {
if (this.state.hasError) {
return (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: 'var(--bg-base)', color: 'var(--text-primary)' }}>
<div className="glass-card" style={{ padding: '3rem', textAlign: 'center', maxWidth: '500px', borderTop: '4px solid #EF4444' }}>
<div style={{ background: 'rgba(239,68,68,0.1)', padding: '1rem', borderRadius: '50%', display: 'inline-flex', marginBottom: '1.5rem' }}>
<AlertTriangle size={48} color="#EF4444" />
</div>
<h2 style={{ fontSize: '1.5rem', marginBottom: '1rem', fontWeight: 800 }}>Ups! Coś poszło nie tak.</h2>
<p style={{ color: 'var(--text-secondary)', marginBottom: '2rem', lineHeight: '1.6' }}>
Wystąpił nieoczekiwany błąd w interfejsie użytkownika. Nasi inżynierowie zostali powiadomieni (w trybie testowym).
</p>
<p style={{ fontSize: '0.85rem', color: '#EF4444', background: 'rgba(239, 68, 68, 0.1)', padding: '0.8rem', borderRadius: '8px', marginBottom: '2rem', textAlign: 'left', wordBreak: 'break-all' }}>
<code>{this.state.error?.message || "Unknown error"}</code>
</p>
<button
onClick={this.handleReload}
className="btn btn-primary"
style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5rem', padding: '0.8rem 1.5rem' }}
>
<RefreshCw size={18} /> Odśwież stronę
</button>
</div>
</div>
);
}
return this.props.children;
}
}