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