obs-ss-plugin-webui/components/ErrorBoundary.tsx
Decobus b6ff9a3cb6
Some checks failed
Lint and Build / build (20) (pull_request) Failing after 35s
Lint and Build / build (22) (pull_request) Failing after 51s
Implement professional error handling and user feedback system
Major UX Improvements:
- Replace all alert() dialogs with elegant toast notifications
- Add comprehensive loading states for all async operations
- Implement client-side form validation with visual feedback
- Add React Error Boundary for graceful error recovery

Components Added:
- Toast notification system with success/error/warning/info types
- useToast hook for easy notification management
- ErrorBoundary component with development error details
- Form validation with real-time feedback

User Experience:
- Professional toast notifications instead of browser alerts
- Loading indicators prevent double-clicks and show progress
- Immediate validation feedback prevents submission errors
- Graceful error recovery with retry options
- Enhanced accessibility with proper ARIA labels

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 05:39:21 -04:00

76 lines
No EOL
2.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { Component, ErrorInfo, ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback?: 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('ErrorBoundary caught an error:', error, errorInfo);
}
public render() {
if (this.state.hasError) {
if (this.props.fallback) {
return this.props.fallback;
}
return (
<div className="glass p-8 text-center max-w-md mx-auto mt-8">
<div className="text-6xl mb-4"></div>
<h2 className="text-xl font-semibold mb-4 text-red-400">
Something went wrong
</h2>
<p className="text-white/80 mb-6">
An unexpected error occurred. Please refresh the page or try again later.
</p>
<div className="button-group" style={{ justifyContent: 'center' }}>
<button
onClick={() => window.location.reload()}
className="btn btn-success"
>
<span className="icon">🔄</span>
Refresh Page
</button>
<button
onClick={() => this.setState({ hasError: false, error: undefined })}
className="btn-secondary"
>
<span className="icon">🔄</span>
Try Again
</button>
</div>
{process.env.NODE_ENV === 'development' && this.state.error && (
<details className="mt-6 text-left">
<summary className="text-red-400 cursor-pointer font-mono text-sm">
Error Details (Development)
</summary>
<pre className="text-red-300 text-xs mt-2 p-3 bg-red-500/10 rounded border border-red-500/20 overflow-auto">
{this.state.error.stack}
</pre>
</details>
)}
</div>
);
}
return this.props.children;
}
}