import { useEffect, useRef, useState } from "react"; import { Modal, Button, Form, Row, Col } from "react-bootstrap" import { useSettings, ThemePreference, StyleTheme, STYLE_THEMES } from "../../context/settings"; import { NotificationSettings, UdalostEnum, getNotificationSettings, updateNotificationSettings } from "../../../../types"; import { useAuth } from "../../context/auth"; import { subscribeToPush, unsubscribeFromPush } from "../../hooks/usePushReminder"; type Props = { isOpen: boolean, onClose: () => void, onSave: (bankAccountNumber?: string, bankAccountHolderName?: string, hideSoupsOption?: boolean, themePreference?: ThemePreference) => void, } /** Modální dialog pro uživatelská nastavení. */ export default function SettingsModal({ isOpen, onClose, onSave }: Readonly) { const auth = useAuth(); const settings = useSettings(); const bankAccountRef = useRef(null); const nameRef = useRef(null); const hideSoupsRef = useRef(null); const themeRef = useRef(null); const styleThemeRef = useRef(null); const showButterfliesRef = useRef(null); const autoOrderChoiceRef = useRef(null); const reminderTimeRef = useRef(null); const boltDeliveredRef = useRef(null); const ntfyTopicRef = useRef(null); const discordWebhookRef = useRef(null); const teamsWebhookRef = useRef(null); const [notifSettings, setNotifSettings] = useState({}); const [enabledEvents, setEnabledEvents] = useState([]); useEffect(() => { if (isOpen && auth?.login) { getNotificationSettings().then(response => { if (response.data) { setNotifSettings(response.data); setEnabledEvents(response.data.enabledEvents ?? []); } }).catch(() => {}); } }, [isOpen, auth?.login]); const toggleEvent = (event: UdalostEnum) => { setEnabledEvents(prev => prev.includes(event) ? prev.filter(e => e !== event) : [...prev, event] ); }; const handleSave = async () => { const newReminderTime = reminderTimeRef.current?.value || undefined; const oldReminderTime = notifSettings.reminderTime; const newBoltDelivered = boltDeliveredRef.current?.checked ?? false; const oldBoltDelivered = notifSettings.boltDeliveredPush ?? false; // Uložení notifikačních nastavení na server const newSettings: NotificationSettings = { ntfyTopic: ntfyTopicRef.current?.value || undefined, discordWebhookUrl: discordWebhookRef.current?.value || undefined, teamsWebhookUrl: teamsWebhookRef.current?.value || undefined, enabledEvents, reminderTime: newReminderTime, boltDeliveredPush: newBoltDelivered, }; await updateNotificationSettings({ body: newSettings }).catch(() => {}); setNotifSettings(newSettings); // Správa push subscription — drží ji naživu kterákoli z push funkcí. // Záměrně bez await: subscribeToPush si vyžádá oprávnění prohlížeče a modal // by na tu dobu zůstal otevřený. const wantsPush = !!newReminderTime || newBoltDelivered; const hadPush = !!oldReminderTime || oldBoltDelivered; if (wantsPush && (newReminderTime !== oldReminderTime || newBoltDelivered !== oldBoltDelivered)) { subscribeToPush(newReminderTime); } else if (!wantsPush && hadPush) { unsubscribeFromPush(); } // Uložení ostatních nastavení (localStorage) if (styleThemeRef.current?.value) { settings?.setStyleTheme(styleThemeRef.current.value as StyleTheme); } if (showButterfliesRef.current) { settings?.setShowButterflies(showButterfliesRef.current.checked); } if (autoOrderChoiceRef.current) { settings?.setAutoOrderChoice(autoOrderChoiceRef.current.checked); } onSave( bankAccountRef.current?.value, nameRef.current?.value, hideSoupsRef.current?.checked, themeRef.current?.value as ThemePreference, ); }; return (

Nastavení

{/* Na širších obrazovkách rozdělení do dvou sloupců, na užších pod sebou */}

Vzhled

Styl {STYLE_THEMES.map(t => )} Barevný motiv Po vypnutí se poletující motýlci ani minihra nebudou vůbec zobrazovat.

Obecné

Experimentální funkce - zejména u TechTower bývá problém polévky spolehlivě rozeznat. 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.

Bankovní účet

Nastavením čísla účtu umožníte automatické generování QR kódů pro úhradu za vámi provedené objednávky v rámci Pizza day.

Číslo účtu e.stopPropagation()} /> Pokud vaše číslo účtu neobsahuje předčíslí, je možné ho zcela vynechat. Název příjemce e.stopPropagation()} /> Jméno majitele účtu pro QR platbu.

Notifikace

Nastavením notifikací budete dostávat upozornění o událostech (např. "Jdeme na oběd") přímo do vámi zvoleného komunikačního kanálu.

Připomínka výběru oběda V zadaný čas vám přijde push notifikace, pokud nemáte zvolenou možnost stravování. Nechte prázdné pro vypnutí. Až bude sledovaná skupinová objednávka doručena, přijde vám push notifikace. Zakladateli skupiny se neposílá — ten dostane upozornění přímo z aplikace rozvozové služby. ntfy téma (topic) e.stopPropagation()} /> Téma pro ntfy push notifikace. Nechte prázdné pro vypnutí. Discord webhook URL e.stopPropagation()} /> URL webhooku Discord kanálu. Nechte prázdné pro vypnutí. MS Teams webhook URL e.stopPropagation()} /> URL webhooku MS Teams kanálu. Nechte prázdné pro vypnutí. Události k odběru {Object.values(UdalostEnum).map(event => ( toggleEvent(event)} /> ))} Zvolte události, o kterých chcete být notifikováni. Notifikace jsou odesílány pouze uživatelům se stejnou zvolenou lokalitou.
); }