feat(drawer): drawer hub — balance now, this-shift figure, daily activity, shift history; busy spinners
/drawer was record + review only: no current balance, no sight of the open shift's incomings, no daily activity, no shift history. Rebuilt as a hub: - Drawer now: the till's running balance (new GET /api/drawer/balance, shift:read — exposes the service's existing drawerBalance(); the drawer is one site-wide till, same exposure the X-report already had) with the open shift's X-report breakdown alongside (float + takings + vouchers = expected = balance) and a "This shift: ±X" figure (expected − opening float — the shift's own contribution vs what it inherited). - Today's cash activity: every cash payment + voucher since local midnight from the signed chain, live, with day totals (card never enters the till). - Record + movements/review: the 2026-07-01 flow, unchanged. - Closed shifts: drawer-focused history via the scope-aware /api/shifts (float → takings ± vouchers → expected per shift). Also: every shift open/close button (header, /shifts, pay modal, end- shift confirm) now shows an animated spinner + dims while busy — the old label-swap-only feedback read as a dead click when a shift open ran slow. The slowness itself (drawer/shift reads fold the WHOLE chain, O(chain)) is recorded as an open item in wiki/concepts/shift.md with the fix sketch: fold from the last z-report's signed expectedDrawerMinor forward. No new ledger surface — one read-only endpoint; RBAC test added. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -21,6 +21,7 @@ import { useShift } from "./lib/use-shift.js";
|
||||
import { formatDuration, formatMoney, formatTime, formatRelativeDateTime } from "./lib/format.js";
|
||||
import { CARD_PAYMENTS_ENABLED } from "./lib/features.js";
|
||||
import { SnapshotStrip } from "./ui/SnapshotStrip.js";
|
||||
import { Spinner } from "./ui/Spinner.js";
|
||||
|
||||
// The booth pay/exit modal. Opened when the operator submits a ticket id. Shows the
|
||||
// session (entry, exit=now, duration, total owed) + entry/exit snapshots, takes
|
||||
@@ -281,7 +282,13 @@ export function BoothPayModal({ identity, onClose }: { identity: string; onClose
|
||||
disabled={openingShift}
|
||||
className="btn btn-go btn-sm mt-2"
|
||||
>
|
||||
{openingShift ? t("shift.opening") : t("shift.openNow")}
|
||||
{openingShift ? (
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
<Spinner /> {t("shift.opening")}
|
||||
</span>
|
||||
) : (
|
||||
t("shift.openNow")
|
||||
)}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user