diff --git a/app/controllers/current_user_controller.rb b/app/controllers/current_user_controller.rb index dc0b299..2fcd3c9 100644 --- a/app/controllers/current_user_controller.rb +++ b/app/controllers/current_user_controller.rb @@ -2,7 +2,7 @@ class CurrentUserController < ApplicationController before_action :authenticate_user! # If a user is authenticated, they are set as the current user. - def index + def show render json: UserSerializer.new(current_user).serializable_hash[:data][:attributes], status: :ok end end diff --git a/config/routes.rb b/config/routes.rb index 56ccb4a..d48648e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,5 @@ Rails.application.routes.draw do - get "/current_user", to: "current_user#index" + get "/current_user", to: "current_user#show" devise_for :users, path: "", path_names: { sign_in: "login", sign_out: "logout", diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index c21a67f..751c5b0 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,5 +1,6 @@ import './App.css'; -import {BrowserRouter as Router, Routes, Route, Navigate} from "react-router-dom"; +import { useContext } from 'react'; +import { Routes, Route, Navigate } from "react-router-dom"; import PageWrapper from './components/PageWrapper'; import Home from './components/pages/Home'; import About from './components/pages/About'; @@ -9,11 +10,9 @@ import RequestKit from './components/pages/RequestKit' import Registration from './components/auth/Registration'; import Login from './components/auth/Login'; import ScrollToHash from './components/ScrollToHash'; -import { useState, useEffect } from 'react'; import Confirmation from './components/pages/Confirmation'; import Donation from './components/pages/Donation'; import RequestSpeaker from './components/pages/RequestSpeaker'; -import { jwtDecode } from 'jwt-decode'; import AdminDashboard from './components/pages/AdminDashboard'; import NewForms from './components/NewForms'; import NewKit from './components/NewKit'; @@ -21,6 +20,7 @@ import NewUser from './components/NewUser'; import AddNew from './components/pages/AddNew'; import NewKitItem from './components/NewKitItem'; import AddItemToKit from './components/AddItemToKit'; +import { AuthContext } from './components/auth/AuthContext'; import UserProfile from './components/pages/UserProfile'; @@ -28,89 +28,26 @@ import UserProfile from './components/pages/UserProfile'; function App() { - const [loggedIn, setLoggedIn] = useState(); - const [user, setUser] = useState(null); - const [tokenExpiration, setTokenExpiration] = useState(null); - - // Method handles login state and token, checking for existence or expiration - useEffect(() => { - const token = localStorage.getItem('jwt'); - - if (token) { - try { - const decoded = jwtDecode(token); - const now = Date.now() / 1000; // Current time in seconds - - if (decoded.exp > now) { - setLoggedIn(true); // Token is valid - setUser(decoded.user ? decoded.user : null); // Set user data - - // Calculate remaining time until token expiration - const timeUntilExpiration = (decoded.exp - now) * 1000; - - // Notify 5 minutes before expiration - if (timeUntilExpiration < 300000) { - alert("Your session is about to expire. Please save your work."); - } - - // Set token expiration time in state - setTokenExpiration(timeUntilExpiration); - - } else { - // Token is expired, clear it - console.log("Token has expired, clearing JWT."); - localStorage.removeItem('jwt'); - setLoggedIn(false); - setUser(null); - alert("Your session has expired. Please log in again."); - } - } catch (error) { - console.error('Token decoding failed:', error); - localStorage.removeItem('jwt'); - setLoggedIn(false); - setUser(null); - } - } else { - // No token, set to logged out state - setLoggedIn(false); - setUser(null); - } - }, []); - - // Logs out the user when the token expires - useEffect(() => { - if (tokenExpiration) { - const timer = setTimeout(() => { - console.log("Token has expired, logging out."); - localStorage.removeItem('jwt'); - setLoggedIn(false); - setUser(null); - alert("Your session has expired. Please log in again."); - }, tokenExpiration); - - return () => clearTimeout(timer); - } - }, [tokenExpiration]); + const { user } = useContext(AuthContext); return ( // Sets routes for app navigation and passes props to the necessary components <>
- - + } /> } /> - } /> - } /> - } /> + } /> + } /> + } /> } /> - }/> - } /> - } /> + }/> + } /> + } /> }/> - : } /> + : } /> } > } /> } /> @@ -120,7 +57,6 @@ function App() { }/> -
); diff --git a/frontend/src/components/DashCardSet.jsx b/frontend/src/components/DashCardSet.jsx index aa0faf7..96b62ab 100644 --- a/frontend/src/components/DashCardSet.jsx +++ b/frontend/src/components/DashCardSet.jsx @@ -29,11 +29,12 @@ const DashCardSet = () => { } } catch (error) { console.error('Error fetching dashboard data:', error); + alert("An error occurred.") } }; fetchDashboardData(); - }, []); + }, [dashUrl]); return ( // Displays data using the dashboard card component diff --git a/frontend/src/components/DashTable.jsx b/frontend/src/components/DashTable.jsx index 74023b2..1c29e0a 100644 --- a/frontend/src/components/DashTable.jsx +++ b/frontend/src/components/DashTable.jsx @@ -28,6 +28,7 @@ const DashTable = ({ apiEndpoint, headers, handleShow }) => { } catch (err) { setError(err.message); console.error("Error fetching data:", err); + alert("A network error occurred.") } finally { setLoading(false); } diff --git a/frontend/src/components/EditModal.jsx b/frontend/src/components/EditModal.jsx index e60c09a..76b4abb 100644 --- a/frontend/src/components/EditModal.jsx +++ b/frontend/src/components/EditModal.jsx @@ -103,6 +103,8 @@ if (recordType === 'user') { console.log(`${recordType} updated successfully!`); alert(`${recordType} updated successfully!`); handleClose(); // Close the modal after success + } else { + alert("An error occurred with the update.") } }; diff --git a/frontend/src/components/Navigation.jsx b/frontend/src/components/Navigation.jsx index ebc64a7..1a7b79e 100644 --- a/frontend/src/components/Navigation.jsx +++ b/frontend/src/components/Navigation.jsx @@ -1,10 +1,12 @@ -import React from "react" +import React, { useContext } from "react" import { Link, useNavigate } from "react-router-dom"; import CurrentUser from "./auth/CurrentUser"; +import { AuthContext } from "./auth/AuthContext"; import Logout from "./auth/Logout"; // Passed in logged in and user state -function Navigation({ loggedIn, setLoggedIn, setUser, user }) { +function Navigation() { + const { loggedIn, user } = useContext(AuthContext); const navigate = useNavigate(); const handleDonateClick = (e) => { e.preventDefault(); @@ -13,7 +15,7 @@ function Navigation({ loggedIn, setLoggedIn, setUser, user }) { if (!user) { // If user not logged in, navigate to login page alert("You must be logged in to make a donation. Please log in or register if you haven't already."); - navigate("/login") + navigate("/login"); } else { // If user is logged in, navigate to the donation page navigate("/donation"); @@ -32,7 +34,7 @@ function Navigation({ loggedIn, setLoggedIn, setUser, user }) {