Frontend v.0.1

This commit is contained in:
2026-02-12 17:29:24 +01:00 Verified
parent f8fe3eb991
commit c12d962da0
20 changed files with 2087 additions and 181 deletions
+46
View File
@@ -0,0 +1,46 @@
// 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';
export default function Layout({ darkMode, setDarkMode }) {
const [isAdmin, setIsAdmin] = React.useState(false);
// Shared state for the navbar title, settable by child pages
const [navTitle, setNavTitle] = React.useState('');
const [navSubtitle, setNavSubtitle] = React.useState('');
React.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 (localStorage.getItem('volleyToken')) checkAuth();
}, []);
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} />
<main className="flex-1 relative overflow-hidden flex flex-col">
<Outlet context={{ setNavTitle, setNavSubtitle, isAdmin }} />
</main>
<div className="fixed bottom-8 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"
>
{darkMode ? <Sun size={24} /> : <Moon size={24} />}
</button>
</div>
</div>
);
}