| import React, { Component, ReactNode } from 'react'; |
|
|
| interface Props { |
| children: ReactNode; |
| fallback?: ReactNode; |
| onError?: (error: Error, errorInfo: React.ErrorInfo) => void; |
| showDetails?: boolean; |
| } |
|
|
| interface State { |
| hasError: boolean; |
| } |
|
|
| class SourcesErrorBoundary extends Component<Props, State> { |
| state = { hasError: false }; |
|
|
| static getDerivedStateFromError() { |
| return { hasError: true }; |
| } |
|
|
| componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { |
| console.error('Sources error:', error); |
| this.props.onError?.(error, errorInfo); |
| } |
|
|
| render() { |
| if (this.state.hasError) { |
| |
| if (this.props.fallback) { |
| return this.props.fallback; |
| } |
|
|
| |
| |
| return ( |
| <div |
| className="flex flex-col items-center justify-center rounded-lg border border-border-medium bg-surface-secondary p-4 text-center" |
| role="alert" |
| aria-live="polite" |
| > |
| <div className="mb-2 text-sm text-text-secondary">Sources temporarily unavailable</div> |
| <button |
| onClick={() => window.location.reload()} |
| className="hover:bg-surface-primary-hover rounded-md bg-surface-primary px-3 py-1 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-ring" |
| aria-label="Reload the page" |
| > |
| Refresh |
| </button> |
| </div> |
| ); |
| |
| } |
|
|
| return this.props.children; |
| } |
| } |
|
|
| export default SourcesErrorBoundary; |
|
|