Better bracket logic
This commit is contained in:
@@ -1,44 +1,65 @@
|
||||
// frontend/src/components/Layout/Layout.jsx
|
||||
|
||||
import React from 'react';
|
||||
import { Outlet, useOutletContext } from 'react-router-dom';
|
||||
import Navbar from './Navbar';
|
||||
import { Moon, Sun } from 'lucide-react';
|
||||
import api from '../../services/api';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
|
||||
import api, { getToken } from '../../services/api';
|
||||
import Navbar from './Navbar';
|
||||
|
||||
export default function Layout({ darkMode, setDarkMode }) {
|
||||
const [isAdmin, setIsAdmin] = React.useState(false);
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
const [navTitle, setNavTitle] = useState('');
|
||||
const [navSubtitle, setNavSubtitle] = useState('');
|
||||
|
||||
// Shared state for the navbar title, settable by child pages
|
||||
const [navTitle, setNavTitle] = React.useState('');
|
||||
const [navSubtitle, setNavSubtitle] = React.useState('');
|
||||
// State to trigger settings modals from Navbar
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const isDashboard = location.pathname === '/';
|
||||
|
||||
useEffect(() => {
|
||||
const checkAuth = async () => {
|
||||
try {
|
||||
const res = await api.get('/auth/check');
|
||||
setIsAdmin(true); // Endpoint returns 200 OK if token valid
|
||||
} catch {
|
||||
setIsAdmin(false);
|
||||
if (getToken()) {
|
||||
try {
|
||||
const res = await api.get('/auth/check');
|
||||
setIsAdmin(res.is_admin);
|
||||
} catch {
|
||||
setIsAdmin(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (localStorage.getItem('volleyToken')) checkAuth();
|
||||
}, []);
|
||||
checkAuth();
|
||||
}, [location.pathname]);
|
||||
|
||||
const handleLogout = () => {
|
||||
localStorage.removeItem('volleyToken');
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-zinc-50 dark:bg-zinc-950 text-zinc-900 dark:text-zinc-100 flex flex-col">
|
||||
<Navbar title={navTitle} subtitle={navSubtitle} isAdmin={isAdmin} />
|
||||
<div className="fixed inset-0 bg-zinc-50 dark:bg-zinc-950 text-zinc-900 dark:text-zinc-100 transition-colors selection:bg-orange-500/30 flex flex-col overflow-hidden">
|
||||
<Navbar
|
||||
title={navTitle}
|
||||
subtitle={navSubtitle}
|
||||
isAdmin={isAdmin}
|
||||
onLogout={handleLogout}
|
||||
onOpenSettings={() => setShowSettings(true)}
|
||||
isDashboard={isDashboard}
|
||||
/>
|
||||
|
||||
<main className="flex-1 relative overflow-hidden flex flex-col">
|
||||
<Outlet context={{ setNavTitle, setNavSubtitle, isAdmin }} />
|
||||
<main className="flex-1 overflow-hidden relative flex flex-col">
|
||||
<Outlet context={{ setNavTitle, setNavSubtitle, isAdmin, showSettings, setShowSettings }} />
|
||||
</main>
|
||||
|
||||
<div className="fixed bottom-8 right-8 z-40">
|
||||
{/* Dark Mode FAB */}
|
||||
<div className="fixed bottom-6 sm:bottom-8 right-6 sm:right-8 z-40">
|
||||
<button
|
||||
onClick={() => setDarkMode(!darkMode)}
|
||||
className="p-4 bg-zinc-900 dark:bg-white text-white dark:text-zinc-900 rounded-full shadow-2xl transition hover:scale-110 active:scale-95 border-2 border-zinc-700 dark:border-zinc-300"
|
||||
title="Toggle Theme"
|
||||
className="p-4 sm:p-5 bg-zinc-900 dark:bg-white text-white dark:text-zinc-900 rounded-[1.5rem] sm:rounded-[2rem] shadow-2xl transition hover:scale-110 active:scale-95 border-2 border-zinc-700 dark:border-zinc-300 group"
|
||||
>
|
||||
{darkMode ? <Sun size={24} /> : <Moon size={24} />}
|
||||
{darkMode ? <Sun size={24} strokeWidth={2.5} className="sm:size-7" /> : <Moon size={24} strokeWidth={2.5} className="sm:size-7" />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user