turash/bugulma/frontend/components/ui/ModuleErrorBoundary.tsx

60 lines
2.0 KiB
TypeScript

import { Component, ErrorInfo, ReactNode } from 'react';
import { classComponentT as t } from '@/lib/class-component-utils';
import { XCircle } from 'lucide-react';
import Button from '@/components/ui/Button.tsx';
import { Text, Heading } from '@/components/ui/Typography.tsx';
import { Stack } from '@/components/ui/layout';
interface Props {
children?: ReactNode;
moduleName?: string;
}
interface State {
hasError: boolean;
}
class ModuleErrorBoundary extends Component<Props, State> {
// FIX: Replaced constructor with a class property for state initialization. This is a more modern and robust approach in class components and resolves the reported errors regarding `this.state` and `this.props` not being available.
state: State = { hasError: false };
static getDerivedStateFromError(): State {
return { hasError: true };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error(`Error in ${this.props.moduleName || 'component'}:`, error, errorInfo);
}
// FIX: Using an arrow function to automatically bind 'this'.
handleReset = () => {
this.setState({ hasError: false });
};
render() {
if (this.state.hasError) {
const moduleName = this.props.moduleName || 'this module';
return (
<Stack
align="center"
justify="center"
spacing="sm"
className="h-full bg-muted/50 p-4 text-center rounded-lg border border-dashed border-destructive/50"
>
<XCircle className="h-4 h-8 text-current text-destructive w-4 w-8" />
<Heading level="h4" className="text-destructive">
{t('moduleErrorBoundary.title', { moduleName })}
</Heading>
<Text variant="muted">{t('moduleErrorBoundary.subtitle')}</Text>
<Button onClick={this.handleReset} variant="outline" size="sm" className="mt-2">
{t('moduleErrorBoundary.cta')}
</Button>
</Stack>
);
}
return this.props.children;
}
}
export default ModuleErrorBoundary;