Feat: Add sticky footer with app version and login details

This commit is contained in:
Jonathan Nielson 2025-01-01 16:40:21 -06:00
parent c3b5b654cc
commit e3740b0fbc
2 changed files with 81 additions and 55 deletions

View File

@ -22,7 +22,7 @@ export const AuthProvider = ({ children }) => {
_setUser(user); _setUser(user);
}; };
// csrf token generation for guest methods // Get a CSRF token for use in non-authenticated actions
const csrfToken = async () => { const csrfToken = async () => {
await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`); await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`);
return true; return true;

View File

@ -1,4 +1,4 @@
import React, { useEffect } from 'react'; import React, { useEffect, useState } from 'react';
import { Navigate, Outlet, NavLink } from 'react-router'; import { Navigate, Outlet, NavLink } from 'react-router';
import axios from '../axios'; import axios from '../axios';
import { useAuth } from '../contexts/AuthContext'; import { useAuth } from '../contexts/AuthContext';
@ -6,10 +6,12 @@ import bannerDayLogo from '/banner-day.svg'
export default function ProtectedLayout() { export default function ProtectedLayout() {
const { user, setUser } = useAuth(); const { user, setUser } = useAuth();
const [ serverVersion, setServerVersion ] = useState("unknown");
// check if user is logged in or not from server
useEffect(() => { useEffect(() => {
(async () => { (async () => {
// Check the server to verify the user is logged in
try { try {
const response = await axios.get('/api/user'); const response = await axios.get('/api/user');
if (response.status === 200) { if (response.status === 200) {
@ -21,14 +23,26 @@ export default function ProtectedLayout() {
window.location.href = '/'; window.location.href = '/';
} }
} }
})();
}, []);
// if user is not logged in, redirect to login page // Get the current app version of the server to display in footer
try {
const response = await axios.get('/api/server-version');
if (response.status === 200) {
console.log("got server version", response.data);
setServerVersion(response.data.serverVersion)
}
} catch (error) {
console.log(error);
}
})();
}, [setServerVersion]);
// If the user isn't logged in, we'll redirect them to the login page
if (!user) { if (!user) {
return <Navigate to="/login" />; return <Navigate to="/login" />;
} }
// logout user // logout user
const handleLogout = async () => { const handleLogout = async () => {
try { try {
@ -43,56 +57,68 @@ export default function ProtectedLayout() {
}; };
return ( return (
<> <>
<nav className="bg-white border-gray-200 px-2 sm:px-4 py-2.5 dark:bg-gray-900 w-screen"> <div class="flex flex-col h-screen justify-between">
<div className="container flex flex-wrap items-center justify-between mx-auto"> <nav className="bg-white border-gray-200 px-2 sm:px-4 py-2.5 dark:bg-gray-900 w-screen">
<NavLink to="/dashboard"> <div className="container flex flex-wrap items-center justify-between mx-auto">
<div className="float-left"> <NavLink to="/dashboard">
<img src={bannerDayLogo} className="w-12 inline" alt="Banner Day logo" /> <div className="float-left">
<span className="text-xl font-semibold whitespace-nowrap dark:text-white"> <img src={bannerDayLogo} className="w-12 inline" alt="Banner Day logo" />
Banner Day <span className="text-xl font-semibold whitespace-nowrap dark:text-white">
</span> Banner Day
</div> </span>
</NavLink> </div>
<div className="hidden w-full md:block md:w-auto" id="navbar-default"> </NavLink>
<ul className="flex flex-col p-4 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 md:mt-0 md:text-sm md:font-medium md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700"> <div className="hidden w-full md:block md:w-auto" id="navbar-default">
<li> <ul className="flex flex-col p-4 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 md:mt-0 md:text-sm md:font-medium md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
<NavLink <li>
to="/profile" <NavLink
className={({ isActive }) => to="/profile"
isActive className={({ isActive }) =>
? 'block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 dark:text-white' isActive
: 'block py-2 pl-3 pr-4 rounded md:bg-transparent md:p-0 dark:text-gray-400 md:dark:hover:text-white' ? 'block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 dark:text-white'
}> : 'block py-2 pl-3 pr-4 rounded md:bg-transparent md:p-0 dark:text-gray-400 md:dark:hover:text-white'
Profile }>
</NavLink> Profile
</li> </NavLink>
<li> </li>
<NavLink <li>
to="/about" <NavLink
className={({ isActive }) => to="/about"
isActive className={({ isActive }) =>
? 'block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 dark:text-white' isActive
: 'block py-2 pl-3 pr-4 rounded md:bg-transparent md:p-0 dark:text-gray-400 md:dark:hover:text-white' ? 'block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 dark:text-white'
}> : 'block py-2 pl-3 pr-4 rounded md:bg-transparent md:p-0 dark:text-gray-400 md:dark:hover:text-white'
About }>
</NavLink> About
</li> </NavLink>
</li>
<li> <li>
<a <a
onClick={handleLogout} onClick={handleLogout}
href="#" href="#"
className="block py-2 pl-3 pr-4 text-gray-700 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent"> className="block py-2 pl-3 pr-4 text-gray-700 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">
Logout Logout
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</nav> </nav>
<main className="container flex justify-center flex-col items-center mt-10 mx-auto">
<Outlet /> <main className="container flex justify-center flex-col items-center mt-10 mb-auto mx-auto">
</main> <Outlet />
</main>
<footer className="h-10 bg-slate-900 py-2">
<div className="float-left px-4">
App Version | Server: v{serverVersion} Client: v{import.meta.env.VITE_CLIENT_VERSION}
</div>
<div className="float-right px-4">
<span>Current User: {user.email} | Logged In: {user.last_login}</span>
</div>
</footer>
</div>
</> </>
); );
} }