Better bracket logic

This commit is contained in:
2026-02-14 01:04:54 +01:00 Verified
parent 87d3ea5ef0
commit 7b878b3abe
32 changed files with 1326 additions and 1348 deletions
+44 -23
View File
@@ -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>