Two bugs made "N در صف" persist even when online:
- The badge counted poisoned ops (failed after 5 retries, never removed), so it
never returned to 0. Now the badge counts only retryable (active) ops; poisoned
ops are tracked separately as failedCount and surfaced as a red "N failed —
clear" chip the user can tap to discard them.
- The manual-retry click drained the LEGACY order_queue, not the real outbox the
app actually uses — so clicking did nothing for stuck items. It now drains the
outbox (drainOutbox), invalidates queries on success, and recounts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Full Persian calendar:
- New JalaliDateField — Shamsi popover picker (Saturday-first weeks,
Persian digits, امروز shortcut); wire format stays ISO Gregorian
YYYY-MM-DD. Falls back to the native input for the en locale.
- Replaces all 5 native type="date" inputs (Gregorian-only pickers):
reservations, expenses from/to, reports from/to.
- Reservations list date now renders Jalali instead of the raw ISO
string; branches purge timestamp now formats with fa-IR.
Responsive shell (mobile + tablet):
- New MobileNav: hamburger in the topbar (< md) opening an RTL-aware
slide-over drawer with all nav destinations, permission-filtered,
Escape/backdrop close and body scroll lock.
- Desktop sidebar hidden below md; header center cluster (clock/plan)
hidden below md; language switcher hidden below sm.
- Main content padding scales p-3 → p-4 → p-6.
- Verified at 375px and 768px: no horizontal overflow, drawer and
Jalali picker fully functional.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sidebar had 22 items in 5 accordion groups, all defaulting closed:
first visit showed five vague headers and zero destinations, there was
no Dashboard/Home link at all, and rare pages (taxes, subscription) had
equal weight with POS. Restructured around usage frequency:
- Flat primary (always visible, no header): Dashboard, POS, Tables,
Kitchen, Queue, Reservations, Menu, Reports
- Two collapsible groups: Customers & marketing (crm, coupons, sms,
reviews, discover) and Café management (inventory, expenses, shifts,
taxes, hr, branches)
- Footer utility icons: settings, subscription, support
- Removed "notifications" from the nav (duplicate of the topbar bell)
Other fixes folded in:
- Deleted [locale]/page.tsx which redirected "/" to /pos — it made the
POS exit button a no-op loop and left OverviewScreen unreachable.
"/" now renders the overview home; login still lands on /pos.
- Branch gating moved from group-level to an item whitelist
(BRANCH_ALLOWED_NAV_KEYS) — also closes the hole where branch
accounts could deep-link to /reports etc. past the RouteGuard.
- RouteGuard now checks footer items too (subscription stays gated).
- revalidate=300 on the locale layout: Next emitted s-maxage=31536000
and the WCDN edge kept serving year-old HTML shells after deploys.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sidebar:
- All groups start collapsed on first load (v4 storage key resets old state)
- Opening one group closes all others (accordion)
- Navigating to a section opens only that section's group
Koja slug:
- SlugHelper: Persian->Latin transliteration, slug validation
- Registration accepts optional custom slug; auto-derives from cafe name
- Slug can be updated from dashboard Settings -> Profile
- Settings PATCH validates uniqueness (SLUG_TAKEN) and format (INVALID_SLUG)
- koja.meezi.ir/{slug} now redirects to /fa/cafe/{slug} (short URL support)
Bug fix:
- SupportTicketService: cafeId/status filters applied before Select() projection
to fix EF "could not be translated" crash on the support tickets page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wrap the POS terminal in the sidebar + topbar layout via a nested
fullscreen layout, and make the sidebar collapse to an icon-only rail
with a persisted toggle so operators keep navigation on the POS screen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>