Commit Graph

1989 Commits

Author SHA1 Message Date
Scott Idem
d939f3190d feat(security): implement API-verified passcode auth with JWT session
Passcodes are no longer compared locally against cached localStorage data.
Entry now POSTs to /v3/action/auth/authenticate_passcode; on success the
returned JWT (with per-role TTL) is stored in $ae_loc.jwt. Page-load
expiry check in +layout.ts resets access_type to anonymous when the JWT
has expired, targeting only auth_type='passcode' JWTs.

- Debounce (600 ms) auto-fires the check after typing stops; Enter key
  fires immediately as a secondary trigger — preserving the original UX
- Inline spinner and error message added to the passcode input
- Silent fallback to local comparison on network error or unresolved
  site_id (ghost), so IDAA staff and Electron/Launcher contexts are safe
- USE_API_PASSCODE_AUTH = true (active); local fallback retained while
  production is observed; site_access_code_kv cleanup deferred

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 13:32:44 -04:00
Scott Idem
f603780e71 Fixing bug with random appended still 2026-06-18 09:32:46 -04:00
Scott Idem
7ef2b55af6 Fixing the permissions of things again. Yes. Some things are hidden by default for staff/trusted access differently than for admins/managers. Staff should use Edit Mode to see more details and edit things. 2026-06-18 09:19:30 -04:00
Scott Idem
2563307d71 fix(build): resolve store binding and linter warnings to harden build stability
- Removed invalid two-way bindings to read-only Dexie observables in the test page
- Fixed 'state_referenced_locally' warning in Field Editor by refactoring draft_value initialization
- Cleaned up empty else block in session list to resolve Vite build warning
- Verified successful production build and clean 'npm run check' output
2026-06-17 18:16:59 -04:00
Scott Idem
d06dcae94b feat(field-editor): modernize field editor with non-blocking modal and viewport clamping
- Completed rewrite of `element_ae_obj_field_editor.svelte` to Svelte 5 + Tailwind v4
- Set `display_modal = true`, `modal_blocking = false`, and `modal_placement = 'center'` as new defaults
- Implemented trigger-relative modal positioning with automatic viewport boundary clamping to prevent off-screen rendering
- Migrated all 12 call sites across core and events modules (Session, Presenter, Location, Exhibit, etc.)
- Removed legacy datetime-to-local manual conversion logic from views as the component now handles it natively
- Retired Skeleton-based legacy component
- Updated testing page and documentation to reflect the new standardized primitive
2026-06-17 18:01:08 -04:00
Scott Idem
ea413bbb9b style(core): enhance UI consistency, support dark mode, and reorder navigation
- Refactored core layout and dashboard to follow AE Firefly guidelines
- Added proper theme-aware backgrounds and transitioned to Skeleton v4 tokens
- Grouped navigation and cards by functional color (Teal: Infra, Indigo: Identity, Amber: Config)
- Reordered items to: Accounts, Sites, Users, People, Data Stores, Lookups, Addresses, Contacts
- Fixed color inconsistency for Activity Logs in dashboard vs navigation
- Enabled non-blocking modal mode for inline field editors in Data Stores table
2026-06-17 17:27:39 -04:00
Scott Idem
04205e4a63 feat(field-editor): add display_modal mode with placement, blocking toggle, and unsaved-changes guard
- New `display_modal` prop opens the edit panel as a native <dialog> anchored
  near the pencil trigger instead of shifting inline content
- `modal_placement` (center|above|below|left|right, default center) positions
  the dialog relative to the trigger via getBoundingClientRect + CSS transform
- `modal_blocking` (default true) toggles showModal() vs show(); non-modal
  mode adds a document pointerdown listener to close on outside click
- `cancel_edit()` now warns "Discard unsaved changes?" when draft differs from
  saved value (matches data store form behaviour); skips warning after a
  successful save
- Dialog background uses theme CSS vars directly (--color-surface-50/900) via
  :global CSS — Skeleton tonal presets are intentionally semi-transparent and
  rendered behind table content without explicit position:fixed + z-index
