diff --git a/client/src/App.scss b/client/src/App.scss
index 1a940d8..a0d7f1f 100644
--- a/client/src/App.scss
+++ b/client/src/App.scss
@@ -87,6 +87,42 @@
--luncher-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.5), 0 4px 6px -4px rgb(0 0 0 / 0.4);
}
+// Modrý motiv – světlý
+[data-luncher-color="blue"][data-bs-theme="light"] {
+ --luncher-primary: #2563eb;
+ --luncher-primary-hover: #1d4ed8;
+ --luncher-primary-light: #dbeafe;
+ --luncher-action-icon: #2563eb;
+ --luncher-success: #2563eb;
+}
+
+// Modrý motiv – tmavý
+[data-luncher-color="blue"][data-bs-theme="dark"] {
+ --luncher-primary: #3b82f6;
+ --luncher-primary-hover: #60a5fa;
+ --luncher-primary-light: #172554;
+ --luncher-action-icon: #3b82f6;
+ --luncher-success: #3b82f6;
+}
+
+// Fialový motiv – světlý
+[data-luncher-color="purple"][data-bs-theme="light"] {
+ --luncher-primary: #7c3aed;
+ --luncher-primary-hover: #6d28d9;
+ --luncher-primary-light: #ede9fe;
+ --luncher-action-icon: #7c3aed;
+ --luncher-success: #7c3aed;
+}
+
+// Fialový motiv – tmavý
+[data-luncher-color="purple"][data-bs-theme="dark"] {
+ --luncher-primary: #a78bfa;
+ --luncher-primary-hover: #c4b5fd;
+ --luncher-primary-light: #2e1065;
+ --luncher-action-icon: #a78bfa;
+ --luncher-success: #a78bfa;
+}
+
// ============================================
// BASE STYLES
// ============================================
@@ -226,6 +262,33 @@ body {
&:hover svg {
transform: rotate(15deg);
}
+
+ // Přizpůsobení pro NavDropdown (palette ikona)
+ &.nav-item.dropdown {
+ .dropdown-toggle {
+ background: transparent;
+ border: none;
+ color: var(--luncher-navbar-text);
+ padding: 8px 12px;
+ font-size: 1.1rem;
+ display: flex;
+ align-items: center;
+
+ &::after {
+ display: none;
+ }
+
+ &:hover {
+ background: rgba(255, 255, 255, 0.1);
+ transform: scale(1.1);
+ }
+
+ &:focus {
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
+ }
+ }
+ }
}
// ============================================
diff --git a/client/src/components/Header.tsx b/client/src/components/Header.tsx
index 9bcecf3..7e9a3e9 100644
--- a/client/src/components/Header.tsx
+++ b/client/src/components/Header.tsx
@@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
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";
+import { useSettings, ThemePreference, ColorTheme } from "../context/settings";
import FeaturesVotingModal from "./modals/FeaturesVotingModal";
import PizzaCalculatorModal from "./modals/PizzaCalculatorModal";
import RefreshMenuModal from "./modals/RefreshMenuModal";
@@ -13,7 +13,7 @@ import { useNavigate } from "react-router";
import { STATS_URL, OBJEDNANI_URL } from "../AppRoutes";
import { FeatureRequest, getVotes, updateVote, LunchChoices, getChangelogs } from "../../../types";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faSun, faMoon } from "@fortawesome/free-solid-svg-icons";
+import { faSun, faMoon, faPalette } from "@fortawesome/free-solid-svg-icons";
import { formatDateString } from "../Utils";
const LAST_SEEN_CHANGELOG_KEY = "lastChangelogDate";
@@ -196,10 +196,20 @@ export default function Header({ choices, dayIndex }: Props) {
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"
+ aria-label="Přepnout světlý/tmavý režim"
>
+ }
+ id="color-theme-dropdown"
+ className="theme-toggle"
+ >
+ settings?.setColorTheme('green' as ColorTheme)}>🟢 Zelený
+ settings?.setColorTheme('blue' as ColorTheme)}>🔵 Modrý
+ settings?.setColorTheme('purple' as ColorTheme)}>🟣 Fialový
+
setSettingsModalOpen(true)}>Nastavení
setRefreshMenuModalOpen(true)}>Přenačtení menu
diff --git a/client/src/context/settings.tsx b/client/src/context/settings.tsx
index 1775c79..ea3796f 100644
--- a/client/src/context/settings.tsx
+++ b/client/src/context/settings.tsx
@@ -4,18 +4,22 @@ const BANK_ACCOUNT_NUMBER_KEY = 'bank_account_number';
const BANK_ACCOUNT_HOLDER_KEY = 'bank_account_holder_name';
const HIDE_SOUPS_KEY = 'hide_soups';
const THEME_KEY = 'theme_preference';
+const COLOR_THEME_KEY = 'color_theme';
export type ThemePreference = 'system' | 'light' | 'dark';
+export type ColorTheme = 'green' | 'blue' | 'purple';
export type SettingsContextProps = {
bankAccount?: string,
holderName?: string,
hideSoups?: boolean,
themePreference: ThemePreference,
+ colorTheme: ColorTheme,
setBankAccountNumber: (accountNumber?: string) => void,
setBankAccountHolderName: (holderName?: string) => void,
setHideSoupsOption: (hideSoups?: boolean) => void,
setThemePreference: (theme: ThemePreference) => void,
+ setColorTheme: (color: ColorTheme) => void,
}
type ContextProps = {
@@ -45,11 +49,24 @@ function getInitialTheme(): ThemePreference {
return 'system';
}
+function getInitialColorTheme(): ColorTheme {
+ try {
+ const saved = localStorage.getItem(COLOR_THEME_KEY) as ColorTheme | null;
+ if (saved && ['green', 'blue', 'purple'].includes(saved)) {
+ return saved;
+ }
+ } catch (e) {
+ // localStorage nedostupný
+ }
+ return 'green';
+}
+
function useProvideSettings(): SettingsContextProps {
const [bankAccount, setBankAccount] = useState();
const [holderName, setHolderName] = useState();
const [hideSoups, setHideSoups] = useState();
const [themePreference, setTheme] = useState(getInitialTheme);
+ const [colorTheme, setColor] = useState(getInitialColorTheme);
useEffect(() => {
const accountNumber = localStorage.getItem(BANK_ACCOUNT_NUMBER_KEY);
@@ -94,6 +111,11 @@ function useProvideSettings(): SettingsContextProps {
localStorage.setItem(THEME_KEY, themePreference);
}, [themePreference]);
+ useEffect(() => {
+ localStorage.setItem(COLOR_THEME_KEY, colorTheme);
+ document.documentElement.setAttribute('data-luncher-color', colorTheme);
+ }, [colorTheme]);
+
useEffect(() => {
const applyTheme = (theme: 'light' | 'dark') => {
document.documentElement.setAttribute('data-bs-theme', theme);
@@ -129,14 +151,20 @@ function useProvideSettings(): SettingsContextProps {
setTheme(theme);
}
+ function setColorTheme(color: ColorTheme) {
+ setColor(color);
+ }
+
return {
bankAccount,
holderName,
hideSoups,
themePreference,
+ colorTheme,
setBankAccountNumber,
setBankAccountHolderName,
setHideSoupsOption,
setThemePreference,
+ setColorTheme,
}
}