87 lines
2.5 KiB
TypeScript
87 lines
2.5 KiB
TypeScript
import React, { Component, ErrorInfo, ReactNode } from 'react';
|
|
import { AlertTriangle, RefreshCw } from 'lucide-react';
|
|
|
|
interface Props {
|
|
children?: ReactNode;
|
|
}
|
|
|
|
interface State {
|
|
hasError: boolean;
|
|
error?: Error;
|
|
}
|
|
|
|
export class ErrorBoundary extends Component<Props, State> {
|
|
public state: State = {
|
|
hasError: false
|
|
};
|
|
|
|
public static getDerivedStateFromError(error: Error): State {
|
|
return { hasError: true, error };
|
|
}
|
|
|
|
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
console.error('Uncaught error:', error, errorInfo);
|
|
}
|
|
|
|
public render() {
|
|
if (this.state.hasError) {
|
|
return (
|
|
<div style={{
|
|
height: '100vh',
|
|
width: '100vw',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
background: 'var(--base-bg)',
|
|
color: 'var(--text-primary)',
|
|
padding: '40px',
|
|
textAlign: 'center',
|
|
zIndex: 9999
|
|
}}>
|
|
<AlertTriangle size={64} color="var(--alert-red)" style={{ marginBottom: '24px' }} />
|
|
<h1 style={{ fontSize: '1.5rem', marginBottom: '16px' }}>Terminal Error Detected</h1>
|
|
<p style={{ color: 'var(--text-secondary)', maxWidth: '500px', marginBottom: '32px' }}>
|
|
A critical failure occurred in the module hierarchy. The security perimeter remains intact, but the interface requires a full system reset.
|
|
</p>
|
|
{this.state.error && (
|
|
<div style={{
|
|
background: 'rgba(255, 59, 59, 0.05)',
|
|
border: '1px solid rgba(255, 59, 59, 0.2)',
|
|
borderRadius: '8px',
|
|
padding: '12px',
|
|
fontFamily: 'monospace',
|
|
fontSize: '0.8rem',
|
|
color: 'var(--alert-red)',
|
|
marginBottom: '32px',
|
|
maxWidth: '80%'
|
|
}}>
|
|
{this.state.error.toString()}
|
|
</div>
|
|
)}
|
|
<button
|
|
onClick={() => window.location.reload()}
|
|
style={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: '8px',
|
|
padding: '12px 24px',
|
|
background: 'var(--accent-cyan)',
|
|
border: 'none',
|
|
borderRadius: '8px',
|
|
color: '#000',
|
|
fontWeight: 700,
|
|
cursor: 'pointer'
|
|
}}
|
|
>
|
|
<RefreshCw size={18} />
|
|
REBOOT SYSTEM
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return this.props.children;
|
|
}
|
|
}
|