84 lines
3.7 KiB
TypeScript
84 lines
3.7 KiB
TypeScript
import { useState } from "react";
|
|
import { Navbar, Nav, NavDropdown } from "react-bootstrap";
|
|
import { Link, useLocation } from "react-router";
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
import { faSun, faMoon, faGear, faDharmachakra } from "@fortawesome/free-solid-svg-icons";
|
|
import { useAuth } from "../context/auth";
|
|
import { useSettings, ThemePreference } from "../context/settings";
|
|
import { DEN_URL, JIDLA_URL, PROFIL_URL, STATISTIKY_URL, TRENINKY_URL } from "../routes";
|
|
import SettingsModal from "./modals/SettingsModal";
|
|
import SpinWheelModal from "./modals/SpinWheelModal";
|
|
|
|
/** Položky hlavní navigace. */
|
|
const NAV_ITEMS = [
|
|
{ url: DEN_URL, label: 'Můj den' },
|
|
{ url: JIDLA_URL, label: 'Jídla' },
|
|
{ url: TRENINKY_URL, label: 'Tréninky' },
|
|
{ url: STATISTIKY_URL, label: 'Statistiky' },
|
|
{ url: PROFIL_URL, label: 'Profil' },
|
|
];
|
|
|
|
export default function Header() {
|
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
const [wheelOpen, setWheelOpen] = useState(false);
|
|
const auth = useAuth();
|
|
const settings = useSettings();
|
|
const location = useLocation();
|
|
|
|
const effectiveDark = settings?.effectiveDark ?? false;
|
|
|
|
/** Případná podstránka nechá zvýrazněnou svou nadřazenou položku. */
|
|
const isActive = (url: string) =>
|
|
location.pathname === url || (url !== DEN_URL && location.pathname.startsWith(`${url}/`));
|
|
|
|
const toggleTheme = () => {
|
|
const next: ThemePreference = effectiveDark ? 'light' : 'dark';
|
|
settings?.setThemePreference(next);
|
|
};
|
|
|
|
return (
|
|
<Navbar variant="dark" expand="lg">
|
|
<Navbar.Brand as={Link} to={DEN_URL}>Food Tracer</Navbar.Brand>
|
|
<Navbar.Toggle aria-controls="main-navbar-nav" />
|
|
<Navbar.Collapse id="main-navbar-nav">
|
|
<Nav className="nav">
|
|
{NAV_ITEMS.map(item => (
|
|
<Link
|
|
key={item.url}
|
|
to={item.url}
|
|
className={`nav-pill ${isActive(item.url) ? 'active' : ''}`}
|
|
>
|
|
{item.label}
|
|
</Link>
|
|
))}
|
|
<button
|
|
className="theme-toggle"
|
|
onClick={() => setWheelOpen(true)}
|
|
title="Zatoč si — kolo štěstí, když nevíte, co jíst"
|
|
aria-label="Kolo štěstí"
|
|
>
|
|
<FontAwesomeIcon icon={faDharmachakra} />
|
|
</button>
|
|
<button
|
|
className="theme-toggle"
|
|
onClick={toggleTheme}
|
|
title={effectiveDark ? 'Přepnout na světlý režim' : 'Přepnout na tmavý režim'}
|
|
aria-label="Přepnout světlý/tmavý režim"
|
|
>
|
|
<FontAwesomeIcon icon={effectiveDark ? faSun : faMoon} />
|
|
</button>
|
|
<NavDropdown align="end" title={auth?.login} id="user-nav-dropdown">
|
|
<NavDropdown.Item onClick={() => setSettingsOpen(true)}>
|
|
<FontAwesomeIcon icon={faGear} /> Nastavení
|
|
</NavDropdown.Item>
|
|
<NavDropdown.Divider />
|
|
<NavDropdown.Item onClick={auth?.logout}>Odhlásit se</NavDropdown.Item>
|
|
</NavDropdown>
|
|
</Nav>
|
|
</Navbar.Collapse>
|
|
<SettingsModal isOpen={settingsOpen} onClose={() => setSettingsOpen(false)} />
|
|
{wheelOpen && <SpinWheelModal isOpen onClose={() => setWheelOpen(false)} />}
|
|
</Navbar>
|
|
);
|
|
}
|