Commit Graph

1098 Commits

Author SHA1 Message Date
Scott Idem
ab294c2a0b Sorry. Quick save to make something live before deadline. 2026-03-25 18:31:39 -04:00
Scott Idem
0091fe3ff6 Updates to the documentation about the id_random legacy. 2026-03-25 17:43:15 -04:00
Scott Idem
0ad36a74b2 Fix: system bar hide logic for iframe and menu param overrides (IDAA embed reliability) 2026-03-25 15:49:41 -04:00
Scott Idem
fd244720a7 Update to AE API v3 for the hosted file hash check. 2026-03-25 13:17:25 -04:00
Scott Idem
362136e677 fix(upload): update clip_video endpoint to V3 action path
The legacy /hosted_file/{id}/clip_video route was decommissioned with the
rest of the hosted_file router. Updated to /v3/action/hosted_file/{id}/clip_video.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 12:30:23 -04:00
Scott Idem
a5a806e256 fix(upload): update hosted file upload endpoint to V3 action path
The legacy /hosted_file/upload_files router was decommissioned (commented
out in registry.py). Both upload components now point to the active V3
endpoint at /v3/action/hosted_file/upload. Response shape is identical
so no consumer-side changes needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 12:11:00 -04:00
Scott Idem
613e43114c fix(idaa): correct reactive loop fix + hide clutter in iframe sys bar
1. Replace incorrect untrack() with idempotent write guard in the
   sys_menu trusted-access effect. untrack() prevents new dep reads but
   ae_loc was already tracked from the outer condition reads, so the write
   still re-notified the effect every run. The guard (only write if value
   != false) breaks the cycle: run 2 finds value already false, skips the
   write, effect stops. Max 2 runs vs the previous infinite loop.

2. Hide auth shield, font-size cycler, and dark/light toggle in the sys
   bar when in iframe mode — host page owns those concerns. Edit mode
   toggle and the main expand button remain visible for staff.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 11:39:24 -04:00
Scott Idem
66f0efb507 fix(store): guard localStorage calls for Node/SSR builds 2026-03-24 16:46:52 -04:00
Scott Idem
a8f3c29b9f Last round of prettier: npx prettier --write src/ 2026-03-24 13:27:40 -04:00
Scott Idem
94849137f0 I think pretty much all references to v1 and v2 have been removed. All files have been renamed from _v3 to just the function/var name with out the appended version. Assume no _vX is the current version. 2026-03-24 11:32:06 -04:00
Scott Idem
512e5ef87c Saving more code clean up and removal 2026-03-24 11:15:01 -04:00
Scott Idem
d27ec58fe9 More code clean up 2026-03-24 10:56:31 -04:00
Scott Idem
42358efe7d More code clean up 2026-03-24 10:54:40 -04:00
Scott Idem
8e61bd0ba1 More and more code removal and clean up 2026-03-24 10:42:40 -04:00
Scott Idem
0bc71391fc Cleaning up and removing old legacy code and files 2026-03-24 10:28:54 -04:00
Scott Idem
6e22639e6e fix(api): pass real account_id for lookup requests instead of bypass header
The x-no-account-id bypass was hardcoded to resolve account_id=1 on the
backend, causing account-scoped lookup overrides (e.g. custom country names)
to leak to all callers regardless of their account.

Removing the bypass lets get_object auto-promote the real account_id from
api_cfg, so the backend's existing account filter works correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 20:00:28 -04:00
Scott Idem
a6f8ff709e fix(idaa): fix country/subdivision/timezone dropdowns — switch to in-memory sort
- Country and state/province fields were showing as plain text inputs because
  liveQuery used orderBy() on non-indexed columns, causing silent Dexie errors
  that left the store as undefined indefinitely.
- Fix: replaced orderBy() with toArray() + in-memory sort across all three
  lookup types (country, country_subdivision, time_zone).
- Sort convention matches Aether backend: sort DESC (higher = first, NULL=0
  last), then name ASC — puts priority entries at the top.
- Added db_lookups.ts (IDB schema for lookup tables) and updated core__countries,
  core__country_subdivisions, core__time_zones to IDB-backed SWR pattern.
