feat: redesign aplikace pomocí claude code

This commit is contained in:
Stánek Pavel
2026-02-03 10:37:27 +01:00
parent 6a1da97ef1
commit 37cacd895a
14 changed files with 1537 additions and 387 deletions

View File

@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { Navbar, Nav, NavDropdown } from "react-bootstrap";
import { Navbar, Nav, NavDropdown, Modal, Button } from "react-bootstrap";
import { useAuth } from "../context/auth";
import SettingsModal from "./modals/SettingsModal";
import { useSettings, ThemePreference } from "../context/settings";
@@ -9,6 +9,14 @@ import RefreshMenuModal from "./modals/RefreshMenuModal";
import { useNavigate } from "react-router";
import { STATS_URL } from "../AppRoutes";
import { FeatureRequest, getVotes, updateVote } from "../../../types";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSun, faMoon } from "@fortawesome/free-solid-svg-icons";
const CHANGELOG = [
"Nový moderní design aplikace",
"Oprava parsování Sladovnické a TechTower",
"Možnost označit se jako objednávající u volby \"budu objednávat\"",
];
export default function Header() {
const auth = useAuth();
@@ -18,8 +26,29 @@ export default function Header() {
const [votingModalOpen, setVotingModalOpen] = useState<boolean>(false);
const [pizzaModalOpen, setPizzaModalOpen] = useState<boolean>(false);
const [refreshMenuModalOpen, setRefreshMenuModalOpen] = useState<boolean>(false);
const [changelogModalOpen, setChangelogModalOpen] = useState<boolean>(false);
const [featureVotes, setFeatureVotes] = useState<FeatureRequest[] | undefined>([]);
// Zjistíme aktuální efektivní téma (pro zobrazení správné ikony)
const [effectiveTheme, setEffectiveTheme] = useState<'light' | 'dark'>('light');
useEffect(() => {
const updateEffectiveTheme = () => {
if (settings?.themePreference === 'system') {
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
setEffectiveTheme(isDark ? 'dark' : 'light');
} else {
setEffectiveTheme(settings?.themePreference || 'light');
}
};
updateEffectiveTheme();
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
mediaQuery.addEventListener('change', updateEffectiveTheme);
return () => mediaQuery.removeEventListener('change', updateEffectiveTheme);
}, [settings?.themePreference]);
useEffect(() => {
if (auth?.login) {
getVotes().then(response => {
@@ -44,6 +73,12 @@ export default function Header() {
setRefreshMenuModalOpen(false);
}
const toggleTheme = () => {
// Přepínáme mezi light a dark (ignorujeme system pro jednoduchost)
const newTheme: ThemePreference = effectiveTheme === 'dark' ? 'light' : 'dark';
settings?.setThemePreference(newTheme);
}
const isValidInteger = (str: string) => {
str = str.trim();
if (!str) {
@@ -121,12 +156,21 @@ export default function Header() {
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="nav">
<button
className="theme-toggle"
onClick={toggleTheme}
title={effectiveTheme === 'dark' ? 'Přepnout na světlý režim' : 'Přepnout na tmavý režim'}
aria-label="Přepnout barevný motiv"
>
<FontAwesomeIcon icon={effectiveTheme === 'dark' ? faSun : faMoon} />
</button>
<NavDropdown align="end" title={auth?.login} id="basic-nav-dropdown">
<NavDropdown.Item onClick={() => setSettingsModalOpen(true)}>Nastavení</NavDropdown.Item>
<NavDropdown.Item onClick={() => setRefreshMenuModalOpen(true)}>Přenačtení menu</NavDropdown.Item>
<NavDropdown.Item onClick={() => setVotingModalOpen(true)}>Hlasovat o nových funkcích</NavDropdown.Item>
<NavDropdown.Item onClick={() => setPizzaModalOpen(true)}>Pizza kalkulačka</NavDropdown.Item>
<NavDropdown.Item onClick={() => navigate(STATS_URL)}>Statistiky</NavDropdown.Item>
<NavDropdown.Item onClick={() => setChangelogModalOpen(true)}>Novinky</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item onClick={auth?.logout}>Odhlásit se</NavDropdown.Item>
</NavDropdown>
@@ -136,5 +180,22 @@ export default function Header() {
<RefreshMenuModal isOpen={refreshMenuModalOpen} onClose={closeRefreshMenuModal} />
<FeaturesVotingModal isOpen={votingModalOpen} onClose={closeVotingModal} onChange={saveFeatureVote} initialValues={featureVotes} />
<PizzaCalculatorModal isOpen={pizzaModalOpen} onClose={closePizzaModal} />
<Modal show={changelogModalOpen} onHide={() => setChangelogModalOpen(false)}>
<Modal.Header closeButton>
<Modal.Title><h2>Novinky</h2></Modal.Title>
</Modal.Header>
<Modal.Body>
<ul>
{CHANGELOG.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={() => setChangelogModalOpen(false)}>
Zavřít
</Button>
</Modal.Footer>
</Modal>
</Navbar>
}
}