Commit Graph

89 Commits

Author SHA1 Message Date
pavlov346346-source
eab678adbe fix: harden inline handlers against id injection, fix stale version label
Some checks failed
Caterium QA / qa (push) Has been cancelled
Inline handlers built as onclick="fn('${esc(id)}')" were injectable:
esc() turns ' into ', which the browser decodes back to ' before
the JS runs, so an id like x');alert(1);// broke out of the string.
Ids can come from a restored backup file or a synced catalog. Add
SunSafe.jsArg (JSON.stringify + HTML escape) and use it in all 23
handlers in app-runtime.js and index.html. Verified in a browser: a
payload id is passed through as a plain string and nothing executes.

Also replace the Settings version label that still showed
v17.6.0 · 2026.09.07, and bump the cache-busting version of the two
changed scripts (sun-safe.js, app-runtime.js).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 12:28:35 +03:00
pavlov346346-source
716a79c58d
Optional per-profile training catalog with reversible example visibility (#35)
Add Settings > Учебный каталог, off by default and available on ordinary writable profiles. Load ready example boxes, photos, TTKs and linked sample inventory additively; preserve own data, saved orders and edited examples when hiding or re-enabling. Respect company/profile scope, read-only permissions, failed downloads and tenant changes. Preserve the opened recipe guide across real catalog refreshes on iPhone. Integrated feature checks and full pull-request QA passed. Standard main QA and exact-asset production UI verification remain in place.
2026-09-20 12:18:40 +03:00
pavlov346346-source
5ce7d8d353
Mobile menu editor above boxes with a matching return arrow (#34)
On phones place the existing menu editor above the catalog and add the same return-to-top control used by New Order. Preserve form nodes, unsaved values and active input focus; keep desktop/tablet layout and read-only permissions. Full QA passed, including iPhone WebKit and existing promotion focus regression. Extend real-asset production verification with a backend-blocked mobile-menu scenario.
2026-09-19 20:02:43 +03:00
pavlov346346-source
ee70c66ed8
Fix iPhone offer template flicker (#33)
Avoid rebuilding the offer template picker during the five-second maintenance pass unless the selected template or template list actually changed. Includes a regression test for repeated maintenance cycles.
2026-09-19 19:28:57 +03:00
pavlo
d7d6f6ff38 Add AI support assistant to the Help dialog
The Поддержка tab opens an assistant that answers how-to questions from
the handbook. The chat is a sandboxed iframe on the assistant's own
origin and is only loaded after an explicit click, so Help and its search
stay local and no third-party script runs inside the app.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 18:27:47 +03:00
pavlov346346-source
424bf8ce87
Compact clients and explicit timed menu promotions (#31)
Add compact accessible client summaries and menu discounts in percent or rubles with explicit durations. Preserve ordinary catalog prices and order line snapshots; derive current prices and expire promotions automatically without background writes. Keep fractional prices, legacy sale compatibility, and regression coverage. Full pull-request QA passed. Publication remains gated by full main QA and byte-for-byte production asset and UI verification.
2026-09-19 09:34:50 +03:00
pavlov346346-source
15ab908836
Match Help icon to native sidebar styling (#30)
Add a question-circle SVG mask to Help using the existing sidebar pseudo-element. Preserve shared icon geometry, theme colors and navigation behavior. Add full-app icon regression and correct the previous loading-recovery fixture. Production promotion remains gated by full main QA.
2026-09-19 07:52:30 +03:00
pavlov346346-source
b2bcb0f4db
Make workspace loading a calm progress-only screen (#29)
* Make workspace loading a calm progress-only screen

* Cover quiet workspace loading and error recovery on desktop and mobile

* Run workspace loading regressions in desktop, mobile and WebKit QA
2026-09-19 06:57:27 +03:00
pavlov346346-source
4f518b3663 Stabilize settings updates, auth gates and modal lifecycle 2026-09-18 21:15:26 +03:00
pavlov346346-source
47ae8df39c Remove device PIN and fit calendar to mobile screens 2026-09-18 20:43:09 +03:00
pavlov346346-source
45e77958cb Remove Map from the sidebar navigation 2026-09-18 20:27:24 +03:00
pavlov346346-source
be0fd9aee7 Hide completed import catalog entries without losing order history 2026-09-18 20:17:30 +03:00
pavlov346346-source
11e7b4bd56 Refine six client proposal layouts and transparent company logos 2026-09-18 19:55:04 +03:00
pavlov346346-source
7807bf4f8f Poll workspace revision through the authorized state RPC 2026-09-18 19:17:03 +03:00
pavlov346346-source
71bc56b0cd Route cloud access through Caterium and vendor login SDK 2026-09-18 19:07:47 +03:00
pavlov346346-source
ff7fe90ccf Add searchable user guide and support area with future assistant design 2026-09-18 18:43:27 +03:00
pavlov346346-source
09bfb0fed8 Fix Safari login request bodies and raw storage uploads 2026-09-18 18:13:00 +03:00
pavlov346346-source
4d4cca2e32 Respect confirmed payment for imported orders with unknown totals 2026-09-18 16:29:44 +03:00
pavlov346346-source
f628a4a27e Remove empty mobile order gap above payment fields 2026-09-18 10:43:08 +03:00
pavlov346346-source
66decb03a5 Show mobile order totals above catalog and add return-to-top button 2026-09-18 10:36:06 +03:00
pavlov346346-source
dac1a1de72 Fill empty trial tabs with premium, drinks, tableware, extras and delivery 2026-09-18 08:26:21 +03:00
pavlov346346-source
18ff2b9c30 Add 18 trial banquet dishes with portion TTKs and additive stock seed 2026-09-18 08:11:32 +03:00
pavlov346346-source
4fe984b584 fix: remove legacy login flash during session restoration 2026-09-18 05:48:20 +03:00
pavlov346346-source
6472dba7ee fix: bound proposal loading and preserve per-order preview 2026-09-18 05:31:15 +03:00
pavlov346346-source
44d6ec9e81 Cache optimized trial photos for legacy URLs in the installed app 2026-09-18 04:59:16 +03:00
pavlov346346-source
6067c3f570 Fix transient cloud sync timeouts and optimize trial photos 2026-09-18 04:51:29 +03:00
pavlov346346-source
7e5c7c1908 Restore distinct proposal designs and improve PDF typography and pagination 2026-09-18 04:05:36 +03:00
pavlov346346-source
9539374c88 Add isolated trial demo boxes with TTK, stock and purchasing scenario 2026-09-18 03:24:43 +03:00
pavlov346346-source
d4e02cab8b Recover login from empty API responses with one authenticated session 2026-09-18 02:39:30 +03:00
pavlov346346-source
1ae56fb57b Fit nine calendar orders per day and preserve all printed events 2026-09-17 21:25:25 +03:00
pavlov346346-source
2d49563b9d Add banquet packages, dish sections and guest totals 2026-09-17 21:07:54 +03:00
pavlov346346-source
57f5807953 Require account login and isolate all company client caches 2026-09-17 20:40:24 +03:00
pavlov346346-source
c18c49770d Start new companies with empty private catalogs 2026-09-17 20:27:07 +03:00
pavlov346346-source
48ffa51748 Preserve imported order history and saved order pricing 2026-09-17 20:15:32 +03:00
pavlov346346-source
11b2bf84c9 Separate account sidebar identity from company document branding 2026-09-17 19:51:01 +03:00
pavlov346346-source
c31f868c83 Apply saved theme before first paint and prevent startup flicker 2026-09-17 19:16:19 +03:00
pavlov346346-source
da8ff042f7 Restore Caterium schema and switch production to fresh Supabase 2026-09-17 17:30:57 +03:00
pavlov346346-source
7446a551f6 fix: allow premium-dark/premium-emerald in template id whitelists
Two separate Set-based whitelists (OFFER_TEMPLATE_IDS in app-runtime.js
and TEMPLATE_IDS in ux-fixes-v1764.js) validated any explicit template
selection before persisting/rendering it, but neither had been updated
when premium-dark/premium-emerald were added. The per-order "Оформление
PDF" picker's click handler calls persistOfferTemplate(), which silently
returned false when the id failed this check -- so clicking either
premium card in an order's offer modal did nothing, no error, no toast.
Verified end-to-end against a real order: both ids now persist and the
picker shows the selected state correctly.

Also bumped performance.js's internal RELEASE tag, since it gates the
cache-busting query string used to dynamically load ux-fixes-v1764.js
and eight other core modules -- otherwise this fix would hit the same
stale-cache issue just fixed in index.html.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 13:46:15 +03:00
pavlov346346-source
5ead4a7f0c feat: add visual heading to midnight-checklist menu section
Replace the plain white "МЕНЮ" text label with a gold icon badge,
item count, and divider line, matching the icon-badge language already
used elsewhere in the template instead of a bare heading.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 13:36:09 +03:00
pavlov346346-source
14e3d6b45b fix: merge addon pills into one card, wire it to editable Settings
Two related fixes reported directly against live screenshots:

1. addonRow rendered each addon ("Напитки", "Чайная станция", ...) as
   its own tall bordered pill sitting side by side -- disjointed, and
   unlike the single-card "Полезные дополнения" treatment in the
   referenced design. Now draws one card with a heading
   ("Рекомендуем добавить") containing all the icon+label items,
   matching how checklistCard already works.

2. The addon list and the "Всё под контролем" checklist were hardcoded
   constants in the canvas module, completely bypassing the app's
   existing editable Client Offer Settings (Настройки → Предложение →
   "Дополнительно к заказу", textarea-backed extraServices/controlLines
   the user can already edit for the old templates). preparedSnapshot
   now attaches the resolved controlLines/extraServices/titles onto
   every snapshot; the 8 signature templates read them via a local
   shadowing const (falls back to the previous defaults when nothing
   is configured), so editing that Settings textarea now actually
   changes what shows up in these templates too, on all 8 of them from
   one change since addonRow/checklistCard are shared helpers.

Verified locally: default list (6 items) lays out cleanly in one card
with 2-line wrapping where needed; a snapshot with custom
controlLines/extraServices renders those exact custom strings instead
of the defaults, confirming the wiring actually works end to end and
isn't just falling back silently.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 11:28:18 +03:00
pavlov346346-source
44bf5e9af1 feat: add 2 new templates modeled on the referenced menu.furset.ru design
User pointed at https://menu.furset.ru/view/23855347 as a design they
like and asked for a couple more templates in that direction. Added:

- premium-dark: near-black background, warm gold accents, real
  line-drawn icon badges (calendar/people/box -- not emoji) for the
  date/guests/boxes stats, bullet-point value props under the title,
  minimal flat menu list -- closely matching that reference's visual
  language instead of the card-heavy style of the existing templates.
- premium-emerald: the same layout in an emerald-green palette, as
  the second "couple" of designs requested, sharing the cover code
  with premium-dark and only differing by PALETTES entry.

Both plug into the existing shared renderContentPages engine, so they
get proper multi-page menu + pricing pages for free, consistent with
all 6 existing signature templates. New icon-drawing helpers
(iconBadge/iconCalendar/iconPeople/iconGauge/iconBox, statBadgeRow,
bulletList) live in the shared helper section for reuse.

Verified locally: both render in <70ms combined, produce 3 pages each
for a normal order, and hold up under the same adversarial-data pass
used for the other 6 (long names, 350 guests, seven-figure price,
item with no photo/price/category) -- no overlap, no crashes, generous
ellipsis truncation throughout. Fixed one real bug found while
testing: the date value in the stat badge ("8 августа 2026 г.") was
getting ellipsis-truncated at font-size 20px; reduced to 16px so it
fits cleanly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 11:11:43 +03:00
pavlov346346-source
28fd97bcf3 fix: replace gourmet-hero's fake category tabs with real ones
Same issue as the cards just removed from cream-elegance: a hardcoded
['РЫБНЫЕ','МЯСНЫЕ','ВЕГЕТАРИАНСКИЕ','САЛАТЫ','ДЕСЕРТЫ'] tab row that
had nothing to do with what was actually in the order (an order with
zero vegetarian items still showed a "ВЕГЕТАРИАНСКИЕ" tab as if
active/relevant). Now derives the chip row from the distinct
categoryName values actually present on the order's items, and
renders nothing if that data isn't available.

Verified this pass end-to-end rather than just by inspection:
- Real "Скачать PDF" pipeline (sunClientOfferDebugPdf) produces a
  valid application/pdf blob with a correct %PDF-1.4 header, not just
  canvases.
- Confirmed Canvas text genuinely falls back through the font stack
  (measured identical metrics for an unregistered font vs. Georgia
  directly, and document.fonts.load() resolves instantly for a
  never-registered family) -- so a blocked/unreachable Google Fonts
  degrades silently to Georgia/Arial instead of hanging or erroring,
  which matters given this app already had to work around Russia
  connectivity issues elsewhere.
- Re-rendered all 6 templates against deliberately adversarial data
  (150+ word event name, 44-char client name, 350 guests, a
  million-ruble price, an item with no photo/price/category, a long
  promo code) -- no crashes, no overlap, graceful ellipsis truncation
  throughout.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 10:57:29 +03:00
pavlov346346-source
b702b4b69e fix: remove static category cards from cream-elegance cover
They were hardcoded labels (Рыбные закуски / Мясные закуски / Для
вегетарианцев / Мини-салаты) with a generic "Собрано под ваше
событие" caption that didn't reflect the actual order — confusing and
requested to be removed. The freed space now goes to a bigger 3x2
photo grid of the order's real items instead of leaving a gap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 10:41:10 +03:00
pavlov346346-source
d78ca14baf feat: bring the other 4 signature templates up to the same quality bar
- Fix the price band on cream-elegance: it was a solid muddy olive
  fill that didn't read as "this is your total" (reported directly by
  the user). It's now a white card with a gold border, matching the
  rest of that template's light card language; the dark templates'
  solid-fill price band is unchanged since that already reads well
  against a dark background.
- Give emerald-circles, midnight-checklist, gourmet-hero and
  diamond-gold the same treatment as the first 2: real fonts
  (Playfair Display/Montserrat or Unbounded/Manrope depending on
  aesthetic) instead of Arial/Georgia, the same center-alignment fixes
  applied everywhere text used align:'center', and their own
  fully-styled inner pages (menu + pricing) via the shared
  renderContentPages engine instead of the old generic base renderer.
- Fix two real regressions the font swap introduced and caught by
  rendering each template locally: gourmet-hero's headline was
  overflowing width and getting ellipsis-truncated ("КЕЙТЕРИНГ..."),
  and diamond-gold's heading was wrapping to a second line that
  collided with the subtitle below it. Both fixed with size/width
  adjustments verified by direct canvas measurement.
- All 6 signature templates are selectable in Settings again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 10:14:25 +03:00
pavlov346346-source
51e2fa4c33 feat: give cream-elegance and neon-menu their own matching inner pages
The cover for these 2 templates was fully custom, but the item-list
and pricing pages behind it still came from the old generic base
renderer (Arial, different card style, different page chrome) — so a
downloaded offer read as a nice cover stapled to a plain, differently
styled document ("два предложения").

Both templates now render their own item-list pages (photo, name,
category/weight, qty and line total, paginated ~10 rows/page) and a
matching pricing-breakdown page (base cost, discount, promo, delivery,
total, per-guest), using the same fonts, palette and card language as
the cover, with a shared footer/page-number treatment across every
page. The other 4 signature templates and the 13 classic ones are
untouched and keep using the original base renderer.

Verified locally: 8 items -> 3 pages (cover + 1 menu + pricing),
15 items -> 4 pages (cover + 2 menu + pricing), 0 items -> 3 pages,
no errors, base renderer confirmed never invoked for these 2 ids.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 09:58:07 +03:00
pavlov346346-source
c0bb18d5f7 fix: polish the 2 kept offer templates — alignment, fonts, gallery
- Fix a systemic centering bug: several canvas text() calls used
  align:'center' but passed the box's left edge as x instead of its
  midpoint, so headings, badge numbers, checkmarks and chip labels
  rendered pinned to the left instead of centered (most visible on
  cream-elegance's "МЕНЮ" heading and neon-menu's guest badge).
- Fix cream-elegance's category icons: the emoji glyph was never
  actually passed into iconCircle, so the icon circles rendered empty.
- Even out cream-elegance's bottom row (stat cards vs price band had
  mismatched heights).
- Load distinctive Cyrillic-friendly type pairs instead of default
  Arial/Georgia: Playfair Display + Montserrat for cream-elegance,
  Unbounded + Manrope for neon-menu, awaited via the Font Loading API
  before each render so text never draws in the fallback face.
- Narrow the Settings gallery to just these two templates per request
  ("остановимся на 2х пдф пока"); the other 4 signature designs and
  the original 13 classic templates stay intact and renderable for any
  order that already used one, just not offered for new ones.

Verified via a local static server (public/, http-server) with a real
uploaded box photo run through window.SunSignatureOfferPDFV18 and the
production sunClientOfferDebugPdfPages pipeline directly — 3 pages,
no duplicate cover, both fonts confirmed loaded via document.fonts.check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 08:49:39 +03:00
pavlov346346-source
90482d0e7d fix: stop signature PDF pages from double-rendering a cover
renderOfferPdfPages routed the signature templates' inner pages back
through the classic module's own renderPages, which drew its own
extra cover page on top of the real content pages -- doubling the
render work and producing an extra page. Route straight to the plain
base renderer instead. Also await the gourmet-hero template's photo
cards instead of firing them off unawaited.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 18:42:32 +03:00
pavlov346346-source
b92b52e03e feat: add 6 new client-offer PDF templates, archive the old 13
New "signature" template pack (cream-elegance, neon-menu,
emerald-circles, midnight-checklist, gourmet-hero, diamond-gold)
replaces the visible template gallery in Settings. The previous 13
classic/archive templates keep rendering correctly for any existing
order that already used one, but are no longer selectable for new
orders — nothing was deleted.

Also adds a Settings option to upload a custom logo and company name
for PDF documents, replacing the hardcoded "Солнце Кейтеринг" branding
wherever a logo fails to load.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 18:27:23 +03:00
pavlov346346-source
79b470d03f fix: fall back to direct Supabase auth on proxy 500 2026-09-14 17:26:32 +03:00
pavlov346346-source
5b827b4e09 fix: reopen app after persisted login session 2026-09-14 16:57:45 +03:00