feat: push upozornění na doručení objednávky Bolt Food
CI / Generate TypeScript types (push) Successful in 12s
CI / Server unit tests (push) Successful in 22s
CI / Build server (push) Successful in 28s
CI / Build client (push) Successful in 41s
CI / Playwright E2E tests (push) Successful in 1m48s
CI / Build and push Docker image (push) Successful in 53s
CI / Notify (push) Successful in 2s

Nové zaškrtávátko v Nastavení → Notifikace pod výběrem času připomínky.
Když skupinová objednávka sledovaná přes Bolt Food přejde do stavu
delivered/finished, dostanou push členové skupiny, kteří si to zapnuli.
Zakladatel skupiny notifikaci nedostává — ten je informován aplikací Bolt.

Push subscription byla dosud svázaná s časem připomínky (subscribe endpoint
bez reminderTime vracel 400), takže by nový přepínač samostatně nefungoval.
Čas připomínky je nově v registru volitelný a scheduler připomínek záznamy
bez času přeskakuje.

Service worker nemá natvrdo tag a akci "Mám vlastní/neobědvám" — obojí se
řídí payloadem, aby je doručovací notifikace nedědila.
This commit is contained in:
2026-08-10 12:36:07 +02:00
parent 377a350211
commit 065ccaf38a
12 changed files with 440 additions and 41 deletions
+35 -12
View File
@@ -21,6 +21,7 @@ export default function SettingsModal({ isOpen, onClose, onSave }: Readonly<Prop
const themeRef = useRef<HTMLSelectElement>(null);
const reminderTimeRef = useRef<HTMLInputElement>(null);
const boltDeliveredRef = useRef<HTMLInputElement>(null);
const ntfyTopicRef = useRef<HTMLInputElement>(null);
const discordWebhookRef = useRef<HTMLInputElement>(null);
const teamsWebhookRef = useRef<HTMLInputElement>(null);
@@ -47,22 +48,29 @@ export default function SettingsModal({ isOpen, onClose, onSave }: Readonly<Prop
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
await updateNotificationSettings({
body: {
ntfyTopic: ntfyTopicRef.current?.value || undefined,
discordWebhookUrl: discordWebhookRef.current?.value || undefined,
teamsWebhookUrl: teamsWebhookRef.current?.value || undefined,
enabledEvents,
reminderTime: newReminderTime,
}
}).catch(() => {});
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 pro připomínky
if (newReminderTime && newReminderTime !== oldReminderTime) {
// 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 (!newReminderTime && oldReminderTime) {
} else if (!wantsPush && hadPush) {
unsubscribeFromPush();
}
@@ -128,6 +136,21 @@ export default function SettingsModal({ isOpen, onClose, onSave }: Readonly<Prop
</Form.Text>
</Form.Group>
<Form.Group className="mb-3">
<Form.Check
id="boltDeliveredCheckbox"
ref={boltDeliveredRef}
type="checkbox"
label="Upozornění na doručení objednávky (Bolt Food)"
defaultChecked={notifSettings.boltDeliveredPush ?? false}
key={`bolt-delivered-${notifSettings.boltDeliveredPush ?? false}`}
/>
<Form.Text className="text-muted">
bude skupinová objednávka sledovaná přes Bolt Food doručena, přijde vám push notifikace.
Zakladateli skupiny se neposílá ten dostane upozornění přímo z aplikace Bolt.
</Form.Text>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>ntfy téma (topic)</Form.Label>
<Form.Control