- Extracted edit panel to {#snippet edit_panel()} — shared by inline and
  dialog paths with no duplication
- data-stores table: all three inline field editors switched to display_modal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 17:21:17 -04:00
Scott Idem
313eca076d style(data-stores): add icon to Edit button; update style guidelines
- Edit button now has SquarePen icon + text per button UX standard
- Style guidelines: extract button icon+text rule into its own section 8
  (was buried in Accessibility); renumber Accessibility to section 9;
  add code examples and context table for the rule

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 16:24:42 -04:00
Scott Idem
f2b4b9802d feat(data-stores): inline field editing for code, name, type; hide preview column
Row is no longer a giant click target. Code, Name, and Type cells now use
AE_Field_Editor for inline editing (pencil in edit_mode). Edit button opens
the full modal for everything else. Preview column hidden (kept in markup).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 16:19:51 -04:00
Scott Idem
726338cb1f fix(data-stores): sort format, enabled filter, account name display
- order_by_li was sent as an array; backend expects plain object — fixes sort
- pass enabled/hidden directly to search_ae_obj (was defaulting to 'enabled'/'not_hidden')
- account column now shows code/short_name from Dexie cache via SvelteMap

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 16:15:34 -04:00
Scott Idem
a6abcd6603 feat(data-stores): auto-load on mount, default sort updated_on DESC, fix sort toggle
- $effect auto-searches once $ae_api is ready (no manual Search click needed)
- Default sort: updated_on DESC (most recently changed first)
- toggle_sort: remove searched guard — column headers always trigger search
- Remove stale "press Search to begin" empty state (no longer relevant)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 15:59:59 -04:00
Scott Idem
8110ddb84e fix(icons): replace deprecated Filter with Funnel (Lucide)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 15:55:50 -04:00
Scott Idem
c0c896d87b refactor(data-store): consolidate into one self-contained edit modal
element_data_store_form.svelte is now the single source of truth for
editing data stores — owns the modal, all form fields, change detection,
save/delete API calls, and IDB cache update.

- element_data_store.svelte: remove ~120 lines of duplicated form/handler
  code; now delegates to AE_DataStore_Form via bind:open + callbacks
- data_stores/+page.svelte: open_edit/open_new are now 2 lines each;
  remove all draft state, submit_status, handle_save/delete; fix label
  a11y (wrapping labels on all filter + bulk-rename inputs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 15:54:58 -04:00
Scott Idem
e321a2c4c5 fix(data-store-form): add change detection, fix button class, restore textarea height
- Add original_obj prop + has_changes bindable output to element_data_store_form
- Derive has_changes by comparing each draft field to original_obj; null = always dirty (new record)
- Wire bind:has_changes + original_obj={is_new ? null : editing_obj} in management page
- Fix Save button: preset-filled-primary → preset-filled-primary-500 (matches element_data_store)
- Disable Save when !has_changes; block modal outsideclose when changes are pending
- Restore textarea rows 10 → 15 to match element_data_store.svelte

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 15:30:42 -04:00
Scott Idem
ae3bc7e085 refactor(data-stores): extract shared element_data_store_form component
New element_data_store_form.svelte handles all form fields for creating/
editing a Data Store. Replaces the inline form in the management page modal.

Features vs old inline form:
- Help text on every label (type descriptions, constraint notes, etc.)
- Advanced section (collapsible, hidden by default): Enable, Hide, Priority,
  Sort, Group, Notes — each with hint text
- For ID: editable on new, read-only on edit (with explanation why)
- show_account_field / show_for_fields props for embedded widget use later
- html_edit_mode + show_advanced are internal state, reset via {#key} on parent

Management page: drops html_edit_mode state + Code/Eye/editor imports; uses
{#key editing_obj?.id ?? 'new'} to recreate the form on each record change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 15:08:37 -04:00
Scott Idem
1ab93fd501 feat(data-stores): sortable Code/Name/Updated columns
Click any column header to sort; click again to toggle ASC/DESC.
Sort re-runs the current search immediately if results are showing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:40:40 -04:00
Scott Idem
752504e173 feat(data-stores): bulk rename, wildcard hint, theme fixes
- Add Bulk Rename panel: code filter (% wildcard), find/replace text,
  preview table before apply, sequential PATCH with IDB cache update
- Fix Code filter label/placeholder to show % wildcard syntax
- Add note that API results are scoped to the active account (backend behavior)
- Replace bg-black/5 with bg-surface-500/10 for light/dark compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:11:19 -04:00
Scott Idem
34736c05a0 feat(core): add Data Stores management page at /core/data_stores
Full CRUD for all data_store records: search by code, account_id,
for_type, for_id; create/edit/delete via modal with type-aware content
editor (CodeMirror / TipTap / textarea). Wired into core nav and
dashboard. for_id shown read-only on edit (DB integer FK constraint).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 13:55:17 -04:00
Scott Idem
1269e2ed53 fix(presenter): guard name-sync warning on person_id + on_open person link
Two fixes in presenter_view:
1. Name-sync warning (given/family mismatch) was showing even when no
   Person was linked. Guard now checks person_id first.
2. Person link replaced the two-step Re-link button flow with on_open
   pattern (matches Session POC). Pencil+Re-link button removed; pencil
   icon opens the editor and loads the person list in one action.
   Admin-only re-link restriction preserved: non-admin staff with a
   linked person see a read-only link instead of the editor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 11:09:09 -04:00
Scott Idem
d23f9073c4 feat(pres_mgmt): automate Session POC loading and enhance field editor UX
- Updated Element_ae_obj_field_editor_new.svelte with on_open callback support.
- Improved Select field UX in the editor with an inline loading spinner when options are empty.
- Streamlined session_view.svelte by using on_open to trigger person record loading automatically.
- Removed redundant manual 'Select Person' button in favor of automated lazy-loading.
2026-06-16 18:14:14 -04:00
Scott Idem
39b23002d9 fix: resolve migration typos and revert location description to textarea 2026-06-16 17:43:21 -04:00
Scott Idem
41555cb717 feat: add CodeMirror support and enhance icons in AE Obj Field Editor (New)
- Integrated AE_Comp_Editor_CodeMirror as a supported field_type.
- Enhanced button UX with descriptive Lucide icons and title text (Eraser for Clear, etc.).
- Switched Location View description field to use the CodeMirror editor.
- Updated test playground to include a CodeMirror example.
2026-06-16 17:24:13 -04:00
Scott Idem
7e97928e05 feat: implement and rollout AE Obj Field Editor (New)
Rolls out the full rewrite of the generic inline field editor, standardizing on
Tailwind v4 + Flowbite styling and resolving several long-standing contract issues.

Component Improvements:
- Fully implemented datetime/date conversion (component now owns format normalization).
- Added type-safety via Svelte 5 generics (<script generics="T">).
- Added automatic select value coercion (prevents stuck optimistic state).
- Added support for 'email', 'url', and 'tel' field types.
- Rebuilt styling on Tailwind v4 utility classes, removing legacy Skeleton UI.
- Improved accessibility: added ARIA labels, Escape-to-cancel, and autofocus.
- Improved error handling with visible inline error messages.

Rollout/Migration:
- Migrated all 8 primary call sites (person_view, device_li, locations_li,
  location_view, presentation_li, leads_manage, presenter_view, session_view).
- Swapped manual datetime pre-conversion at call sites for internal handling.
- Updated the test playground to show legacy vs. new side-by-side.

This migration runs the new component in parallel with the old one (still present)
ensuring a safe transition.
2026-06-16 17:20:05 -04:00
Scott Idem
49e3fb18b2 Fixing things if there is no end datetime set. 2026-06-16 16:18:25 -04:00
Scott Idem
5321eb0d70 fix(pres_mgmt): enforce presenter agreement before file upload
presenter_is_authed only checked sign-in state, never .agree, so a
presenter could upload without ever agreeing whenever the admin's
"Require Presenter Agreement" setting was on.

Added presenter_agree_ok (trusted_access || !require__presenter_agree ||
auth__event_presenter_obj.agree) and presenter_can_upload
(presenter_is_authed && presenter_agree_ok) in
presenter/[presenter_id]/+page.svelte, swapped into every place the
upload UI / file-list permissions are gated in both the default and
manage_files alt views. The alt view's public_access identity bypass is
preserved but now also requires presenter_agree_ok.

Added an inline warning message in place of the upload section when
signed in but pending agreement, instead of it silently disappearing.

Marked done in TODO__Agents.md; all three open LCI Pres Mgmt restoration
items are now resolved (2 were already fixed and just needed verifying).

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 15:27:12 -04:00
Scott Idem
ba2558fbf7 feat(pres_mgmt): self-documenting Config page + split POC into its own section
Two things prompted by direct feedback after testing:

1. Every input on the Config page now has a title tooltip explaining what
   it actually controls, where, and any interaction with other settings
   (e.g. clarifying Hide Location affects both the session detail page AND
   the Location column in Session Search results — not obvious from the
   label alone).

2. Split "Session Field Visibility" into "Session Display" (just
   description/location/message) and a new dedicated "POC Settings"
   section. Previously hide__session_poc ("Hide POC", checked = remove)
   sat directly next to show__session_li_poc_field ("Show POC Column",
   checked = add) in the same flat list — same checked state meaning
   opposite things for adjacent fields, confusing even though each field's
   own hide__/show__ naming is internally consistent with the project
   convention. Hide POC is now rendered as a visually distinct master
   switch (bold, its own row) with the three dependent settings indented
   under a left border below it and auto-disabled (with reduced opacity)
   whenever Hide POC is checked, so the "no effect once hidden" dependency
   is visible in the UI, not just documented in a footnote.

No field semantics changed — same PressMgmtRemoteCfg, same sync function,
same save path. Pure presentation/documentation pass.

Logged the rationale in PROJECT__AE_Events_PressMgmt_Config_Cleanup.md.
svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 14:32:56 -04:00
Scott Idem
cbc94babe0 fix(pres_mgmt): Location column ignored admin's Hide Location setting
Same bug pattern as the earlier POC column fix. The Session Search
results table's Location column prop only ever read the local-only,
never-synced hide__session_li_location_field — never the admin-synced
hide__session_location (Config page > Session Field Visibility > Hide
Location). Column always showed regardless of that setting or
permission level.

Fixed in pres_mgmt/+page.svelte:
  hide__session_location || hide__session_li_location_field

The other two usages of this component already hardcode
hide__session_location={true} correctly (you're already on that
location's own page, showing its name again would be redundant).

Logged in PROJECT__AE_Events_PressMgmt_Config_Cleanup.md with a note to
audit other hide__* fields for the same gap if more reports come in.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 14:10:54 -04:00
Scott Idem
af2236eea4 fix(pres_mgmt): remove lock_config — sync is now fully unconditional
lock_config made roughly half of sync_config__event_pres_mgmt()'s fields
conditional: they only updated in a given browser if lock_config happened
to be true at the exact moment that browser last synced. A field's local
value therefore depended on the history of saves, not the current setting
— undebuggable from the UI, and easy to corrupt by toggling Lock Config
off even briefly during testing. This was the actual root cause of the
"POC column / Hide POC sometimes works" reports.

Checked the DB: every event, old and new, already had lock_config: true.
The "unlocked, per-browser preference" use case it was built for has
never actually been used in practice.

- Removed lock_config from PressMgmtRemoteCfg, PresMgmtLocState, the
  sync function (no more conditional block — every field syncs
  unconditionally now, same as labels/Require Agreements always did),
  and the Config page UI (no more System section)
- Old DB records with a lock_config key are simply ignored, same as any
  other removed key — no migration needed
- Moved the now-fully-orphaned ae_comp__event_settings_pres_mgmt_form.svelte
  to ~/tmp/agents_trash (zero imports anywhere; the settings page already
  links to the canonical Config page) — completes Step 5 from the
  cleanup doc
- Marked PROJECT__AE_Events_PressMgmt_Config_Cleanup.md complete — all
  Implementation Steps and known regressions resolved

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 13:56:27 -04:00
Scott Idem
e5c141e765 fix(pres_mgmt): config sync round 2 — save race, dead fields, launcher gate, version stamps
Four fixes found while tracing why Manager-saved Config page changes
(QR, POC column, etc.) weren't reliably reaching pres_mgmt_loc:

1. Config page save was a race, not deterministic. The save handler only
   called load_ae_obj_id__event() (SWR — returns stale Dexie cache
   immediately, refreshes in the background, not awaited) and assumed
   that "picked up the new config." It never called
   sync_config__event_pres_mgmt() itself. Now calls it directly with the
   just-saved draft, so the editing browser updates instantly with no
   race. Kept the load_ae_obj_id__event() call (default try_cache: true)
   for propagating to other browsers/tabs via Dexie — do not pass
   try_cache: false there, that skips the Dexie write entirely.

2. Removed the dead "Lock Config" Sync/Unlink toggle in the sign-in
   panel (e_app_access_type.svelte). It wrote to four fields
   ($ae_loc.lock_config/sync_local_config,
   pres_mgmt_loc.current.lock_config/sync_local_config) that are never
   read anywhere (confirmed via full-repo grep), and confusingly shared
   a name with the real, functional "Lock Config" checkbox on the Pres
   Mgmt Config page. Removed the button and the now-orphaned
   lock_config/sync_local_config fields from PresMgmtLocState.

3. show__launcher_link was never assigned by sync_config__event_pres_mgmt()
   — only its inverse hide__launcher_link was. The toggle button's
   `show__launcher_link || trusted_access` visibility gate (in 3 menu
   files) always collapsed to trusted-only, ignoring the admin's setting.
   Added the missing assignment.

4. AE_PRES_MGMT_LOC_VERSION was bumped to 2 this morning claiming it
   "forces a localStorage reset" — it didn't, because _check_and_wipe()
   was never wired up for ae_pres_mgmt_loc, and even if it had been, the
   store never wrote a __version field to compare. Fixed: the store's
   serializer now stamps __version, and store_versions.ts wires the
   check. Found and fixed the same bug already live in ae_leads_loc,
   except worse there — it was wiping leads users' local prefs on EVERY
   page load, not just once.

All logged in PROJECT__AE_Events_PressMgmt_Config_Cleanup.md.
svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 13:21:04 -04:00
Scott Idem
8eb9444edf fix(pres_mgmt): sync remote config on all deep-link entry pages
Root cause of the presenter QR not propagating to other browsers/incognito:
sync_config__event_pres_mgmt() was only called from pres_mgmt/+page.svelte
and session/[session_id]/+page.svelte. A browser landing directly on the
presenter page (e.g. via a presenter's sign-in link) never synced remote
config into pres_mgmt_loc.current at all — every always-synced and
lock-synced field (QR enables, POC visibility, code visibility, labels,
etc.) silently stayed at hardcoded local defaults regardless of what was
set on the Config page, since that page was never visited in that browser.

Added the same sync $effect (mirroring the existing pattern/comment already
in session/[session_id]/+page.svelte) to:
- presenter/[presenter_id]/+page.svelte
- locations/+page.svelte
- location/[event_location_id]/+page.svelte
- reports/+page.svelte

Logged in PROJECT__AE_Events_PressMgmt_Config_Cleanup.md with a note that
any future pres_mgmt entry page needs the same block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 12:29:43 -04:00
Scott Idem
a37866e5bb fix(pres_mgmt): presenter QR follows session QR global-default pattern
show__presenter_qr (admin) is meant to be the global default for everyone,
signed in or not. show_content__presenter_qr is a trusted-staff-only local
override for when the admin hasn't enabled it globally. Presenter QR was
still on the old logic requiring show_content__presenter_qr to also be
true even when the admin enabled it for everyone — non-trusted users
(presenters) have no way to set that flag, so QR never appeared for them.

- presenter_view.svelte: generation effect + display block now use
  show__presenter_qr || (trusted_access && show_content__presenter_qr),
  matching the session_view.svelte fix from earlier today
- presenter_page_menu.svelte: QR toggle was gated to administrator_access,
  hiding it from plain Trusted onsite staff; loosened to trusted_access
  and dropped the redundant `|| trusted_access` (now only shown when
  admin hasn't already enabled QR globally)
- ae_comp__events_menu_opts.svelte: both session and presenter QR toggles
  were visible to all authenticated_access users whenever admin had
  enabled QR globally, even though the toggle had no effect for them;
  now gated to trusted_access && !show__*_qr, matching session_page_menu.svelte
- Log the fix in PROJECT__AE_Events_PressMgmt_Config_Cleanup.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 12:14:24 -04:00
Scott Idem
2e4547f433 pres_mgmt: fix session QR never showing for POCs/presenters
The condition (show__session_qr || trusted_access) && show_content__session_qr
required the local per-browser toggle to also be true. Non-trusted users
(POCs, presenters) have no way to set it, so QR never appeared even when
admin had enabled it in Config.

New logic: show__session_qr alone is sufficient to generate and display the QR.
show_content__session_qr is now a staff-only override for when admin has NOT
enabled QR globally (allows trusted users to force it on per-browser).

Also: add QR Code toggle to session page Options modal (Display section),
visible to trusted staff only when admin has not already enabled it globally.
2026-06-16 12:02:03 -04:00
Scott Idem
7335721f6d pres_mgmt: fix QR code display not respecting remote show__session_qr / show__presenter_qr
Gate QR generation effect and display blocks on the remote admin enable flag:
- session_view: effect and display both check show__session_qr || trusted_access
- presenter_view: generation effect and await block check show__presenter_qr || trusted_access
Previously only the toggle buttons were gated; the actual QR content rendered
regardless of the remote config if show_content__*_qr was already true in localStorage
2026-06-16 11:49:15 -04:00
Scott Idem
2364c0edfb pres_mgmt: config schema cleanup phase 2
- Add show__session_qr + show__presenter_qr to PressMgmtRemoteCfg and sync function;
  QR toggles now gated on remote admin enable (trusted_access can still override)
- Remove hide__launcher_link_legacy everywhere (Flask launcher fully retired)
- Remove limit__options (YAGNI)
- Implement limit__navigation: hides Session Search nav link for non-trusted users
- Wire hide__report_kv into reports page: all 8 report tabs now use synced store
  with canonical slug names and edit_mode bypass; config UI now uses structured
  toggles instead of raw JSON textarea
- Gate hide__launcher_link local toggle on show__launcher_link || trusted_access
- Config UI: add show__session_qr + show__presenter_qr to opt-in features section
- Menu opts: add Query Limits / Display & Search / Staff Options section labels
- Bump AE_PRES_MGMT_LOC_VERSION to 2 (schema change forces localStorage reset)
- svelte-check: 0 errors
2026-06-16 11:39:47 -04:00
Scott Idem
a47a2103eb fix(pres_mgmt): make POC list/table column a real per-event config
show__session_li_poc_field was local-browser-only and the session list
prop computation ignored the admin's hide__session_poc master switch
entirely, so disabling POC for an event didn't hide the column if a
user's browser had it toggled on.

- Add show__session_li_poc_field to PressMgmtRemoteCfg + Config page UI
  (Session Field Visibility) + sync_config__event_pres_mgmt() lock-synced
  block, so it's admin-configurable per event like the other display flags
- Fix list/table column visibility to hide__session_poc || !show__session_li_poc_field
  in pres_mgmt/+page.svelte and locations/ae_comp__event_location_obj_li.svelte
- Remove the now-redundant local "Show/Hide POC Column" toggle buttons from
  ae_comp__events_menu_opts.svelte and event_page_menu.svelte
- Log the fix in PROJECT__AE_Events_PressMgmt_Config_Cleanup.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 10:18:10 -04:00
Scott Idem
0954369ef0 Time to wrap up. More style improvements. 2026-06-15 18:17:21 -04:00
Scott Idem
2f2e9d554a The copy link now looks better 2026-06-15 18:10:37 -04:00
Scott Idem
d193004882 More subtle style clean up 2026-06-15 18:05:14 -04:00
Scott Idem
8b1bf64740 Making things look nicer. AI is still not good at this. 2026-06-15 17:59:58 -04:00
Scott Idem
4c210e3e36 feat: email fallback and consistent auth checks across presenter components
ae_comp__event_presenter_obj_li.svelte:
- Email Access Link now shows for presenter.email when person_primary_email is
  null (same fallback logic as +page.svelte). Passes email as person_id when no
  Person record exists. Uses person_passcode ?? passcode.
- Visibility gate changed from administrator_access to trusted_access so staff
  signed in via any method can still send links (was blocking non-admin staff).
- Icon changed to class="mr-1" for consistency.

presenter_view.svelte:
- Email field <li>, passcode <li>, and biography textarea disabled now all check
  auth__kv.presenter[email] as a secondary key alongside auth__kv.presenter[id],
  matching the pattern established in presenter_page_menu.svelte. Presenters who
  signed in via email identity (no Person record) can now see and edit their own
  fields without needing a Person record link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:22:23 -04:00
Scott Idem
a784395d7b fix: consistent Lucide icons and auth checks on all Agreed buttons
session_view.svelte: replaced raw Unicode ✓/✗ in hardcoded color spans with
Check/X Lucide components (class="mr-1") matching the app icon pattern.

ae_comp__event_presenter_obj_li.svelte: same icon cleanup (removed bg-red-500,
px-1, text-green-500 etc). Also brought disabled conditions in line with
presenter_page_menu.svelte — now checks auth__kv.presenter by both
event_presenter_id and email, plus person_id match, so multi-session and
email-identity presenters can interact with their Agreed buttons from the list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:15:37 -04:00
Scott Idem
06f52bae34 fix: clean up Agreed/Not Agreed button icon classes
Icons now use class="mr-1" consistent with all other Lucide icons in the
codebase. Removed hardcoded text-green-500 on Check and bg-red-500/text-white
on X — the button's ae_btn_success_filled/ae_btn_warning_filled classes already
handle theming in both light and dark mode via Skeleton presets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:09:41 -04:00
Scott Idem
affbd0dc20 feat: use email as identity anchor for presenters without Person records
For events like LCI where ~75% of presenters are not in iMIS and have no Person
record, person_id on the presenter is null. Email (from the spreadsheet import)
is now the fallback identity throughout the sign-in flow:

- expand_auth_for_person: detects email via '@', routes Dexie and API lookups to
  presenter.email field instead of person_id. Keys auth__kv.presenter by BOTH
  event_presenter_id and email so any sibling presenter record with the same email
  auto-unlocks without per-ID lookups.
- Copy Access Link button: now visible for any presenter with person_id OR email.
  URL uses person_id ?? email and person_passcode ?? passcode as fallbacks.
- Email Access Link button: now visible for person_primary_email OR email. Sends
  to the best available address; passes email as person_id when no Person record.
- presenter_agree_enabled: checks auth__kv.presenter[email] as a second key so
  the Agreed button unlocks across all sessions for the same email identity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:02:29 -04:00
Scott Idem
28025df038 feat: auto-expand presenter auth to all roles at sign-in
When a presenter or session POC signs in via their access link, expand_auth_for_person
now queries both Dexie (warm cache) and the API in parallel so that cold-cache sessions
are covered. All presenter records and POC sessions for the same person_id in the event
are granted auth in one shot — a multi-session presenter no longer needs to click every
individual link.

Agreed button now also unlocks via person_id match (not only auth__kv.presenter[id]),
covering the case where a presenter signed in via a different session's link and wasn't
individually in auth__kv for this record yet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 16:51:22 -04:00
Scott Idem
01b1729a67 feat(pres_mgmt): auto-expand auth for all presenter/POC roles on sign-in
A person signing in via a single email link previously only got auth for
that one event_presenter_id or event_session_id. Presenters/POCs in
multiple sessions had to click a separate link per role.

On sign-in, expand_auth_for_person() queries Dexie for all presenter
records and POC sessions this person holds in the event and pre-populates
auth__kv.presenter, auth__kv.presentation, and auth__kv.session for all
of them. Runs as fire-and-forget — benign no-op on cold cache since
person_id matching in auth checks provides fallback coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 15:24:55 -04:00
Scott Idem
b90daa0a43 Cleaning things up... again. I will have to come back to this again later probably. 2026-06-15 15:13:09 -04:00
Scott Idem
37c8e20302 fix(pres_mgmt): remove auth gate from presenter email access link button
A signed-in POC/chair/moderator who has session auth was blocked from
seeing the Email Access Link button because presenter_is_authed includes
auth__kv.session[session_id]. POCs need to help presenters sign in
regardless of their own auth state.

show__email_access_link (staff-only feature toggle) is the correct gate.
No auth gate needed — same pattern as the session POC email button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:56:55 -04:00
Scott Idem
6ab4166da0 fix(pres_mgmt): decouple email access link buttons from require_agree flags
Presenter email button: removed dependency on require__presenter_agree,
fixed auth gate that blocked trusted staff (presenter_is_authed includes
trusted_access, so !presenter_is_authed always hid the button from staff).
New condition: show when email feature is on AND person has email AND
(staff OR presenter not yet authed).

Session POC email button: removed dependency on require__session_agree.
Staff need to send sign-in links regardless of whether an agreement form
is in use. Added confirm dialog and descriptive title attribute. Updated
copy-link btn_title for consistency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:43:41 -04:00
Scott Idem
04ae723309 fix(pres_mgmt): restore Add Person and Save Biography on presenter page
Three regressions in presenter_view.svelte:

- update_ae_obj__event_presenter calls for "Add Person" and "Save
  Biography" were missing event_presentation_id. The function falls
  back to events_slct.event_presentation_id which is never set on
  this page, so both calls returned null silently.

- "Add Person" confirm dialog showed null for the presenter's name
  because it referenced person_given_name (the linked person's field,
  which is null when no person is linked) instead of given_name (the
  presenter's own field).

Also: Re-link person list limit raised to 1000 (matching session POC
pattern) and added WHY comment explaining the admin-only re-link
restriction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:09:10 -04:00
Scott Idem
b6d162c66e Minor style changes 2026-06-15 13:23:58 -04:00