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
This commit is contained in:
@@ -32,7 +32,7 @@ frontend pass the location directly in the Launcher URL without the extra lookup
|
||||
- [x] **Minor Svelte warning:** `slct_event_location_id` in `menu_location_list.svelte` — prop already has `$bindable(null)`; stale comment in file updated. (2026-03-11)
|
||||
|
||||
### [Svelte] State reference warnings
|
||||
- [x] **`state_referenced_locally` warnings resolved** — all 42 warnings fixed. v1 edit form retired; v2 renamed to canonical name. Remaining 23 warnings in `ae_idaa_comp__event_obj_id_edit.svelte` are CSS `@apply`/`@reference` warnings from the svelte-check CSS language service not understanding Tailwind v4 at-rules — harmless, build works fine, not fixable without a full `<style>` block refactor. (2026-03-11)
|
||||
- [x] **`svelte-check` fully clean — 0 errors, 0 warnings.** All 42 `state_referenced_locally` warnings fixed (2026-03-11). CSS `@apply`/`@reference` warnings in `ae_idaa_comp__event_obj_id_edit.svelte` also resolved — Tailwind utilities inlined, `<style>` block removed. (2026-03-16)
|
||||
|
||||
### [Badges] Remaining badge work before first live event
|
||||
- **Badge print controls UX polish:** Scott has improvements in mind — TBD next session.
|
||||
@@ -75,6 +75,10 @@ lead record look like in the DB?
|
||||
- **Input Field Audit:** Several input fields are missing `name`/`id` attributes or `data-testid`. Known examples: badge override fields in `ae_comp__badge_obj_view.svelte`; template name input in `ae_comp__badge_template_form.svelte`. Matters for: accessibility, autofill, label associations, and test targeting. (For tests, use `getByLabel()` rather than `input[value*=...]` which only checks the HTML attribute, not the Svelte-bound DOM property.)
|
||||
|
||||
## ✅ Completed (2026-03)
|
||||
- [x] **[UI]** Pres Mgmt Phase 3 — FA→Lucide icon migration across all 24 pres_mgmt files. (2026-03-16)
|
||||
- [x] **[IDAA]** `ae_idaa_comp__event_obj_id_edit.svelte` — inlined Tailwind utilities, removed `<style>` block; eliminated all 23 `@apply`/`@reference` svelte-check warnings. (2026-03-16)
|
||||
- [x] **[Badges]** Badge print page svelte-check fix: extracted print CSS to `static/ae-print-badge.css`; fixed unclosed `<script>` tag in `print/+page.svelte`. (2026-03-16)
|
||||
- [x] **[Svelte/Tests]** svelte-check cleanup: fixed `select_ref_badge_type` `$state()` declaration; two `<svelte:component>` deprecations in launcher components; `page.evaluate()` two-arg pattern in `badge_print_layout.test.ts`. (2026-03-16)
|
||||
- [x] **[Launcher]** Hosted file download button `require_auth` prop — added `require_auth?: boolean` (default `true`) to `ae_comp__hosted_files_download_button.svelte`; all existing consumers unchanged. Launcher `launcher_file_cont.svelte` passes `require_auth={false}` so unauthenticated kiosk users can open/download files without being blocked. (2026-03-16)
|
||||
- [x] **[Security]** `PUBLIC_AE_API_SECRET_KEY` audit complete. Key is `PUBLIC_*` by design (always in client bundle). Highest-risk anonymous path uses limited-permission `PUBLIC_AE_BOOTSTRAP_KEY`. Full server-side migration not justified given JWT + account_id auth layers. Current state acceptable. (2026-03-11)
|
||||
- [x] **[UX]** Session Expired banner — `ae_auth_error` store wired to API helpers; root layout sets `flag_expired` on 401/403; non-blocking dismissible banner rendered. (2026-03-12)
|
||||
|
||||
@@ -8,21 +8,20 @@ import type { Writable } from 'svelte/store';
|
||||
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
|
||||
// Set the version for the app data. Changing this should force a notification and ask the user to clear and reload the page.
|
||||
// Deployment version stamp. Compared against events_sess.ver in events/+layout.svelte
|
||||
// to detect stale persisted data after a deploy (triggers a reload). Bump this alongside
|
||||
// events_session_data_struct.ver. See store_versions.ts for the schema-level wipe mechanism.
|
||||
const ver = '2025-10-16_2139';
|
||||
const ver_idb = '2025-10-16_2139';
|
||||
|
||||
/* *** BEGIN *** Initialize events_local_data_struct */
|
||||
// Longer-term app data. This should be stored to *local* storage.
|
||||
// Updated 2024-03-06
|
||||
// Persisted to localStorage. Retains user preferences and event-specific config across
|
||||
// browser sessions. See store_versions.ts for the schema-level invalidation mechanism.
|
||||
const events_local_data_struct: key_val = {
|
||||
__version: AE_EVENTS_LOC_VERSION, // Schema version gate — see store_versions.ts
|
||||
ver: ver,
|
||||
ver_idb: ver_idb,
|
||||
ver: ver, // Deployment stamp — compared against events_sess.ver to trigger reloads.
|
||||
|
||||
// Shared
|
||||
name: 'Aether - Events (SvelteKit 2.x Svelte 4.x)',
|
||||
title: `OSIT's Æ Events`, // - Dev SvelteKit`, // Æ
|
||||
name: 'Aether - Events',
|
||||
title: `OSIT's Æ Events`,
|
||||
|
||||
ds: {},
|
||||
|
||||
@@ -44,41 +43,19 @@ const events_local_data_struct: key_val = {
|
||||
// The auth__entered_key (usually email or person_id) and auth__entered_passcode is found under events_sess.entered_key and events_sess.entered_passcode because it should be temporary.
|
||||
// auth__entered_passcode: null,
|
||||
|
||||
// The auth__kv (key value pairs) is used to store the xyz IDs that the browser client can access. This is a key value list of xyz ID and created datetime stamp (or just true). These should not be more than X days old.
|
||||
// auth__kv tracks which IDs the browser client is permitted to access.
|
||||
// Each entry is an ID mapped to true, false, 'read', or 'write'.
|
||||
// Keys should be no older than a configurable max age (checked on read).
|
||||
auth__kv: {
|
||||
event: {
|
||||
// 'LNDF-67-89-92': true
|
||||
},
|
||||
exhibit: {
|
||||
// 'LNDF-67-89-92': true
|
||||
},
|
||||
location: {
|
||||
// 'LNDF-67-89-92': true
|
||||
},
|
||||
session: {
|
||||
// 'LNDF-67-89-92': true, false, 'read', 'write'
|
||||
},
|
||||
presentation: {
|
||||
// 'LNDF-67-89-92': true
|
||||
},
|
||||
presenter: {
|
||||
// 'LNDF-67-89-92': true
|
||||
},
|
||||
person: {
|
||||
// 'LNDF-67-89-92': true
|
||||
}
|
||||
event: {},
|
||||
exhibit: {},
|
||||
location: {},
|
||||
session: {},
|
||||
presentation: {},
|
||||
presenter: {},
|
||||
person: {}
|
||||
},
|
||||
|
||||
// auth__session_kv: {
|
||||
// // {'LNDF-67-89-92': true}
|
||||
// },
|
||||
// auth__presentation_kv: {
|
||||
// // {'LNDF-67-89-92': true}
|
||||
// },
|
||||
// auth__presenter_kv: {
|
||||
// // {'LNDF-67-89-92': true}
|
||||
// },
|
||||
|
||||
// Badge Printing
|
||||
badges: {
|
||||
auto_view: true,
|
||||
@@ -91,8 +68,6 @@ const events_local_data_struct: key_val = {
|
||||
|
||||
show_element__cfg: true,
|
||||
show_element__cfg_detail: false,
|
||||
// 'theme_mode': 'dark',
|
||||
// 'theme_name': 'wintry',
|
||||
|
||||
fulltext_search_qry_str: null,
|
||||
search_badge_type_code: null,
|
||||
@@ -114,10 +89,6 @@ const events_local_data_struct: key_val = {
|
||||
classes__form: 'border border-surface-200 p-4 space-y-4 rounded-container'
|
||||
},
|
||||
|
||||
// Event Files - uploads for sessions, presenters, etc
|
||||
// 'files': {
|
||||
// },
|
||||
|
||||
// Event Presentation Launcher (and native Electron app)
|
||||
launcher: {
|
||||
// default - browser, onsite - browser onsite, native - Electron app onsite
|
||||
@@ -192,8 +163,6 @@ const events_local_data_struct: key_val = {
|
||||
},
|
||||
|
||||
native: {
|
||||
// 'local_file_cache_path': aether_cfg_data.app.local_file_cache_path,
|
||||
// 'host_file_temp_path': aether_cfg_data.app.host_file_temp_path,
|
||||
host_file_config_path: 'device_configs/ae_native_app_config.default.json'
|
||||
},
|
||||
|
||||
@@ -223,8 +192,8 @@ const events_local_data_struct: key_val = {
|
||||
show_content__email_link_warning: true,
|
||||
|
||||
default_to_scan: true,
|
||||
|
||||
// For ISHLT 2024 Annual Meeting only!
|
||||
// Fallback external registration ID used when building lead export data.
|
||||
// Should be overridden by the active event's external_event_id in cfg_json.
|
||||
default__external_registration_id: '2024_Annual Meeting',
|
||||
|
||||
auto_view: true, // Show the new lead after added by scan or search
|
||||
@@ -251,15 +220,11 @@ const events_local_data_struct: key_val = {
|
||||
// The entered_passcode is the exhibit booths shared passcode for staff. This is used to initially access the lead retrieval service.
|
||||
entered_passcode: null,
|
||||
|
||||
// The auth_exhibit_kv (key value pairs) is used to store the exhibit IDs that the browser client can access. This is a key value list of exhibit ID and created datetime stamp. These should not be more than X days old. The entered_passcode for events_sess.leads is what they are entering to log in.
|
||||
auth_exhibit_kv: {
|
||||
// {'LNDF-67-89-92': {key: 'example@oneskyit.com', updated_on: '2024-03-13T08:05:29Z}}
|
||||
},
|
||||
// auth_exhibit_kv: key-value of exhibit IDs this browser client
|
||||
// is authorized for, mapped to { key, updated_on }. Entries expire
|
||||
// after a configurable max age and must be re-authenticated.
|
||||
auth_exhibit_kv: {},
|
||||
|
||||
// The auth_exhibit_license_li is used to store the exhibit license(s) being used on the browser client. There can be multiple exhibit IDs, but only one license per exhibit ID for the browser client. This is used to determine who can actually access and use the lead retrieval service. This is a key value list of key (email address) and created datetime stamp. These should not be more than X days old.
|
||||
// auth_exhibit_license_li: {
|
||||
// // 'LNDF-67-89-92': { 'key': 'example@oneskyit.com', 'updated_on': '2024-03-13T08:05:29Z'}
|
||||
// },
|
||||
edit_license_li: false,
|
||||
|
||||
// The "tab" is a key value list of exhibit ID and tab name. This is intentionally using local storage to store the current tab for each exhibit.
|
||||
@@ -298,10 +263,7 @@ const events_local_data_struct: key_val = {
|
||||
require__presenter_agree: false,
|
||||
require__session_agree: false,
|
||||
|
||||
// show_content__agree_text: false,
|
||||
show_content__event_view: null,
|
||||
// show__launcher_link: false,
|
||||
// show__location_link: false,
|
||||
show_content__location_qr: false,
|
||||
show_content__presentation_description: false, // Note that this is for *all* presentations in the user interface. It is a global setting.
|
||||
show_content__presenter_page_help: true,
|
||||
@@ -348,10 +310,6 @@ const events_local_data_struct: key_val = {
|
||||
show_menu__event_reports: null,
|
||||
|
||||
show_report: null,
|
||||
// show_report__presenters_agree: false,
|
||||
// show_report__recent_files: false,
|
||||
|
||||
// time_format: 'time_12_short', // 'time_short', 'time_12_short'
|
||||
|
||||
disable_submit__opt_out: true,
|
||||
submit_status__opt_out: null,
|
||||
@@ -364,27 +322,15 @@ const events_local_data_struct: key_val = {
|
||||
}
|
||||
}
|
||||
|
||||
// Speakers Management (Collection)
|
||||
// 'speakers': {
|
||||
// },
|
||||
|
||||
// other
|
||||
};
|
||||
// console.log(`AE Stores - App Events Local Storage Data:`, events_local_data_struct);
|
||||
|
||||
// This works, but does not uses local storage:
|
||||
// export let ae_loc = writable(events_local_data_struct);
|
||||
|
||||
// This works and uses *local* storage:
|
||||
export const events_loc: Writable<key_val> = persisted('ae_events_loc', events_local_data_struct);
|
||||
// console.log(`AE Stores - App Local Storage Data:`, get(ae_loc));
|
||||
|
||||
/* *** BEGIN *** Initialize events_session_data_struct */
|
||||
// Temporary app data. This should be stored to session storage.
|
||||
// Updated 2024-03-06
|
||||
// In-memory only (writable, not persisted). Resets on page load.
|
||||
const events_session_data_struct: key_val = {
|
||||
// Deployment stamp — compared against events_loc.ver in events/+layout.svelte.
|
||||
ver: ver,
|
||||
ver_idb: ver_idb,
|
||||
log_lvl: 1,
|
||||
|
||||
// Shared
|
||||
@@ -477,8 +423,6 @@ const events_session_data_struct: key_val = {
|
||||
|
||||
// Lead Retrievals (Exhibit)
|
||||
leads: {
|
||||
example: true,
|
||||
|
||||
show_form__license: false,
|
||||
show_form__search: false,
|
||||
show_form__scan: false,
|
||||
@@ -496,7 +440,6 @@ const events_session_data_struct: key_val = {
|
||||
last_refresh_time: null as string | null,
|
||||
next_refresh_countdown: 0,
|
||||
|
||||
// The entered_passcode is the exhibit booths shared passcode for staff. This is used to initially access the lead retrieval service.
|
||||
entered_passcode: null,
|
||||
|
||||
tmp_license: {
|
||||
@@ -517,24 +460,6 @@ const events_session_data_struct: key_val = {
|
||||
qr_scan_result: null
|
||||
},
|
||||
|
||||
stripe: {
|
||||
license_qty: 1,
|
||||
rental_qty: 0,
|
||||
rental_option: true,
|
||||
api_use: false,
|
||||
client_reference_id: null,
|
||||
publishable_key: 'pk_live_zqaWNDfak2eDHeqnRiyaJcFi',
|
||||
btn_payment_id: null,
|
||||
btn_1_license: 'buy_btn_1OvqWJ2gJkNsDuiNqMCWz5nG',
|
||||
btn_1_license_rental: 'buy_btn_1OvqVA2gJkNsDuiNhk9r8Io2',
|
||||
btn_3_license: 'buy_btn_1OvrI22gJkNsDuiNXjBg3c4Y',
|
||||
btn_3_license_rental: 'buy_btn_1OvrKa2gJkNsDuiNhSBCkNau',
|
||||
btn_6_license: 'buy_btn_1OvrWc2gJkNsDuiN7mnwvZNL',
|
||||
btn_6_license_rental: 'buy_btn_1OvrXP2gJkNsDuiNZpWZs3Uy',
|
||||
btn_10_license: 'buy_btn_1OvrPM2gJkNsDuiNRCMHfSuz',
|
||||
btn_10_license_rental: 'buy_btn_1OvrPs2gJkNsDuiN1nPkjPOM'
|
||||
},
|
||||
|
||||
// Presentation Management
|
||||
pres_mgmt: {
|
||||
// link: {
|
||||
@@ -616,11 +541,10 @@ const events_session_data_struct: key_val = {
|
||||
|
||||
// other
|
||||
};
|
||||
// console.log(`AE Stores - App Events Session Storage Data:`, events_session_data_struct);
|
||||
export const events_sess = writable(events_session_data_struct);
|
||||
|
||||
/* *** BEGIN *** Initialize events_slct and events_trigger */
|
||||
/* The slct and slct_trigger variable should not be stored in local storage. Only use session storage because browser tabs can be open to different events, badges, exhibits, etc. */
|
||||
// In-memory only — tabs can have different event/session/presenter selections.
|
||||
|
||||
// Intended for temporary session storage.
|
||||
// Updated 2024-03-06
|
||||
@@ -692,20 +616,14 @@ const events_slct_obj_template: key_val = {
|
||||
auth__event_presenter_id: null,
|
||||
auth__event_presentation_id: null
|
||||
};
|
||||
// console.log(`AE Stores - Selected Events Objects:`, events_slct_obj_template);
|
||||
|
||||
// This works, and uses *session* (not local) storage:
|
||||
// In-memory only (not persisted) — separate tabs can select different events/sessions/presenters.
|
||||
export const events_slct = writable(events_slct_obj_template);
|
||||
|
||||
// This works and uses *local* storage:
|
||||
// export let events_slct: Writable<key_val> = persisted('ae_events_slct', events_slct_obj_template);
|
||||
|
||||
/* *** BEGIN *** Initialize events_trigger */
|
||||
// Intended for temporary session storage.
|
||||
// Updated 2024-03-06
|
||||
// Broadcast trigger — increment or set truthy to signal subscribers to re-query.
|
||||
export const events_trigger: any = writable(null);
|
||||
// console.log(`AE Events Stores - Events Trigger:`, events_trigger);
|
||||
|
||||
// events_trig: fine-grained triggers per object type.
|
||||
// Set an ID to signal that specific object needs to be re-fetched.
|
||||
const tmp__events_trig: key_val = {
|
||||
event_id: null,
|
||||
event_id_li: [],
|
||||
@@ -721,22 +639,7 @@ const tmp__events_trig: key_val = {
|
||||
// console.log(`AE Stores - Events Trigger:`, events_trig);
|
||||
export const events_trig: Writable<key_val> = writable(tmp__events_trig);
|
||||
|
||||
/* *** BEGIN *** TESTING Initialize trig_resp */
|
||||
// The idea behind this is for a shared (Svelte app (within Events for now)) trigger and response. In theory this could be used to monitor multiple downloads or have a universal status area. Intended for temporary session storage.
|
||||
// Updated 2024-06-25
|
||||
// events_trig_kv: response/status map — keys are request IDs, values are
|
||||
// completion status or Promise results. Used for tracking parallel downloads.
|
||||
const tmp__events_trig_kv: key_val = {};
|
||||
// {
|
||||
// 'example-1':
|
||||
// {
|
||||
// 'a-rand-id-1': true,
|
||||
// 'a-rand-id-2': false,
|
||||
// 'a-rand-id-3': Promise.resolve('This is a test promise.'),
|
||||
// },
|
||||
// 'example-2':
|
||||
// {
|
||||
// 'a-rand-id-4': true,
|
||||
// 'a-rand-id-5': false,
|
||||
// 'a-rand-id-6': Promise.resolve('This is a test promise.'),
|
||||
// },
|
||||
// };
|
||||
export const events_trig_kv = writable(tmp__events_trig_kv);
|
||||
@@ -36,69 +36,49 @@ const ae_no_account_id_token = PUBLIC_AE_NO_ACCOUNT_ID_TOKEN;
|
||||
const ae_event_id = PUBLIC_AE_EVENT_ID;
|
||||
const ae_sponsorship_cfg_id = PUBLIC_AE_SPONSORSHIP_CFG_ID;
|
||||
|
||||
// import { getStores, navigating, page, updated } from '$app/stores';
|
||||
// import { assets, base, resolveRoute } from '$app/paths';
|
||||
// console.log(page.path); // Everything after the domain name
|
||||
|
||||
// console.log(import.meta.env.MODE);
|
||||
// console.log(import.meta.env.BASE_URL);
|
||||
|
||||
// Export the key_val type for use in other files.
|
||||
// Loose bag-of-anything type used throughout the store. Once stores are broken into
|
||||
// typed domain files, individual structs will have proper interfaces instead.
|
||||
export type key_val = {
|
||||
[key: string]: any; // variable key
|
||||
// name: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
// export type key_val = key_val;
|
||||
|
||||
// import { html__not_set, classes__events_pres_mgmt_menu } from './ae_string_snippets';
|
||||
import { string_snippets } from '$lib/utils/ae_string_snippets';
|
||||
export const ae_snip = string_snippets;
|
||||
|
||||
// export let ae_snip =
|
||||
// {
|
||||
// 'not_set': html__not_set,
|
||||
// 'classes__events_pres_mgmt_menu': classes__events_pres_mgmt_menu
|
||||
// };
|
||||
|
||||
// Set the version for the app data. Changing this should force a notification and ask the user to clear and reload the page.
|
||||
const ver = '2025-05-01_1445'; // KEEP: 2025-05-01_1445
|
||||
const ver_idb = '2025-05-01_1445'; // Not currently used
|
||||
// Deployment version stamp. Compared against ae_sess.ver in +layout.svelte to detect
|
||||
// stale persisted data after a deploy (triggers a reload). Bump this alongside
|
||||
// ae_app_session_data_defaults.ver whenever a deploy changes expected stored shape.
|
||||
// See store_versions.ts for the schema-level localStorage wipe mechanism (separate concern).
|
||||
const ver = '2025-05-01_1445';
|
||||
|
||||
// *** BEGIN *** Longer-term app data. This should be stored to local storage.
|
||||
const ae_app_local_data_defaults: key_val = {
|
||||
__version: AE_LOC_VERSION, // Schema version gate — see store_versions.ts
|
||||
last_page_reload: null,
|
||||
// last_idb_reload: null,
|
||||
// last_cache_refresh: null, // Date.now()
|
||||
last_cache_refresh: Date.now(),
|
||||
cache_expired: false,
|
||||
ver: ver, // ver, // '2025-04-18_1100',
|
||||
ver_idb: ver_idb, // '2025-04-18_1100',
|
||||
// Deployment stamp — compared against ae_sess.ver in +layout.svelte to trigger
|
||||
// a reload when the persisted local data predates the current deploy.
|
||||
ver: ver,
|
||||
|
||||
name: 'Aether - App Hub (SvelteKit 2.x Svelte 4.x)',
|
||||
name: 'Aether - App Hub',
|
||||
|
||||
theme: 'light',
|
||||
theme_mode: 'light',
|
||||
theme_name: 'AE_Firefly', // "Shiny serenity, like a firefly." — OSIT default 2026
|
||||
theme_name: 'AE_Firefly', // OSIT default theme
|
||||
font_size_mode: 'default', // 'default' | 'larger' | 'smaller'
|
||||
iframe: false,
|
||||
|
||||
// disable_sys_header: false,
|
||||
// disable_sys_nav: false,
|
||||
// disable_sys_footer: false,
|
||||
browser_type: null, // Safari needs special handling for scrolling in iframes.
|
||||
|
||||
browser_type: null, // Safari needs help with scrolling correctly in iframes.
|
||||
title: `OSIT's Æ`,
|
||||
|
||||
title: `OSIT's Æ`, // - Dev SvelteKit`, // Æ
|
||||
debug_mode: false,
|
||||
edit_mode: false,
|
||||
adv_mode: false,
|
||||
sync_local_config: true, // When true, pulls site config from the remote API on load.
|
||||
|
||||
// debug_menu: false, // Flag show debug menu.
|
||||
debug_mode: false, // Flag to know if we should be in debug mode and show show debug options.
|
||||
edit_mode: false, // Flag to know if we should be in edit mode and show edit options.
|
||||
adv_mode: false, // Flag to know if we should be in advanced mode and show advanced options.
|
||||
// sys_menu: true, // Flag show system menu.
|
||||
sync_local_config: true, // Flag to know if we should sync local config with the remote API server.
|
||||
|
||||
account_id: ae_account_id, // OSIT Demo _XY7DXtc9MY
|
||||
account_id: ae_account_id,
|
||||
account_code: 'not_set',
|
||||
account_name: 'Account Name Not Set',
|
||||
allow_access: true, // Set to key site key was used, otherwise set to true.
|
||||
@@ -112,18 +92,14 @@ const ae_app_local_data_defaults: key_val = {
|
||||
header_image_path: null
|
||||
},
|
||||
|
||||
// The site access codes can be pulled from the site records for an account.
|
||||
// Per-permission-level passcodes loaded from the site record on login.
|
||||
// null = no passcode required for that tier. Overwritten by the site API response.
|
||||
site_access_code_kv: {
|
||||
// 'manager': '10240',
|
||||
administrator: null,
|
||||
trusted: null,
|
||||
public: 'public1980',
|
||||
authenticated: 'auth1980'
|
||||
},
|
||||
// 'manager_passcode': '10240',
|
||||
// 'administrator_passcode': '11500',
|
||||
// 'trusted_passcode': '19111',
|
||||
// 'authenticated_passcode': 'auth2024',
|
||||
|
||||
access_type: 'anonymous',
|
||||
administrator_access: false,
|
||||
@@ -132,49 +108,40 @@ const ae_app_local_data_defaults: key_val = {
|
||||
authenticated_access: false,
|
||||
anonymous_access: true,
|
||||
|
||||
user_email: null, // Currently used with Sponsorships only?
|
||||
user_access_type: null, // Used to revert back to the user's access type after quick access (temporarily escalate permissions) turned off.
|
||||
user_email: null,
|
||||
// Stored on sign-in so the original permission level can be restored if temporarily escalated.
|
||||
user_access_type: null,
|
||||
|
||||
jwt: null, // JSON Web Token for authenticated API requests
|
||||
jwt: null, // JSON Web Token for authenticated API requests.
|
||||
|
||||
// Added 2025-04-04
|
||||
person_id: null, // The current person_id of the logged-in user (if any)
|
||||
person_id: null,
|
||||
person: {
|
||||
// WARNING: We need to add some logic on sign in to only include needed fields. 2025-08-12
|
||||
id: null, // The current person_id of the logged-in user
|
||||
// profile_id: null, // The current person_profile_id of the logged-in user
|
||||
// pronouns: null,
|
||||
// informal_name: null,
|
||||
id: null,
|
||||
given_name: null,
|
||||
// family_name: null,
|
||||
// professional_title: null,
|
||||
full_name: null, // convenience
|
||||
full_name_override: null, // was called display_name
|
||||
|
||||
// affiliations: null,
|
||||
primary_email: null, // The primary email of the logged-in person/user
|
||||
user_id: null, // The user ID of the logged-in user
|
||||
full_name: null,
|
||||
full_name_override: null, // Previously called display_name.
|
||||
primary_email: null,
|
||||
user_id: null,
|
||||
|
||||
qry_limit__people: 150,
|
||||
|
||||
show_content__person_page_help: false
|
||||
},
|
||||
|
||||
// Added 2025-04-04
|
||||
user_id: null, // The current user_id of the logged-in user (if any)
|
||||
user_id: null,
|
||||
user: {
|
||||
id: null, // The current user_id of the logged-in user
|
||||
id: null,
|
||||
username: null,
|
||||
name: null,
|
||||
email: null, // The email of the logged-in user
|
||||
allow_auth_key: null, // For sign in without password
|
||||
super: false, // Is the user a super user
|
||||
manager: false, // Is the user a global manager (can manage accounts and users)
|
||||
administrator: false, // Is the user an account administrator
|
||||
verified: false, // Is the user verified
|
||||
public: false, // Is the user a public user (can view public content)
|
||||
person_id: null, // The person ID of the logged-in user
|
||||
access_type: null, // The access type of the logged-in user
|
||||
email: null,
|
||||
allow_auth_key: null, // Magic-link token — allows sign-in without password.
|
||||
super: false,
|
||||
manager: false, // Can manage accounts and users globally.
|
||||
administrator: false, // Account-level administrator.
|
||||
verified: false,
|
||||
public: false,
|
||||
person_id: null,
|
||||
access_type: null,
|
||||
|
||||
qry_limit__users: 100
|
||||
},
|
||||
@@ -208,7 +175,6 @@ const ae_app_local_data_defaults: key_val = {
|
||||
debug_menu: {
|
||||
hide: false,
|
||||
expand: false
|
||||
// hide_quick_info: true
|
||||
},
|
||||
|
||||
app_cfg: {
|
||||
@@ -259,18 +225,10 @@ const ae_app_local_data_defaults: key_val = {
|
||||
show_list__event_presenter_obj_li: true,
|
||||
show_view__event_presenter_obj: false,
|
||||
|
||||
submit_status: null, // 'saving', 'created', 'updated'
|
||||
submit_status: null,
|
||||
|
||||
// Badge Printing
|
||||
|
||||
// Lead Retrievals
|
||||
|
||||
// Presentation Management
|
||||
|
||||
// Speakers Management
|
||||
default_session_id: null // Assign to presenters by default
|
||||
|
||||
// other
|
||||
// When set, new presenters are automatically assigned to this session.
|
||||
default_session_id: null
|
||||
},
|
||||
|
||||
journals: {},
|
||||
@@ -283,15 +241,17 @@ const ae_app_local_data_defaults: key_val = {
|
||||
for_type: null,
|
||||
for_id: null,
|
||||
|
||||
// Max complimentary guests per sponsorship tier (0 = no tier).
|
||||
// These are fallback defaults; the active event config should override via events_cfg_json.
|
||||
level_guest_max_li: {
|
||||
0: 0,
|
||||
1: 4, // CHOW 2024 - Friend
|
||||
2: 8, // CHOW 2024 - Supporter
|
||||
3: 8, // CHOW 2024 - Advocate
|
||||
4: 8, // CHOW 2024 - Champion
|
||||
5: 8, // CHOW 2024 - Presenting Partner
|
||||
6: 16, // CHOW 2024 - Signature Partner
|
||||
7: 16 // CHOW 2024 - Premier Partner
|
||||
1: 4,
|
||||
2: 8,
|
||||
3: 8,
|
||||
4: 8,
|
||||
5: 8,
|
||||
6: 16,
|
||||
7: 16
|
||||
},
|
||||
|
||||
show_edit__sponsorship_obj: false,
|
||||
@@ -305,57 +265,15 @@ const ae_app_local_data_defaults: key_val = {
|
||||
|
||||
// testing: {},
|
||||
}
|
||||
|
||||
// testing: true,
|
||||
// ver_testing: true,
|
||||
};
|
||||
|
||||
// let ae_app_local_data_struct: key_val = {
|
||||
// ...ae_app_local_data_defaults,
|
||||
// };
|
||||
// // {
|
||||
// // // ...ae_app_local_data_defaults,
|
||||
// // };
|
||||
// // console.log(`AE Stores - App Local Storage Data:`, ae_app_local_data_struct);
|
||||
// if (!ae_app_local_data_defaults?.ver_testing) {
|
||||
// console.log(`TEST: AE Stores - ver_testing missing:`, ae_app_local_data_defaults);
|
||||
// // ae_app_local_data_struct = {
|
||||
// // ...ae_app_local_data_defaults,
|
||||
// // ...ae_app_local_data_struct,
|
||||
// // };
|
||||
// } else {
|
||||
// console.log(`TEST: AE Stores - ver_testing found`);
|
||||
// }
|
||||
// if (ae_app_local_data_struct?.ver !== ae_app_local_data_defaults?.ver) {
|
||||
// console.log(`TEST: AE Stores - ver not match:`, ae_app_local_data_struct);
|
||||
|
||||
// ae_app_local_data_struct = {
|
||||
// ...ae_app_local_data_defaults,
|
||||
// };
|
||||
// } else {
|
||||
// console.log(`TEST: AE Stores - ver match: ${ae_app_local_data_struct.ver} === ${ae_app_local_data_defaults.ver}`);
|
||||
// }
|
||||
// if (!ae_app_local_data_struct?.app_cfg) {
|
||||
// console.log(`TEST: AE Stores - app_cfg missing:`, ae_app_local_data_struct);
|
||||
|
||||
// ae_app_local_data_struct = {
|
||||
// ...ae_app_local_data_defaults,
|
||||
// ...ae_app_local_data_struct,
|
||||
// };
|
||||
// }
|
||||
|
||||
// This works, but does not uses local storage:
|
||||
// export let ae_loc = writable(ae_app_local_data_struct);
|
||||
|
||||
// This works and uses local storage:
|
||||
export const ae_loc: Writable<key_val> = persisted('ae_loc', ae_app_local_data_defaults);
|
||||
// console.log(`AE Stores - App Local Storage Data:`, get(ae_loc));
|
||||
|
||||
// *** BEGIN *** Temporary app data. This should be stored to session storage.
|
||||
const ae_app_session_data_defaults: key_val = {
|
||||
// ver: '2025-04-18_1335', // ver, // '2025-04-18_1100',
|
||||
// Deployment stamp — compared against ae_loc.ver in +layout.svelte.
|
||||
// When these differ, the app reloads to flush stale persisted data.
|
||||
ver: ver,
|
||||
ver_idb: ver_idb,
|
||||
log_lvl: 0,
|
||||
|
||||
disable_sys_header: false,
|
||||
@@ -391,9 +309,8 @@ const ae_app_session_data_defaults: key_val = {
|
||||
video_clip_file_kv: {},
|
||||
processed_file_list: [],
|
||||
status__file_list: null,
|
||||
// uploaded_file_list: [],
|
||||
video_clip_file_list: [],
|
||||
submit_status: null, // 'saving', 'created', 'updated', 'saved'
|
||||
submit_status: null,
|
||||
clip_complete: null
|
||||
},
|
||||
|
||||
@@ -410,13 +327,7 @@ const ae_app_session_data_defaults: key_val = {
|
||||
},
|
||||
mod: {
|
||||
archives: {},
|
||||
events: {
|
||||
// Badge Printing
|
||||
// Lead Retrievals
|
||||
// Presentation Management
|
||||
// Speakers Management
|
||||
// other
|
||||
},
|
||||
events: {},
|
||||
journals: {},
|
||||
posts: {},
|
||||
sponsorships: {
|
||||
@@ -437,25 +348,23 @@ const ae_app_session_data_defaults: key_val = {
|
||||
show__modal_change_password: false,
|
||||
|
||||
download: {},
|
||||
// For API download and upload progress status per file.
|
||||
// Per-file progress keyed by file_id (downloads) or temp_id (uploads).
|
||||
// Shape: { status, endpoint, filename, size_total, size_loaded, percent_completed }
|
||||
api_download_kv: {},
|
||||
// Example: {example_file_id: {status: 'downloading', endpoint: '/event/file/abc123/download', filename: 'example_file_name.ext', size_total: 0, size_loaded: 0, percent_completed: 0}}
|
||||
api_upload_kv: {}, // {example_temp_id: {status: 'uploading', endpoint: '/event/file/abc123/upload', filename: 'example_file_name.ext', size_total: 0, size_loaded: 0, percent_completed: 0}}
|
||||
api_upload_kv: {},
|
||||
|
||||
test: true
|
||||
};
|
||||
// console.log(`AE Stores - App Session Storage Data:`, ae_app_session_data_defaults);
|
||||
export const ae_sess = writable(ae_app_session_data_defaults);
|
||||
|
||||
// *** BEGIN *** Temporary API data. This should be stored to session storage.
|
||||
export const ae_api_data_struct: key_val = {
|
||||
ver: '2024-08-11_11',
|
||||
fqdn: api_server_fqdn,
|
||||
base_url: api_base_url,
|
||||
base_url_bak: api_base_url_bak,
|
||||
api_secret_key: api_secret_key, // 'YOUR_API_SECRET_KEY',
|
||||
api_secret_key_bak: api_secret_key, // 'YOUR_API_SECRET_KEY',
|
||||
api_crud_super_key: api_crud_super_key, // 'YOUR_SUPER_KEY' 'zp5PtX4zUsI'
|
||||
api_secret_key: api_secret_key,
|
||||
api_secret_key_bak: api_secret_key,
|
||||
api_crud_super_key: api_crud_super_key, // Used for operations that bypass normal account-scoped CRUD limits.
|
||||
headers: {},
|
||||
account_id: ae_account_id
|
||||
};
|
||||
@@ -465,18 +374,15 @@ ae_api_headers['Content-Type'] = 'application/json';
|
||||
ae_api_headers['x-aether-api-key'] = ae_api_data_struct.api_secret_key;
|
||||
if (ae_account_id) {
|
||||
ae_api_headers['x-account-id'] = ae_account_id;
|
||||
} else {
|
||||
// ae_api_headers['x-account-id'] = ;
|
||||
}
|
||||
if (ae_no_account_id) {
|
||||
ae_api_headers['x-no-account-id'] = ae_no_account_id;
|
||||
}
|
||||
ae_api_data_struct['headers'] = ae_api_headers;
|
||||
|
||||
// console.log(`AE Stores - API Data:`, ae_api_data_struct);
|
||||
export const ae_api = writable(ae_api_data_struct);
|
||||
|
||||
// *** BEGIN *** Trigger to update the slct variables and other things.
|
||||
// General-purpose reactive trigger. Set any truthy value to signal consumers to re-query.
|
||||
const ae_trig_template: key_val = {};
|
||||
export const ae_trig = writable(ae_trig_template);
|
||||
|
||||
@@ -491,9 +397,6 @@ const slct_obj_template: key_val = {
|
||||
event_id: null,
|
||||
event_obj: {},
|
||||
event_obj_li: [],
|
||||
// 'event_exhibit_id': null,
|
||||
// 'event_exhibit_obj': {},
|
||||
// 'event_exhibit_obj_li': [],
|
||||
event_presentation_id: null,
|
||||
event_presentation_obj: {},
|
||||
event_presentation_obj_li: [],
|
||||
@@ -516,26 +419,18 @@ const slct_obj_template: key_val = {
|
||||
post_comment_obj: {},
|
||||
post_comment_obj_li: []
|
||||
};
|
||||
// console.log(`AE Stores - Selected Objects:`, slct_obj_template);
|
||||
|
||||
// This works, and uses *session* (not local) storage:
|
||||
// In-memory only (not persisted) — separate browser tabs can have different selections.
|
||||
export const slct = writable(slct_obj_template);
|
||||
|
||||
// This works and uses *local* storage:
|
||||
// export let slct: Writable<key_val> = persisted('ae_slct', slct_obj_template);
|
||||
|
||||
/* *** BEGIN *** Initialize slct_trigger */
|
||||
// Intended for temporary session storage.
|
||||
// Updated 2024-02-27
|
||||
// Increment (or set any truthy value) to tell subscribers that the selection changed
|
||||
// and they should re-query their data.
|
||||
export const slct_trigger: any = writable(null);
|
||||
// console.log(`AE Stores - Selected Trigger:`, slct_trigger);
|
||||
|
||||
// Auth error signal — set by API helpers on 401/403 to trigger the session-expired banner in the root layout.
|
||||
// Only set from browser context (never SSR). 'expired' covers both 401 and 403 responses.
|
||||
export const ae_auth_error = writable<{ type: 'expired' | null; ts: number | null }>({ type: null, ts: null });
|
||||
|
||||
/* *** BEGIN *** Create time variable */
|
||||
// Updated 2020
|
||||
// Reactive clock — updates every second. Used for live countdown and elapsed-time displays.
|
||||
export const time = readable(new Date(), function start(set) {
|
||||
const interval = setInterval(() => {
|
||||
set(new Date());
|
||||
|
||||
Reference in New Issue
Block a user