feat: umožnění automatického přepnutí na volbu "Budu objednávat" při přidání se k objednávce
CI / Generate TypeScript types (push) Successful in 16s
CI / Server unit tests (push) Successful in 29s
CI / Build server (push) Successful in 31s
CI / Build client (push) Successful in 42s
CI / Playwright E2E tests (push) Successful in 2m16s
CI / Build and push Docker image (push) Successful in 1m11s
CI / Notify (push) Successful in 3s
CI / Generate TypeScript types (push) Successful in 16s
CI / Server unit tests (push) Successful in 29s
CI / Build server (push) Successful in 31s
CI / Build client (push) Successful in 42s
CI / Playwright E2E tests (push) Successful in 2m16s
CI / Build and push Docker image (push) Successful in 1m11s
CI / Notify (push) Successful in 3s
This commit is contained in:
4 files changed
+66
-4
No files matched your search
@@ -21,6 +21,7 @@ export default function SettingsModal({ isOpen, onClose, onSave }: Readonly<Prop
|
|||||||
const themeRef = useRef<HTMLSelectElement>(null);
|
const themeRef = useRef<HTMLSelectElement>(null);
|
||||||
const styleThemeRef = useRef<HTMLSelectElement>(null);
|
const styleThemeRef = useRef<HTMLSelectElement>(null);
|
||||||
const showButterfliesRef = useRef<HTMLInputElement>(null);
|
const showButterfliesRef = useRef<HTMLInputElement>(null);
|
||||||
|
const autoOrderChoiceRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const reminderTimeRef = useRef<HTMLInputElement>(null);
|
const reminderTimeRef = useRef<HTMLInputElement>(null);
|
||||||
const boltDeliveredRef = useRef<HTMLInputElement>(null);
|
const boltDeliveredRef = useRef<HTMLInputElement>(null);
|
||||||
@@ -83,6 +84,9 @@ export default function SettingsModal({ isOpen, onClose, onSave }: Readonly<Prop
|
|||||||
if (showButterfliesRef.current) {
|
if (showButterfliesRef.current) {
|
||||||
settings?.setShowButterflies(showButterfliesRef.current.checked);
|
settings?.setShowButterflies(showButterfliesRef.current.checked);
|
||||||
}
|
}
|
||||||
|
if (autoOrderChoiceRef.current) {
|
||||||
|
settings?.setAutoOrderChoice(autoOrderChoiceRef.current.checked);
|
||||||
|
}
|
||||||
onSave(
|
onSave(
|
||||||
bankAccountRef.current?.value,
|
bankAccountRef.current?.value,
|
||||||
nameRef.current?.value,
|
nameRef.current?.value,
|
||||||
@@ -144,6 +148,18 @@ export default function SettingsModal({ isOpen, onClose, onSave }: Readonly<Prop
|
|||||||
Experimentální funkce - zejména u TechTower bývá problém polévky spolehlivě rozeznat.
|
Experimentální funkce - zejména u TechTower bývá problém polévky spolehlivě rozeznat.
|
||||||
</Form.Text>
|
</Form.Text>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
|
<Form.Group className="mb-3">
|
||||||
|
<Form.Check
|
||||||
|
id="autoOrderChoiceCheckbox"
|
||||||
|
ref={autoOrderChoiceRef}
|
||||||
|
type="checkbox"
|
||||||
|
label='Při objednávání automaticky zvolit "Budu objednávat"'
|
||||||
|
defaultChecked={settings?.autoOrderChoice ?? false}
|
||||||
|
/>
|
||||||
|
<Form.Text className="text-muted">
|
||||||
|
Po založení skupinové objednávky nebo připojení k existující se vaše dnešní volba stravování přepne na "Budu objednávat". Volba Pizza day zůstane beze změny.
|
||||||
|
</Form.Text>
|
||||||
|
</Form.Group>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const ACCENT_HUE_KEY = 'accent_hue';
|
|||||||
const LEGACY_COLOR_THEME_KEY = 'color_theme';
|
const LEGACY_COLOR_THEME_KEY = 'color_theme';
|
||||||
const STYLE_THEME_KEY = 'style_theme';
|
const STYLE_THEME_KEY = 'style_theme';
|
||||||
const SHOW_BUTTERFLIES_KEY = 'show_butterflies';
|
const SHOW_BUTTERFLIES_KEY = 'show_butterflies';
|
||||||
|
const AUTO_ORDER_CHOICE_KEY = 'auto_order_choice';
|
||||||
|
|
||||||
export type ThemePreference = 'system' | 'light' | 'dark';
|
export type ThemePreference = 'system' | 'light' | 'dark';
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ export type SettingsContextProps = {
|
|||||||
effectiveDark: boolean,
|
effectiveDark: boolean,
|
||||||
styleTheme: StyleTheme,
|
styleTheme: StyleTheme,
|
||||||
showButterflies: boolean,
|
showButterflies: boolean,
|
||||||
|
autoOrderChoice: boolean,
|
||||||
setBankAccountNumber: (accountNumber?: string) => void,
|
setBankAccountNumber: (accountNumber?: string) => void,
|
||||||
setBankAccountHolderName: (holderName?: string) => void,
|
setBankAccountHolderName: (holderName?: string) => void,
|
||||||
setHideSoupsOption: (hideSoups?: boolean) => void,
|
setHideSoupsOption: (hideSoups?: boolean) => void,
|
||||||
@@ -39,6 +41,7 @@ export type SettingsContextProps = {
|
|||||||
setAccentHue: (hue: number) => void,
|
setAccentHue: (hue: number) => void,
|
||||||
setStyleTheme: (theme: StyleTheme) => void,
|
setStyleTheme: (theme: StyleTheme) => void,
|
||||||
setShowButterflies: (show: boolean) => void,
|
setShowButterflies: (show: boolean) => void,
|
||||||
|
setAutoOrderChoice: (enabled: boolean) => void,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContextProps = {
|
type ContextProps = {
|
||||||
@@ -90,6 +93,15 @@ function getInitialShowButterflies(): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getInitialAutoOrderChoice(): boolean {
|
||||||
|
try {
|
||||||
|
return localStorage.getItem(AUTO_ORDER_CHOICE_KEY) === 'true';
|
||||||
|
} catch {
|
||||||
|
// localStorage nedostupný
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function getInitialAccentHue(): number {
|
function getInitialAccentHue(): number {
|
||||||
try {
|
try {
|
||||||
const saved = localStorage.getItem(ACCENT_HUE_KEY);
|
const saved = localStorage.getItem(ACCENT_HUE_KEY);
|
||||||
@@ -158,6 +170,7 @@ function useProvideSettings(): SettingsContextProps {
|
|||||||
const [accentHue, setHue] = useState<number>(getInitialAccentHue);
|
const [accentHue, setHue] = useState<number>(getInitialAccentHue);
|
||||||
const [styleTheme, setStyle] = useState<StyleTheme>(getInitialStyleTheme);
|
const [styleTheme, setStyle] = useState<StyleTheme>(getInitialStyleTheme);
|
||||||
const [showButterflies, setShowButterfliesState] = useState<boolean>(getInitialShowButterflies);
|
const [showButterflies, setShowButterfliesState] = useState<boolean>(getInitialShowButterflies);
|
||||||
|
const [autoOrderChoice, setAutoOrderChoiceState] = useState<boolean>(getInitialAutoOrderChoice);
|
||||||
const [effectiveDark, setEffectiveDark] = useState<boolean>(() => {
|
const [effectiveDark, setEffectiveDark] = useState<boolean>(() => {
|
||||||
try {
|
try {
|
||||||
const pref = localStorage.getItem(THEME_KEY) as ThemePreference | null;
|
const pref = localStorage.getItem(THEME_KEY) as ThemePreference | null;
|
||||||
@@ -235,6 +248,10 @@ function useProvideSettings(): SettingsContextProps {
|
|||||||
localStorage.setItem(SHOW_BUTTERFLIES_KEY, showButterflies ? 'true' : 'false');
|
localStorage.setItem(SHOW_BUTTERFLIES_KEY, showButterflies ? 'true' : 'false');
|
||||||
}, [showButterflies]);
|
}, [showButterflies]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
localStorage.setItem(AUTO_ORDER_CHOICE_KEY, autoOrderChoice ? 'true' : 'false');
|
||||||
|
}, [autoOrderChoice]);
|
||||||
|
|
||||||
// Aplikuje accent barvy při změně hue nebo přepnutí světlý/tmavý.
|
// Aplikuje accent barvy při změně hue nebo přepnutí světlý/tmavý.
|
||||||
// Tematické styly (Umamusume, My Little Pony, Hell Girl, K-ON!, Bocchi the Rock!) mají vlastní pevnou paletu, accent barvu proto uplatňuje jen jednoduchý styl.
|
// Tematické styly (Umamusume, My Little Pony, Hell Girl, K-ON!, Bocchi the Rock!) mají vlastní pevnou paletu, accent barvu proto uplatňuje jen jednoduchý styl.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -274,6 +291,10 @@ function useProvideSettings(): SettingsContextProps {
|
|||||||
setShowButterfliesState(show);
|
setShowButterfliesState(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setAutoOrderChoice(enabled: boolean) {
|
||||||
|
setAutoOrderChoiceState(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bankAccount,
|
bankAccount,
|
||||||
holderName,
|
holderName,
|
||||||
@@ -290,5 +311,7 @@ function useProvideSettings(): SettingsContextProps {
|
|||||||
setStyleTheme,
|
setStyleTheme,
|
||||||
showButterflies,
|
showButterflies,
|
||||||
setShowButterflies,
|
setShowButterflies,
|
||||||
|
autoOrderChoice,
|
||||||
|
setAutoOrderChoice,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,8 +7,8 @@ import DatePicker, { registerLocale } from 'react-datepicker';
|
|||||||
import { cs } from 'date-fns/locale';
|
import { cs } from 'date-fns/locale';
|
||||||
import 'react-datepicker/dist/react-datepicker.css';
|
import 'react-datepicker/dist/react-datepicker.css';
|
||||||
import {
|
import {
|
||||||
ClientData, GroupState, MealSlot, OrderGroup, OrderGroupMember, PendingQr, TrackingProvider,
|
ClientData, GroupState, LunchChoice, MealSlot, OrderGroup, OrderGroupMember, PendingQr, TrackingProvider,
|
||||||
StoreMenuDish, getData, createGroup, deleteGroup, addGroupMember, removeGroupMember, updateGroupMember, setGroupState, updateGroupTimes, setTracking, getOrderDates, getStoreMenu,
|
StoreMenuDish, getData, createGroup, deleteGroup, addGroupMember, removeGroupMember, updateGroupMember, setGroupState, updateGroupTimes, setTracking, getOrderDates, getStoreMenu, addChoice,
|
||||||
} from '../../../types';
|
} from '../../../types';
|
||||||
import MenuHintCell from '../components/MenuHintCell';
|
import MenuHintCell from '../components/MenuHintCell';
|
||||||
import EaterBadge from '../components/EaterBadge';
|
import EaterBadge from '../components/EaterBadge';
|
||||||
@@ -261,6 +261,22 @@ export default function OrderGroupsPage() {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pokud to má uživatel zapnuté v nastavení, přepne jeho dnešní volbu stravování na "Budu objednávat".
|
||||||
|
* Volbu nemění, pokud již objednává, nebo je přihlášen na Pizza day (změnou by přišel o objednané pizzy).
|
||||||
|
*/
|
||||||
|
const switchChoiceToOrdering = async () => {
|
||||||
|
if (!settings?.autoOrderChoice || !auth?.login) return;
|
||||||
|
const lunch = await getData({ query: { slot: MealSlot.OBED } });
|
||||||
|
const choices = lunch.data?.choices;
|
||||||
|
if (!choices) return;
|
||||||
|
if (auth.login in (choices[LunchChoice.OBJEDNAVAM] ?? {}) || auth.login in (choices[LunchChoice.PIZZA] ?? {})) return;
|
||||||
|
const result = await addChoice({ body: { locationKey: LunchChoice.OBJEDNAVAM, slot: MealSlot.OBED } });
|
||||||
|
if (result.error) {
|
||||||
|
setPageError(`Nepodařilo se přepnout volbu stravování: ${(result.error as any).error || 'Nastala chyba'}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleCreate = async () => {
|
const handleCreate = async () => {
|
||||||
if (!newGroupName || !auth?.login) return;
|
if (!newGroupName || !auth?.login) return;
|
||||||
setCreating(true);
|
setCreating(true);
|
||||||
@@ -271,13 +287,17 @@ export default function OrderGroupsPage() {
|
|||||||
if (ok) {
|
if (ok) {
|
||||||
setNewGroupName('');
|
setNewGroupName('');
|
||||||
setNewGroupUrl('');
|
setNewGroupUrl('');
|
||||||
|
await switchChoiceToOrdering();
|
||||||
}
|
}
|
||||||
setCreating(false);
|
setCreating(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const handleJoin = (groupId: string) =>
|
const handleJoin = async (groupId: string) => {
|
||||||
refresh(() => addGroupMember({ body: { id: groupId } }));
|
if (await refresh(() => addGroupMember({ body: { id: groupId } }))) {
|
||||||
|
await switchChoiceToOrdering();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleToggleLock = (group: OrderGroup) => {
|
const handleToggleLock = (group: OrderGroup) => {
|
||||||
const next = group.state === GroupState.OPEN ? GroupState.LOCKED : GroupState.OPEN;
|
const next = group.state === GroupState.OPEN ? GroupState.LOCKED : GroupState.OPEN;
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[
|
||||||
|
"Nové nastavení: po založení skupinové objednávky nebo připojení k ní se vaše dnešní volba automaticky přepne na \"Budu objednávat\""
|
||||||
|
]
|
||||||
Reference in new issue
Block a user