feat: zobrazení stavu objednávky Bolt Food jako progress stepper
CI / Generate TypeScript types (push) Successful in 9s
CI / Server unit tests (push) Successful in 21s
CI / Build server (push) Successful in 24s
CI / Build client (push) Successful in 35s
CI / Playwright E2E tests (push) Successful in 1m22s
CI / Build and push Docker image (push) Successful in 41s
CI / Notify (push) Successful in 2s

Jak to funguje:
- OrderGroup má nové pole boltOrderState (raw order_state z Bolt API).
  Polling scheduler ho ukládá při každé změně a rozesílá přes Socket.io,
  takže stepper se posouvá živě všem uživatelům.
- Komponenta BoltOrderProgress vykresluje čtyři kroky
  (Přijato → Příprava → Na cestě → Doručeno) pod časy skupiny.
  Známé stavy se mapují explicitně, neznámé heuristikou podle
  klíčových slov, zrušená objednávka se zobrazí červeně.
  Tooltip ukazuje raw stav, aktivní krok pulzuje, dokud sledování běží.
- Po doručení (nebo zmizení objednávky z API) se token smaže,
  ale boltOrderState zůstává "delivered" — dokončený stepper je vidět
  po zbytek dne. Vynuluje se při změně/zrušení odkazu nebo návratu
  skupiny do stavu uzamčeno.
- Nastavení odkazu nově spustí okamžitý poll, stepper se tak objeví
  do vteřiny místo čekání na další tik scheduleru.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 12:28:26 +02:00
co-authored by Claude Fable 5
parent 9152425d2b
commit 84b95c6c70
8 changed files with 199 additions and 11 deletions
+7 -1
View File
@@ -152,6 +152,7 @@ export async function setGroupState(login: string, groupId: string, newState: Gr
group.deliveryAt = undefined;
group.qrGenerated = undefined;
group.boltTrackingToken = undefined;
group.boltOrderState = undefined;
for (const ml of memberLogins) {
group.members[ml] = { ...group.members[ml], paid: undefined };
}
@@ -209,11 +210,16 @@ export async function setGroupBoltTracking(login: string, groupId: string, share
if (group.creatorLogin !== login) throw new Error('Sledování Bolt může nastavit pouze zakladatel');
if (!shareUrl) {
group.boltTrackingToken = undefined;
group.boltOrderState = undefined;
} else {
if (group.state !== GroupState.ORDERED) throw new Error('Sledování Bolt lze nastavit pouze ve stavu "objednáno"');
const token = extractBoltToken(shareUrl);
if (!token) throw new Error('Neplatný odkaz na sledování objednávky Bolt');
group.boltTrackingToken = token;
if (token !== group.boltTrackingToken) {
group.boltTrackingToken = token;
// Stav patří k předchozí objednávce — vyčistíme, doplní ho první poll
group.boltOrderState = undefined;
}
}
return saveExtraData(data, date);
}