- Affected: archive edit, archive content edit, recovery meeting edit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 18:44:24 -04:00
Scott Idem
f3ab1c1050 fix(idaa/recovery_meetings): fix weekday chips, recurring fields, and timezone lookup
- Weekday chips: replace bind:checked (unreliable with dynamic bracket notation in
  {#each}) with explicit onchange handlers + class: directives; read weekdays from
  state in submit handler instead of FormData
- Recurring pattern/times: bind select and time inputs to working copy
  so values display and edit correctly
- Times clearing: map empty string to null so times can be cleared once set
- liveQuery guard: skip event_obj sync while edit form is open to prevent
  background refresh from overwriting in-progress user changes
- Timezone lookup: forward order_by_li, limit, offset through the full call chain
  so priority sort and result count params are actually sent to the API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 16:05:16 -04:00
Scott Idem
a14320d9ed idaa(recovery_meetings): sanitize Zoom encrypted passcode to avoid saving literal 'null' and normalize related fields 2026-03-23 14:23:29 -04:00
Scott Idem
fe23899479 feat: leads QR UX — merged confirm modes, faster scanning, correct capture identity
- Merge Rapid + Qualify scan modes into single Confirm mode with two-button card:
  "Add & Scan Next" (resets) and "Add & View Lead" (navigates to detail). Same
  two-button pattern on the reenable card: "Restore & Scan Next" / "Restore & View Lead".
  Stale 'qualify' localStorage values normalized to 'rapid' via $derived.by().
- QR scanner speed: fps 10→25, qrbox 82%→88%, useBarCodeDetectorIfSupported (native
  BarcodeDetector API on Chrome/Edge — significantly faster than ZXing JS fallback)
- Fix capture identity stored in external_person_id / group:
  licensed exhibit user → their email; shared passcode → 'shared_passcode' label
  (not the raw passcode); Aether user bypassing exhibit sign-in → access_type string
  ('trusted', 'manager', 'super', etc.). Consistent across all three lead capture
  components (single scanner, multi scanner, manual search).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 19:15:35 -04:00
Scott Idem
6662e82f40 feat: leads re-enable flow — detect removed leads on scan + Remove/Restore buttons
- QR scanner (single + multi): detect previously-removed leads via IDB enable flag;
  route to 'reenable' state instead of duplicate error; offer Re-activate button
- API fallback: if create fails and no IDB record, search API for disabled tracking
  record by event_exhibit_id + event_badge_id (adds qry_badge_id param to
  search__exhibit_tracking)
- Lead detail page: Replace raw enable checkbox with Remove Lead (two-click confirm,
  navigates back after) and Restore Lead card (shown when enable is falsy)
- Fix flash of disabled records in leads list: filter !enable in both filtered_lead_li
  derived and local IDB fast-path in handle_search_refresh
- eslint.config.js: disable svelte/no-navigation-without-resolve (no base path configured)
- Also includes _random field annotation cleanup (db_events, ae_types), iframe layout
  fixes, badge view tweaks, test updates, and doc updates from prior session

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 18:18:10 -04:00
Scott Idem
334c3a21bc feat: leads QR scanner — Auto/Multi modes, 4-mode fancy selector, UX polish
Scanner modes (now 4, persisted per exhibit):
- Rapid:   confirm tap → auto-reset (existing, fixed)
- Qualify: confirm tap → navigate to lead detail (existing, fixed)
- Auto:    badge found → auto-add immediately, no confirmation tap needed
- Multi:   BarcodeDetector batch scan → responsive grid of confirm cards

Multi scanner (new ae_comp__lead_qr_scanner_multi.svelte):
- Native BarcodeDetector API (Chrome/Edge/Safari 17+); Firefox fallback message
- 16:9 viewfinder with corner guides + "Align up to 4 badges flat" overlay
- Capture Batch tap → up to 8 QR codes detected in one frame
- Per-card states: loading skeleton, ready (Add/Skip), blocked (opt-out),
  already-captured (View/OK), adding spinner, success (auto-fade), error
- Add All (N) bulk action; cards fade+scale out smoothly on dismiss

Mode selector (ae_tab__add.svelte):
- Replaces Rapid/Qualify toggle with collapsible 4-mode fancy select
- Trigger shows active mode icon (color-coded) + name + description
- 2×2 options grid expands on tap, closes on selection

QR scanner element (element_qr_scanner_v3.svelte):
- object-fit: cover eliminates 4:3 camera letterbox dead zone
- 7-second start timeout with actionable error message
- Starting/error overlays with high-contrast styling
- Try Again button with RefreshCw icon

Style guide updated: icon+text button rule (§8), btn/preset-filled workaround (§12)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 16:30:38 -04:00
Scott Idem
14c2635df4 docs + fix: Leads module doc, badges onsite doc, license access fix, QR log cleanup
- Add MODULE__AE_Events_Exhibitor_Leads.md — full module reference (auth model, tabs,
  data model, routes, offline/PWA notes, OSIT admin notes)
- Add MODULE__AE_Events_Badges_Onsite.md — onsite printing guide (browser settings,
  CUPS/Linux setup, Zebra ZC10L section with test results, Epson stub, troubleshooting)
- Archive PROJECT__AE_Events_Exhibitor_Leads_v3*.md + Zebra test day doc → history/
- Fix leads license management access: ae_tab__manage.svelte license section now visible
  to administrator_access OR shared-passcode sign-in (type === 'shared'); matches spec
- Add type field to LeadsLocState.auth_exhibit_kv interface (was set at runtime but missing from type)
- Silence QR code console noise: entry log gated at log_lvl >= 2, data URL log removed
- vite.config.ts: exclude documentation/ and tests/ from Vite HMR file watcher

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 12:58:57 -04:00
Scott Idem
9673cbefe3 fix: PWA install prompt — capture beforeinstallprompt at module load time
The browser fires beforeinstallprompt very early (~1s after page load),
before Svelte's $effects run. Moving the event listener registration to
module level ensures we never miss the event regardless of when init()
is called from the root layout.

init() now only handles dismiss state (localStorage) and standalone
detection (DOM) — both safe to defer until after component mount.

Platforms:
- Chrome / Chromium / Android: native install button via captured prompt
- iOS Safari: manual Share → Add to Home Screen instructions (unchanged)
- Firefox desktop: no beforeinstallprompt support (browser-level limitation);
  Firefox shows its own install button in the address bar automatically

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 11:14:17 -04:00
Scott Idem
bb0365f1e8 chore: move tiptap scss to styles/, trash orphaned codemirror files, update project doc
- element_tiptap_editor.scss → elements/styles/ (single importer path updated)
- Trashed element_codemirror_editor.svelte and element_codemirror_editor_wrapper.svelte (zero importers — active component is element_editor_codemirror.svelte)
- PROJECT__AE_Object_Field_Editor_V3_upgrade.md: mark v1/v2 removal complete, update status to 🟡 Mostly Complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:58:46 -04:00
Scott Idem
2b747de9bd chore: retire CRUD v1/v2 components — both were already unused
element_ae_crud.svelte and element_ae_crud_v2.svelte had zero active
importers; only a commented-out reference remained. Moved both to trash
and removed the dead comment from ae_comp__event_presentation_obj_li.svelte.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:54:33 -04:00
Scott Idem
519f5b949c chore: move ae_events_functions.ts into ae_events/ module
Relocates the functions file from lib root into its module directory,
matching the pattern used by all other modules (ae_journals, ae_archives, etc.).
Updated all 85 import paths from \$lib/ae_events_functions → \$lib/ae_events/ae_events_functions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:52:13 -04:00
Scott Idem
bf834aa165 chore: rename editor components and analytics to follow element_* convention
- AE_Comp_Editor_CodeMirror.svelte → element_editor_codemirror.svelte
- AE_Comp_Editor_TipTap.svelte → element_editor_tiptap.svelte
- analytics.svelte → e_app_analytics.svelte (matches e_app_* prefix of siblings)
- Updated all import paths; import variable names unchanged

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:49:57 -04:00
Scott Idem
0d960435f8 chore: remove orphaned legacy files and move QR scanner to elements/
- Trashed 10 unreferenced files: core .legacy types, bak files, element_modal_v1, element_websocket_v2, AE_MetadataFooter_not_ref, element_qr_scanner_v2
- Removed empty placeholder dirs: ae_db/, hooks/
- Moved element_qr_scanner_v3.svelte from lib root into elements/
- Updated 2 import paths for QR scanner (badges + leads)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:45:57 -04:00
Scott Idem
621a637b85 feat: badge print UX improvements — chrome toggle, banner width, overlap fix, header centering
- Replace ae_comp__badge_obj_view_v2 with ae_comp__badge_obj_view (consolidated component)
- Add hide-chrome toggle ([H] shortcut + button) to hide site nav/footer/sys bar for clean print workspace
  — syncs $ae_loc.sys_menu.hide + $ae_sess.disable_sys_nav/footer with restore-on-unmount
- Add banner_full_width toggle (default true=100% width, false=natural pixel size for calibration)
- Center badge header image (display:block; margin:0 auto) — was left-aligned when narrower than badge
- Fix controls panel overlap: move from bottom-0 to bottom-24 to clear sys bar (84px tall)
- Add [H] keyboard shortcut for chrome toggle (guards against focus in inputs)
- Persist hide_chrome and banner_full_width in ae_badge_print_tweaks localStorage key
- Add sample header image assets (calibration SVG/PNG, hex blue SVG/PNG, demo PNG)
- Update badge PVC CSS layout and module docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 15:42:22 -04:00
Scott Idem
9fc3ee0198 fix(imports): point to element_data_store_v3 and restore Data Store v3; commit workspace updates 2026-03-17 18:57:27 -04:00
Scott Idem
adef935188 chore: aggressive cleanup: remove legacy element_data_store.svelte (v1) after v3 migration 2026-03-17 12:22:00 -04:00
Scott Idem
e085a1d513 chore: remove broken/redundant components imported from WIP branch 2026-03-17 10:51:58 -04:00
Scott Idem
47f0ee0e81 chore: remove unused element_data_store_v2.svelte 2026-03-17 10:45:34 -04:00
Scott Idem
df8189cd66 cherry: import element_input_v2.svelte from wip-modal-fix-attempt 2026-03-17 10:32:59 -04:00
Scott Idem
cedf76344b cherry: import element_data_store_v2.svelte from wip-modal-fix-attempt 2026-03-17 10:32:39 -04:00
Scott Idem
1156e02e48 cherry: import element_modal_v1.svelte from wip-modal-fix-attempt 2026-03-17 10:29:37 -04:00
Scott Idem
f92058d394 refactor: Remove all legacy variant-* class usage from Svelte components, enforce preset-* (Skeleton v4) everywhere 2026-03-16 19:01:46 -04:00
Scott Idem
0cebd3868b docs+utils: Remove all legacy variant-* class references, update all docs and snippets to use only preset-* (Skeleton v4) 2026-03-16 18:59:21 -04:00
Scott Idem
b543c8a930 chore: migrate all FA icons to Lucide (@lucide/svelte)
- Replaced all active FontAwesome <span class="fas fa-*"> icons with
  Lucide components across 145 files (excluding /idaa/ which is intentional)
- Fixed merge script bug: consolidated lucide-svelte imports into @lucide/svelte
- Replaced dynamic toggle patterns (fa-toggle-on/off) with ToggleRight/ToggleLeft
- Replaced fa-eye/fa-eye-slash with Eye/EyeOff
- Replaced fa-bug/fa-bug-slash with Bug/BugOff
- Replaced fa-sync fa-spin with RefreshCw + animate-spin
- Replaced fa-microchip with Cpu
- Fixed {@const} placement in element_manage_event_file_li.svelte
- Removed obsolete CSS hover rules for .unlock_icon/.lock_icon
- svelte-check: 0 errors, 0 warnings
2026-03-16 18:07:43 -04:00
Scott Idem
c9050264a5 fix: hide passcode input after successful validation
When a passcode matched, entered_passcode was cleared and the trigger
was set, but show_passcode_input was never set to false. This left the
input visible so users could keep typing after access was granted.

Set show_passcode_input = false immediately after clearing entered_passcode
on a successful match, consistent with the intent described in the
handle_clear_access() function which resets it to true on clear.
2026-03-16 17:54:52 -04:00
Scott Idem
464b63c1a3 refactor(leads): export function → V3 action endpoint
Updated download_export__event_exhibit_tracking to call
/v3/action/event_exhibit/{exhibit_id}/tracking_export instead of the
legacy /event/exhibit/{exhibit_id}/tracking/export (V1 path).

Added doc comment listing the expected export columns so the backend
agent has the full field spec when implementing the endpoint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 16:05:18 -04:00
Scott Idem
be24cfdeb5 feat(leads): allow_tracking gate + icon bug fix + docs update
- QR scanner: after badge loads, blocks add with 'Tracking Opt-Out' warning
  card if allow_tracking !== true; replaced deprecated CheckCircle → CircleCheck
- Manual search: shows ShieldOff 'Opt-Out' label per row for blocked badges;
  add_as_lead() also guards against programmatic bypass
- Fix: ae_comp__exhibit_tracking_obj_li — Loader2 from wrong package
  @lucide/svelte → LoaderCircle from lucide-svelte
- ae_types.ts: added allow_tracking and agree_to_tc to ae_EventBadge interface
- README.md (leads): full rewrite reflecting actual current state and known gaps
- TODO__Agents.md: updated Leads entry from stale 'NEXT MAJOR FEATURE' to
  accurate in-progress status with remaining checklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:59:26 -04:00
Scott Idem
b8104b3ff2 feat(stores): Phase 2b — TypeScript interfaces for store defaults sub-files
ae_stores__auth_loc_defaults.ts
  SiteCfgJson, AePerson, AeUser, AccessType, AuthLocState

ae_events_stores__badges_defaults.ts
  BadgesLocState, BadgesSessState

ae_events_stores__launcher_defaults.ts
  SectionState, LauncherLocState, LauncherSessState

ae_events_stores__leads_defaults.ts
  LeadsLocState, TmpLicense, LeadsSessState

ae_events_stores__pres_mgmt_defaults.ts
  PresMgmtLocState, PresMgmtSessState

All exported consts annotated with their interface type.
svelte-check: 0 errors, 0 warnings
2026-03-16 15:52:19 -04:00
Scott Idem
41ed6a8adc refactor(stores): Phase 2a — split store defaults into domain sub-files
ae_stores.ts
- Extract auth/identity section (~80 lines) into ae_stores__auth_loc_defaults.ts
- Spread auth_loc_defaults into ae_app_local_data_defaults (zero consumer changes)

ae_events_stores.ts (both loc and sess structs)
- badges   → ae_events_stores__badges_defaults.ts
- launcher → ae_events_stores__launcher_defaults.ts
- leads    → ae_events_stores__leads_defaults.ts
- pres_mgmt → ae_events_stores__pres_mgmt_defaults.ts

Each new file exports *_loc_defaults and *_sess_defaults. The store files
now reference these by name instead of embedding inline objects. All
$ae_loc.* and $events_loc.* consumer paths are unchanged.

svelte-check: 0 errors, 0 warnings
2026-03-16 15:42:21 -04:00
Scott Idem
f4020e7834 refactor(stores): phase 1 cleanup — ae_idaa_stores.ts
- Remove unused `import { offset } from '@floating-ui/dom'`
- Remove ver_idb constant and field (same as ae_stores / ae_events_stores)
- Remove commented-out personal Novi UUIDs (security hygiene — these belong
  in site_cfg_json on the server, not in source; idaa layout already reads
  them from $ae_loc.site_cfg_json and writes to idaa_loc at mount)
- Add comment explaining novi_admin/trusted/jitsi_mod_li are server-driven
- Remove dead writable/persisted alternatives and console.log lines
- Remove stale 'Updated 20xx-xx-xx' date comments
- Condense redundant tracking comments to single-line form
2026-03-16 15:23:22 -04:00
Scott Idem
65291aa5b9 refactor(stores): phase 1 cleanup — ae_stores.ts and ae_events_stores.ts
- Remove ~200 lines of dead commented-out code (old test blocks, stale
  import alternatives, unused console.log lines)
- Remove ver_idb fields — superseded by store_versions.ts __version mechanism
- Remove Stripe button IDs / publishable key from events_sess (no consumers)
- Remove stale event-specific comments (CHOW 2024 sponsor tiers, ISHLT note)
- Remove example: true test field from session leads struct
- Improve comments: ver stamp rationale, auth__kv expiry intent, api_*_kv
  shape doc, slct/events_slct tab-isolation rationale, level_guest_max_li
  fallback note, events_trig_kv purpose
- Keep all active business logic and exports unchanged; zero consumer impact
2026-03-16 14:50:53 -04:00
Scott Idem
6ca2314472 Badges: fix print page svelte-check error — extract print CSS to static file
Svelte 5 does not support <style> or conditional {#if} blocks wrapping
<style> tags inside <svelte:head>. The parser treats them as raw-text
elements and reports '<script> was left open' at EOF.

Fix:
- Print media CSS moved to static/ae-print-badge.css (plain static file,
  no framework magic needed — all selectors target global elements).
- svelte:head now uses a simple <link> to that file.
- $effect injects the @page size dynamically per template layout field,
  avoiding the Svelte 5 parser limitation for conditional style injection.
- Badge_template interface in db_events.ts: added cfg_json / data_json
  (standard Aether object fields that were missing from the type).
2026-03-16 13:50:28 -04:00
Scott Idem
a79be722ae feat: add require_auth prop to hosted file download button
- Defaults to true (authenticated_access required) — no change to existing consumers
- Launcher file buttons set require_auth=false to allow unauthenticated downloads
2026-03-16 11:00:45 -04:00
Scott Idem
45fbf35c6b fix(sys-bar): full dark mode fix — base text color, select/input global CSS, color-scheme 2026-03-16 10:40:04 -04:00