From e547d4e318ab9856fa77eef614b112fbc6a5c5b8 Mon Sep 17 00:00:00 2001 From: a2-imeri <Alfret2.imeri@live.uwe.ac.uk> Date: Tue, 2 Jul 2024 20:29:04 +0100 Subject: [PATCH] Impliment Code 500 Error --- .../__pycache__/settings.cpython-310.pyc | Bin 3897 -> 3897 bytes frontend/src/App.js | 164 +++++++------ .../src/pages/Error/Error500/Error500.css | 232 ++++++++++++++++++ frontend/src/pages/Error/Error500/Error500.js | 28 +++ frontend/src/services/api.js | 38 ++- 5 files changed, 375 insertions(+), 87 deletions(-) create mode 100644 frontend/src/pages/Error/Error500/Error500.css create mode 100644 frontend/src/pages/Error/Error500/Error500.js diff --git a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc index 7fa541b2a5a2e158311f32a20c37fca92143ce0d..7c952482daa59997e044c9f5af09e212b1a6f4eb 100644 GIT binary patch delta 19 acmdlfw^NQQpO=@5fq{X6({v-3K0g2|`~!mk delta 19 acmdlfw^NQQpO=@5fq{XcUwR{#K0g30o&)ay diff --git a/frontend/src/App.js b/frontend/src/App.js index 1a19e4f..5a0f1cd 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,6 +1,6 @@ // src/App.js import React from 'react'; -import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; +import { BrowserRouter as Router, Route, Routes, useLocation } from 'react-router-dom'; import Navbar from './layouts/Navbar/Navbar'; import HomePage from './pages/Home/Home'; import AdminLoginPage from './pages/Admin/AdminLoginPage'; @@ -15,93 +15,99 @@ import DetectionOptionsPage from './pages/DetectionOptions/DetectionOptionsPage' import NormalDetectionPage from './pages/NormalDetection/NormalDetectionPage'; import UserDashboard from './pages/UserDashboard/UserDashboard'; import UserProfile from './pages/UserProfile/UserProfile'; -import VideoDetectionPage from './pages/Video/VideoDetectionPage'; // Import the new page - +import VideoDetectionPage from './pages/Video/VideoDetectionPage'; +import Error500 from './pages/Error/Error500/Error500'; import ProtectedRoute from './firewall/ProtectedRoute'; import RouteProtection from './firewall/RouteProtection'; +function App() { + const location = useLocation(); + return ( + <div className="App"> + {location.pathname !== '/error-500' && <Navbar />} + <div className="content"> + <Routes> + <Route path="/" element={<HomePage />} /> + <Route path="/login" element={<RouteProtection redirectTo="/" />}> + <Route path="/login" element={<LoginPage />} /> + </Route> + <Route path="/register" element={<RouteProtection redirectTo="/" />}> + <Route path="/register" element={<RegisterPage />} /> + </Route> + <Route path="/admin/login" element={<RouteProtection redirectTo="/admin/dashboard" />}> + <Route path="/admin/login" element={<AdminLoginPage />} /> + </Route> + <Route path="/admin/dashboard" element={ + <ProtectedRoute isAdminRoute={true}> + <AdminDashboard /> + </ProtectedRoute> + } /> + <Route path="/admin/users" element={ + <ProtectedRoute isAdminRoute={true}> + <AdminUsers /> + </ProtectedRoute> + } /> + <Route path="/admin/manage-items" element={ + <ProtectedRoute isAdminRoute={true}> + <ManageItems /> + </ProtectedRoute> + } /> + <Route path="/admin/manage-locations" element={ + <ProtectedRoute isAdminRoute={true}> + <ManageLocationsPage /> + </ProtectedRoute> + } /> + <Route path="/admin/manage-rules" element={ + <ProtectedRoute isAdminRoute={true}> + <ManageRulesPage /> + </ProtectedRoute> + } /> + <Route path="/detection-options" element={ + <ProtectedRoute> + <DetectionOptionsPage /> + </ProtectedRoute> + } /> + <Route path="/normal-detection" element={ + <ProtectedRoute> + <NormalDetectionPage /> + </ProtectedRoute> + } /> + <Route path="/user/dashboard" element={ + <ProtectedRoute> + <UserDashboard /> + </ProtectedRoute> + } /> + <Route path="/user/profile" element={ + <ProtectedRoute> + <UserProfile /> + </ProtectedRoute> + } /> + <Route path="/user/manage-rules" element={ + <ProtectedRoute> + <ManageRulesPage /> + </ProtectedRoute> + } /> + <Route path="/upload-video" element={ + <ProtectedRoute> + <VideoDetectionPage /> + </ProtectedRoute> + } /> + <Route path="/error-500" element={<Error500 />} /> + <Route path="*" element={<HomePage />} /> {/* Catch-all route */} + </Routes> + </div> + </div> + ); +} -function App() { +function AppWrapper() { return ( <Router> - <div className="App"> - <Navbar /> - <div className="content"> - <Routes> - <Route path="/" element={<HomePage />} /> - <Route path="/login" element={<RouteProtection redirectTo="/" />}> - <Route path="/login" element={<LoginPage />} /> - </Route> - <Route path="/register" element={<RouteProtection redirectTo="/" />}> - <Route path="/register" element={<RegisterPage />} /> - </Route> - <Route path="/admin/login" element={<RouteProtection redirectTo="/admin/dashboard" />}> - <Route path="/admin/login" element={<AdminLoginPage />} /> - </Route> - <Route path="/admin/dashboard" element={ - <ProtectedRoute isAdminRoute={true}> - <AdminDashboard /> - </ProtectedRoute> - } /> - <Route path="/admin/users" element={ - <ProtectedRoute isAdminRoute={true}> - <AdminUsers /> - </ProtectedRoute> - } /> - <Route path="/admin/manage-items" element={ - <ProtectedRoute isAdminRoute={true}> - <ManageItems /> - </ProtectedRoute> - } /> - <Route path="/admin/manage-locations" element={ - <ProtectedRoute isAdminRoute={true}> - <ManageLocationsPage /> - </ProtectedRoute> - } /> - <Route path="/admin/manage-rules" element={ - <ProtectedRoute isAdminRoute={true}> - <ManageRulesPage /> - </ProtectedRoute> - } /> - <Route path="/detection-options" element={ - <ProtectedRoute> - <DetectionOptionsPage /> - </ProtectedRoute> - } /> - <Route path="/normal-detection" element={ - <ProtectedRoute> - <NormalDetectionPage /> - </ProtectedRoute> - } /> - <Route path="/user/dashboard" element={ - <ProtectedRoute> - <UserDashboard /> - </ProtectedRoute> - } /> - <Route path="/user/profile" element={ - <ProtectedRoute> - <UserProfile /> - </ProtectedRoute> - } /> - <Route path="/user/manage-rules" element={ - <ProtectedRoute> - <ManageRulesPage /> - </ProtectedRoute> - } /> - <Route path="/upload-video" element={ // Add the new route - <ProtectedRoute> - <VideoDetectionPage /> - </ProtectedRoute> - } /> - - <Route path="*" element={<HomePage />} /> {/* Catch-all route */} - </Routes> - </div> - </div> + <App /> </Router> ); } -export default App; +export default AppWrapper; diff --git a/frontend/src/pages/Error/Error500/Error500.css b/frontend/src/pages/Error/Error500/Error500.css new file mode 100644 index 0000000..981037d --- /dev/null +++ b/frontend/src/pages/Error/Error500/Error500.css @@ -0,0 +1,232 @@ +/* General styling */ +.error500-page * { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Poppins', sans-serif; +} + +.error500-page { + background: linear-gradient(to right, #fbc2eb, #a6c1ee); + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + overflow: hidden; + padding: 20px; +} + +.error500-container { + text-align: center; + color: #fff; + background: rgba(0, 0, 0, 0.7); + padding: 50px; + border-radius: 20px; + position: relative; + overflow: hidden; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5); + max-width: 90%; + z-index: 10; + /* Added z-index to ensure it's on top */ +} + +.error500-header h1 { + font-size: 180px; + font-weight: bold; + margin-bottom: 10px; + background: -webkit-linear-gradient(#ff9a9e, #fad0c4); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + animation: pulse 1s infinite; +} + +.error500-header h2 { + font-size: 36px; + font-weight: 300; + margin-bottom: 20px; + animation: fadeIn 1s ease-in-out; +} + +.error500-body .error500-message { + font-size: 18px; + color: #eee; + margin-bottom: 30px; + animation: fadeInUp 1s ease-in-out; +} + +.error500-body .error500-link { + display: inline-block; + padding: 15px 30px; + font-size: 18px; + color: #fff; + background-color: #ff6f61; + text-decoration: none; + border-radius: 30px; + transition: background-color 0.3s; + animation: bounce 1s ease-in-out infinite; + z-index: 20; + /* Ensure link has higher z-index */ + position: relative; + /* Ensure z-index is applied */ +} + +.error500-body .error500-link:hover { + background-color: #e55d50; +} + +/* Animations */ +@keyframes pulse { + + 0%, + 100% { + transform: scale(1); + } + + 50% { + transform: scale(1.1); + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes bounce { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-10px); + } +} + +.error500-animation { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; + z-index: 0; + overflow: hidden; +} + +.circle { + position: absolute; + border-radius: 50%; + opacity: 0.7; + background-color: #ff6f61; + animation: float 3s infinite ease-in-out; +} + +.circle-1 { + width: 300px; + height: 300px; + top: -50px; + left: -50px; + animation-delay: 0s; +} + +.circle-2 { + width: 200px; + height: 200px; + bottom: -50px; + right: -50px; + animation-delay: 1s; + background-color: #ff8566; +} + +.circle-3 { + width: 150px; + height: 150px; + bottom: 50%; + left: 50%; + transform: translate(-50%, 50%); + animation-delay: 2s; + background-color: #ffb399; +} + +@keyframes float { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-20px); + } +} + +/* Media Queries */ +@media (max-width: 768px) { + .error500-header h1 { + font-size: 120px; + } + + .error500-header h2 { + font-size: 28px; + } + + .error500-body .error500-message { + font-size: 16px; + } + + .error500-body .error500-link { + padding: 12px 24px; + font-size: 16px; + } +} + +@media (max-width: 480px) { + .error500-container { + padding: 30px; + } + + .error500-header h1 { + font-size: 90px; + } + + .error500-header h2 { + font-size: 24px; + } + + .error500-body .error500-message { + font-size: 14px; + } + + .error500-body .error500-link { + padding: 10px 20px; + font-size: 14px; + } + + .circle-1, + .circle-2, + .circle-3 { + display: none; + /* Hide the circles on very small screens */ + } +} \ No newline at end of file diff --git a/frontend/src/pages/Error/Error500/Error500.js b/frontend/src/pages/Error/Error500/Error500.js new file mode 100644 index 0000000..9f82751 --- /dev/null +++ b/frontend/src/pages/Error/Error500/Error500.js @@ -0,0 +1,28 @@ +// src/pages/Error/Error500/Error500.js +import React from 'react'; +import { Link } from 'react-router-dom'; +import './Error500.css'; + +const Error500 = () => { + return ( + <div className="error500-page"> + <div className="error500-container"> + <div className="error500-header"> + <h1 className="error500-title">500</h1> + <h2 className="error500-subtitle">Internal Server Error</h2> + </div> + <div className="error500-body"> + <p className="error500-message">Oops! Something went wrong on our end. Please try again later or go back to the homepage.</p> + <Link to="/" className="error500-link" onClick={() => console.log('Go Home clicked')}>Go Home</Link> + </div> + <div className="error500-animation"> + <div className="circle circle-1"></div> + <div className="circle circle-2"></div> + <div className="circle circle-3"></div> + </div> + </div> + </div> + ); +}; + +export default Error500; diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index d74f49b..e81f19b 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -1,6 +1,6 @@ // src/services/api.js import axios from 'axios'; -import { refreshToken } from './auth'; // Import the refresh token function +import { refreshToken } from './auth'; export const getCsrfToken = () => { const cookies = document.cookie.split(';'); @@ -14,7 +14,7 @@ export const getCsrfToken = () => { }; const api = axios.create({ - baseURL: 'http://localhost:8080', + baseURL: 'http://localhost:8080', // Ensure this URL is correct headers: { 'Content-Type': 'application/json', }, @@ -27,12 +27,20 @@ api.interceptors.request.use( const tokenExpiry = localStorage.getItem('tokenExpiry'); const now = Math.floor(Date.now() / 1000); if (tokenExpiry && now >= tokenExpiry) { - // Token expired, refresh it - const newTokens = await refreshToken(); - if (newTokens) { - token = newTokens.access; - } else { - // Refresh token also expired or failed, logout user + try { + const newTokens = await refreshToken(); + if (newTokens) { + token = newTokens.access; + localStorage.setItem('token', newTokens.access); + localStorage.setItem('tokenExpiry', newTokens.accessExpiry); + } else { + localStorage.removeItem('token'); + localStorage.removeItem('refresh'); + localStorage.removeItem('tokenExpiry'); + window.location.href = '/login'; + return Promise.reject('Session expired. Please log in again.'); + } + } catch (err) { localStorage.removeItem('token'); localStorage.removeItem('refresh'); localStorage.removeItem('tokenExpiry'); @@ -51,4 +59,18 @@ api.interceptors.request.use( (error) => Promise.reject(error) ); +api.interceptors.response.use( + (response) => response, + (error) => { + console.log('API error:', error); // Debugging + if (error.response && error.response.status === 500) { + window.location.href = '/error-500'; + } else if (error.request && !error.response) { + console.log('Network or server error'); // Debugging + window.location.href = '/error-500'; + } + return Promise.reject(error); + } +); + export default api; -- GitLab