Frontend v.0.1
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user