Commit Graph

2168 Commits

Author SHA1 Message Date
Scott Idem
81aa0eefcd fix(badges): properly suppress pronouns and lead scanning with {#if false}
HTML comments don't suppress Svelte {#if} blocks — the content was rendering
unconditionally. Switch to {#if false} so the blocks are genuinely hidden.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 23:29:36 -04:00
Scott Idem
430d39231d temp(badges): comment out pronouns and lead scanning for Axonius 2026
Lead scanning was canceled last-minute; pronouns not on this badge template.
Both blocks left in source with AXONIUS 2026 markers for easy restoration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 23:14:35 -04:00
Scott Idem
5203104fef refactor(badges): move hide toggle + print count editor to individual badge view
Hide/Unhide and print count edit belong on the per-badge page (print controls
staff section), not the search list — the list was getting too crowded.

- ae_comp__badge_obj_li: removed hide toggle, print count input, and the
  ae_api/events_func imports that were only there to support them
- ae_comp__badge_print_controls: added Hide Badge button (Trusted, top of staff
  section) and Print Count editor (Admin+, below hide); both reuse the existing
  save_field/field_save_status pattern for consistent spinner/done/error feedback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 22:44:58 -04:00
Scott Idem
bf31f13650 fix(badges): gate Show Hidden filter on trusted_access + edit_mode
Lower access levels (authenticated, public) can have edit_mode active.
Show Hidden must be trusted+ only — split it out of the generic edit_mode block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 22:38:58 -04:00
Scott Idem
7bc7bf5554 feat(badges): hide toggle, print count editor, show hidden filter
- Hide/Unhide toggle button (Trusted + Edit Mode) on each badge row in the list; badge disappears immediately when hidden unless Show Hidden is active
- Print count inline editor in debug row (Admin + Edit Mode); updates count only, no timestamp changes
- "Show Hidden" checkbox in search filters (Trusted + Edit Mode); wires through IDB fast-path, API hidden param, and visible_badge_obj_li filter
- show_hidden requires edit_mode to be active — reverts to hiding hidden badges when edit mode is off

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 22:21:08 -04:00
Scott Idem
6aeaef6f1d fix(badges): trusted staff visibility driven by filter, not edit mode
Edit mode should not override the filter state — staff set their
filters and turn off edit mode all the time. The real split is
trusted staff vs kiosk/public, not edit mode on/off.

Trusted and above: qry_printed_status is the sole control over
printed badge visibility, regardless of edit mode state.

Public (kiosk) / authenticated / anonymous: always unprinted only.
Badge kiosks run at public_access and should never expose a list
of already-printed badges to attendees.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 19:44:30 -04:00
Scott Idem
ae00ddffb0 fix(badges): fix Printed/Not Printed filter visibility and API query
Two bugs:

1. visible_badge_obj_li gated on trusted+edit_mode, but the filter
   dropdown is also accessible to manager+ without edit_mode. Changed
   gate to (trusted+edit) || manager_access to match the filter's own
   access condition.

2. not_printed API query used print_count eq 0, which does not match
   NULL in SQL. Unprinted badges have print_count = NULL, so the API
   was returning 0 results and overwriting the correct IDB fast-path
   results. Removed the not_printed condition from the API query —
   IDB fast path (print_count ?? 0) < 1 and visible_badge_obj_li
   both handle NULL correctly and are the authoritative filter for
   that case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 19:39:58 -04:00
Scott Idem
8d430a9c31 fix(badges): drive printed badge visibility from status filter not edit_mode
Previously edit_mode was a blunt override: trusted+edit showed all
badges regardless of the filter setting. This meant the Printed Status
dropdown had no effect on what was visible in the list.

Now trusted+edit mode respects qry_printed_status as the single source
of truth: 'all' shows everything, 'printed' shows only printed, and
'not_printed' shows only unprinted. The filter dropdown is only
accessible to trusted+edit users so it is safe to use as the control.

Kiosk/attendee behavior (trusted no edit, public, anonymous) unchanged:
only unprinted badges are shown regardless of filter state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 19:24:24 -04:00
Scott Idem
f6051156cf fix(badges): include sort selection in active-filters check
Sort changes without a text query were falling through to the fallback
liveQuery (50 badges sorted by given_name), ignoring the selected sort
entirely. Added params.sort to has_active_filters so any explicit sort
selection triggers the full search path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 19:15:11 -04:00
Scott Idem
d64222ca91 fix(badges): implement missing sort cases for all sort options
All four sort options in the dropdown were falling through to the
default (given_name ASC) because their cases were missing from both
the IDB fast-path sort and the API order_by_li mapping:

- Affiliations ASC: IDB sorts by affiliations_override → affiliations;
  API sorts by affiliations column
- Badge Type ASC: badge_type_code ASC
- First Printed DESC: print_first_datetime DESC
- Last Printed DESC: print_last_datetime DESC

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:57:03 -04:00
Scott Idem
acf0a13955 fix(badges): update badge type list and fix filter-only search
Update badge type codes for Axonius 2026 (replaces ISHLT 2024 list).
Added TODO to drive this from event templates in the future.

Fix printed status and badge type filters not working without a text
query. The min_chars guard was blocking all filter-only searches,
causing "Printed" and "Not Printed" to always return empty results.
Now bypasses min_chars when any non-default filter is active (printed
status, type code, or affiliations), since selecting a filter is
explicit user intent regardless of the text query.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:42:04 -04:00
Scott Idem
5826b21821 feat(badges): allow public_access to print first-print badges
Badge print kiosks authenticate at the public_access level (site-wide
passcode). Previously the print gate was trusted_access, meaning kiosk
operators had to sign in at the trusted level just to print.

Changed in both the list view and the badge detail controls panel:
- First print: public_access and above (kiosk use case)
- Reprint: still requires trusted_access + edit_mode

ae_comp__badge_obj_li.svelte: added is_public derived; updated
can_print and the print button #if condition.

ae_comp__badge_print_controls.svelte: added is_public derived; updated
can_print comment and logic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:01:47 -04:00
Scott Idem
ad3b27b747 fix(badges): auto-save font sizes on adjustment
Font size changes now persist automatically (600ms debounce) without
requiring the user to find and click Lock Sizes in the collapsed Staff
section. reset_font_sizes_to_auto continues to handle its own save.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:37:31 -04:00
Scott Idem
15566efec1 revert(badges): remove _random workaround on badge create template ID
Per V3 convention, {obj_type}_id IS the random string — send
event_badge_template_id (not _random). The backend not saving it is
a backend bug, not a frontend concern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 18:37:16 -04:00
Scott Idem
5e07f2822c fix(badges): send event_badge_template_id_random on badge create
The IDB stores the random string in event_badge_template_id (overwritten
by _process_generic_props). Sending this as event_badge_template_id
passed a string to an int(11) FK column — backend silently ignored it.
Using event_badge_template_id_random lets the V3 CRUD handler resolve
it to the correct integer FK.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 18:34:54 -04:00
Scott Idem
d35a28f912 ui(badges): show template name on create form when only one exists
Single-template events auto-select silently but gave no visual
confirmation. Added a read-only display of the template name so staff
can verify the correct template is in use before submitting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 18:06:26 -04:00
Scott Idem
2e01e7f115 fix(badges): always pre-select first template on badge create
Every badged event must have a template — without one the badge cannot
render. Changed auto-select from === 1 to >= 1 so multi-template events
also get a default (first template). Added an error message and disabled
submit when no templates are configured at all. Removed blank
"-- Select Template --" option so the form never submits with null.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 18:03:15 -04:00
Scott Idem
f7ddcaa448 fix(badges): use base fields instead of _override on badge create
Professional title, organization, and location entered during manual
badge creation were being stored in the *_override fields. Override
fields are intended for overriding imported/AMS person data — for new
manually created badges, the base fields (professional_title,
affiliations, location) are correct.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 17:53:48 -04:00
Scott Idem
940e25d549 fix(theme): add missing color ramps to AE_Firefly_Axonius
Each data-theme selector is fully self-contained — CSS custom properties
do not inherit across theme selectors. The Axonius file only defined the
primary ramp, leaving surface/secondary/tertiary/success/warning/error
undefined, causing the UI to render in grey/black/white.

Added full color ramps and dark-mode contrast tokens (matching base
AE_Firefly) to both light and dark blocks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 20:52:58 -04:00
Scott Idem
22d62ba3b1 Adjusting styles Axonius 2026-04-10 19:42:41 -04:00
Scott Idem
c7fa75afc7 ui(badges): add background image bleed support (cfg_json, PVC layout)
- Add `bleed` field to BadgeTemplateCfg (CSS length, e.g. "0.125in")
- Badge view: derive bleed_offset, move bg-image to absolute positioned div
  that extends past card edges; add isolation:isolate to badge_front stacking context
- Template form: add bleed input in Advanced > Appearance; wire to cfg_json save/load
- PVC layout CSS: change overflow:hidden → overflow:visible in print rule to allow
  bleed div to render at physical card boundary (Zebra driver clips at card edge)
- Prevents white borders on PVC cards when printer has slight alignment variance.
  Screen preview shows bleed visually extending past the card outline.
2026-04-10 14:25:08 -04:00
Scott Idem
cfdec1e305 Forgot to include this update 2026-04-10 11:53:38 -04:00
Scott Idem
bfe02727bf docs(passcode): note backend fixes implemented and tested; phase 2 pending 2026-04-10 11:53:00 -04:00
Scott Idem
e542c55500 ui(badges): layout & fit-text tweaks; improve template form controls; remove badge modals from event settings; add documentation for passcode security 2026-04-10 11:44:22 -04:00
Scott Idem
c9e2284758 Badges: per-badge locked font sizes via cfg_json
Allows coordinators to pre-tune font sizes for attendees with long names
and have those sizes apply automatically on every kiosk, not just one machine.

- ae_types.ts: add cfg_json to ae_EventBadge interface
- db_events.ts: add cfg_json to Badge Dexie interface
- ae_events__event_badge.ts: add cfg_json to properties_to_save so it is
  persisted to IndexedDB on load and returned by the API
- print/+page.svelte: on first load per badge, read cfg_json.font_sizes and
  initialize font_size_name/title/affiliations/location state from saved values
  (guarded by _font_sizes_loaded_for to avoid clobbering user adjustments on
  background liveQuery refreshes)
- ae_comp__badge_print_controls.svelte: add lock_font_sizes() and
  reset_font_sizes_to_auto() functions; add Lock Sizes / Auto reset UI in the
  Staff adjustments section (trusted-only); button shows warning style when
  sizes are unsaved vs success when locked; status indicator shows what is
  currently locked

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 21:47:34 -04:00
Scott Idem
941ad6ae88 Badges: template controls cfg, collapsible form sections, navigation polish
- badge_template_form: fix default field visibility (location off render, pronouns/leads excluded from controls); fix duplicate QR checkboxes by removing orphan show_qr_front/back state vars; reorganize Advanced cfg_json into labeled sub-groups; make all 5 non-Advanced sections collapsible (general starts open, rest collapsed)
- print_controls: add DEFAULT_SHOWN constant so field_shown() uses explicit whitelist fallback instead of showing all fields when no controls_cfg is set
- badges config +page: add Templates navigation button in header (FileText icon)
- templates +page: add back-nav header with ArrowLeft to badges/config, Settings icon, page title

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 20:31:38 -04:00
Scott Idem
d05420d9c1 Badges: persist template controls_cfg; fix onchange syntax in template form 2026-04-09 15:10:03 -04:00
Scott Idem
76c28a7e22 Updated to do list. Cleaned up the badge search area at the top of the badge. Also tested the upload option 2026-04-09 14:31:29 -04:00
Scott Idem
a84ea4cbcb Cleaned up the Badges main search area and the top in general. 2026-04-08 17:34:05 -04:00
Scott Idem
dd4c558d1b feat(badges): add Axonius Zoom CSV server import option to upload form 2026-04-08 17:10:55 -04:00
Scott Idem
d7b49efdde Apply site cfg_json theme when persisted ae_loc shows no explicit user-theme; parse persisted ae_loc to detect prior user choice 2026-04-08 16:43:47 -04:00
Scott Idem
fec08fdfbf Respect site cfg_json theme on first-run; add user_theme_selected flag; set flag when user selects theme or URL param 2026-04-08 16:38:12 -04:00
Scott Idem
32ed4e47a8 Remove outline... 2026-04-08 16:13:36 -04:00
Scott Idem
534bda9203 Apply site.cfg_json theme defaults only on first-run (no persisted ae_loc); preserve manual/URL overrides 2026-04-08 16:07:20 -04:00
Scott Idem
8aef519aa6 Apply site.cfg_json theme defaults to ae_loc (theme_name, theme_mode); allow URL param to override 2026-04-08 15:43:15 -04:00
Scott Idem
dd339a7280 Better for the small screens now. 2026-04-08 15:19:07 -04:00
Scott Idem
3659fef17c chore(badges): add 'Start Here' helper button to focus fulltext search input 2026-04-08 15:14:18 -04:00
Scott Idem
d5b2b557f3 chore(badges): hex-only body_text_color + form color picker; renderer default black 2026-04-08 14:19:48 -04:00
Scott Idem
0aa32a5293 chore(tailwind): safelist common text-* color utilities for dynamic classes 2026-04-08 13:42:47 -04:00
Scott Idem
ef5c807c27 chore(badges): tidy badge template form grouping and advanced cfg_json 2026-04-08 13:29:11 -04:00
Scott Idem
b02843e467 feat(badges): cfg_json body_text_color applied in renderer 2026-04-08 12:32:13 -04:00
Scott Idem
56b4e5c627 Slight change to header and footer background colors. 2026-04-08 11:56:02 -04:00
Scott Idem
b64db756ad Add AE_Firefly_BGH theme; align typography tokens for Axonius/BGH; register themes in UI 2026-04-08 11:42:34 -04:00
Scott Idem
590139e63a New style option for Axonius 2026. Set as default for them as well in their site config.
Also general style clean ups
2026-04-08 10:21:08 -04:00
Scott Idem
372d79df2b docs(idaa): track contact_li_json_ext search gap + message sent to backend
- TODO__Agents.md: added task for contact search — backend to whitelist
  contact_li_json_ext in event search, frontend to add OR condition in
  search__event() and update local IDB fast-path filter. Blocked on backend.

- CLIENT__IDAA_and_customized_mods.md: documented the search architecture
  gap under Recovery Meetings — what default_qry_str contains, why
  contact_li_json is unsearchable as raw JSON, what contact_li_json_ext is
  and what needs to happen to enable contact name/email search.

Backend agent notified via ae_send_message 2026-04-08.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:20:59 -04:00
Scott Idem
c979454d84 docs(idaa): update IDAA doc with staff editing rules, Contact 1 convention, test coverage
- Added Section 4 'Staff Editing Rules': documents per-object behavior when
  trusted/admin staff edit member content. BB Post external_person_id is readonly
  for non-admin staff; Post Comment preserves existing record identity; Recovery
  Meeting external_person_id is intentionally editable for ownership reassignment.
  Clarifies that staff identity only fills when the record has no existing linkage.

- Added Section 5 'Recovery Meetings — Contact 1 Convention': states the business
  rule that Contact 1 is nearly always the same person as external_person_id (the
  meeting owner). Documents the distinction between ownership link vs. display contact.

- Added race condition defense note to Section 3 Implementation Patterns: creation
  buttons and edit submit handlers must scavenge from localStorage when the Svelte
  store is briefly null on mount.

- Updated test coverage table: Recovery Meetings now has substantial Playwright
  coverage (idaa_recovery_meeting_edit.test.ts). Noted pending BB Post/Comment tests.

- Updated Last Verified date to 2026-04-07.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 22:41:49 -04:00
Scott Idem
8d30e01ad4 fix(idaa): harden identity linkage in BB post and comment edit handlers
Three targeted fixes following code review of the Novi UUID linkage commit:

1. ae_idaa_comp__post_obj_id_edit.svelte — Add localStorage scavenge fallback
   in handle_submit_form() for external_person_id / full_name / email.
   WHY: The form input falls back to $idaa_loc.novi_uuid at render time only.
   On a race-condition mount where the store was null, the input captures an
   empty string.  Without this, a subsequent PATCH on a legacy post (no
   external_person_id) would overwrite the field with an empty string, permanently
   breaking the Novi linkage for that record.  The scavenge re-checks the live
   store and then localStorage before submitting.

2. ae_idaa_comp__post_options.svelte — Fix double alert() on creation failure.
   WHY: The .catch() handler alerted the user and reset 'creating'.  The
   .finally() block then ran unconditionally and fired a second alert when
   final_id was null (which it always is on failure).  User saw two dialogs.
   Fixed by removing the duplicate alert from .finally() — it now only resets
   the 'creating' flag, which .catch() may have already done (harmless reset).

3. ae_idaa_comp__post_comment_obj_id_edit.svelte — Remove 'log_lvl = 1' mutation.
   WHY: log_lvl is a $bindable prop.  Assigning to it inside handle_submit_form()
   unconditionally mutated the parent binding on every single form submission,
   overriding the caller's logging preference.  This was debug code accidentally
   left in.  Removed; the existing 'if (log_lvl)' guard is sufficient.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 22:23:33 -04:00
Scott Idem
f2765d6a5e feat(idaa): enforce mandatory Novi UUID linkage for member content
CRITICAL IDENTITY FIX:
Ensures all member-generated content (Meetings, Posts, Comments) is explicitly linked to the creator's Novi UUID via 'external_person_id' at the moment of creation.

Changes:
- Added 'external_person_id' to creation payloads in Recovery Meetings and BB Posts.
- Implemented 'identity scavenging' from localStorage in submit handlers to prevent race conditions where Svelte stores are briefly null.
- Refactored Post Comment edit component to robustly initialize and save creator identity.
- Added 'The Novi UUID Rule' to IDAA documentation to mandate this pattern for future development.
- Added Playwright test to verify creation linkage and fixed a version-mismatch bug in the test auth helper.

Note: Archives and Archive Content are excluded as they do not require member ownership.
2026-04-07 22:07:53 -04:00
Scott Idem
ef45a0ca0f feat(badges): TC modal centering, positioning, and allow-tracking toggle
- Center modal horizontally; position 10vh from top instead of centered vertically
- Add Allow/Do-not-allow toggle buttons inside the TC modal so attendees
  can set their lead scanning preference while reading the terms
- Buttons reflect current DB value on open and use solid color fills
  (green/red) so selection state is unambiguous in light and dark mode
- Save & Close calls existing save_field('allow_tracking') then closes;
  Cancel closes without saving

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 20:29:41 -04:00
Scott Idem
b01478a87f More layout and style clean up and related. 2026-04-07 19:04:27 -04:00