Spaces:
Sleeping
Sleeping
| import React from 'react' | |
| import ReactDOM from 'react-dom/client' | |
| import App from './App' | |
| import './index.css' | |
| // Restore persisted theme | |
| try { | |
| const saved = localStorage.getItem('theme') as 'dark' | 'light' | null | |
| if (saved) document.documentElement.setAttribute('data-theme', saved) | |
| else document.documentElement.setAttribute('data-theme', 'dark') | |
| } catch { | |
| document.documentElement.setAttribute('data-theme', 'dark') | |
| } | |
| class ErrorBoundary extends React.Component< | |
| { children: React.ReactNode }, | |
| { error: Error | null } | |
| > { | |
| constructor(props: { children: React.ReactNode }) { | |
| super(props) | |
| this.state = { error: null } | |
| } | |
| static getDerivedStateFromError(error: Error) { | |
| return { error } | |
| } | |
| render() { | |
| if (this.state.error) { | |
| return ( | |
| <div style={{ | |
| height: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', | |
| background: '#08080d', color: '#fff', flexDirection: 'column', gap: 16, padding: 32, | |
| fontFamily: 'monospace' | |
| }}> | |
| <div style={{ fontSize: 14, color: '#ef4444', marginBottom: 8 }}>Runtime error</div> | |
| <pre style={{ fontSize: 11, color: '#9ca3af', maxWidth: 600, overflow: 'auto' }}> | |
| {this.state.error.message} | |
| </pre> | |
| <button | |
| onClick={() => window.location.reload()} | |
| style={{ marginTop: 8, padding: '8px 16px', background: '#8b5cf6', border: 'none', | |
| color: '#fff', borderRadius: 8, cursor: 'pointer', fontSize: 12 }} | |
| > | |
| Reload | |
| </button> | |
| </div> | |
| ) | |
| } | |
| return this.props.children | |
| } | |
| } | |
| ReactDOM.createRoot(document.getElementById('root')!).render( | |
| <ErrorBoundary> | |
| <App /> | |
| </ErrorBoundary> | |
| ) | |