diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 1be5bbd..c0ef959 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -16,7 +16,7 @@ import Footer from '@ui/Footer'; import {ToastContainer} from 'react-toastify'; import {checkSetupStatus} from '@api/auth'; import 'react-toastify/dist/ReactToastify.css'; - +import ErrorBoundary from '@ui/ErrorBoundary'; function App() { const [darkMode, setDarkMode] = useState(true); const [authState, setAuthState] = useState({ @@ -140,25 +140,33 @@ function App() { return ( <> -
- -
- - } /> - } /> - } /> - } - /> - } - /> - + +
+ +
+ + } /> + } + /> + } + /> + } + /> + } + /> + +
+
-
-
+ ); } - export default App; diff --git a/frontend/src/components/ui/ErrorBoundary.jsx b/frontend/src/components/ui/ErrorBoundary.jsx new file mode 100644 index 0000000..1284ea7 --- /dev/null +++ b/frontend/src/components/ui/ErrorBoundary.jsx @@ -0,0 +1,75 @@ +import React from 'react'; +import {AlertTriangle, Github, BookOpen} from 'lucide-react'; +import DiscordIcon from '@logo/Discord.svg'; +import GithubIcon from '@logo/GitHub.svg'; + +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = {hasError: false, error: null}; + } + + static getDerivedStateFromError(error) { + return {hasError: true, error}; + } + + componentDidCatch(error, errorInfo) { + console.error('Error caught by boundary:', error, errorInfo); + } + + render() { + if (this.state.hasError) { + return ( +
+
+
+ +
+

+ Unexpected Error +

+

+ We apologize, but something went wrong while + rendering this page. +

+ + {/* Support links */} +
+

+ Need help? Reach out to us: +

+ +
+
+
+ ); + } + + return this.props.children; + } +} + +export default ErrorBoundary;