From 68075d37a15d73413da1dbb8c04f394ebd328bea Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Sun, 8 Feb 2026 21:28:16 -0500 Subject: [PATCH] Standardize on Licensed Exhibit Leads User (licensee) terminology - Renamed all staff-related fields and variables to 'licensee'. - Implemented correct filtering logic for Aether Admins (default All, hide My). - Implemented correct filtering for booth users (default My, show colleagues). - Populated dropdown labels with Full Names from license_li_json. - Removed 'Shared Passcode' from the Lead List filter. --- .../ae_events/ae_events__exhibit_tracking.ts | 12 ++++- src/lib/stores/ae_events_stores.ts | 1 + .../leads/exhibit/[exhibit_id]/+page.svelte | 33 +++++++++--- .../ae_comp__exhibit_tracking_search.svelte | 50 +++++++++++++++++++ .../ae_comp__lead_manual_search.svelte | 25 +++++----- .../ae_comp__lead_qr_scanner.svelte | 8 ++- 6 files changed, 106 insertions(+), 23 deletions(-) diff --git a/src/lib/ae_events/ae_events__exhibit_tracking.ts b/src/lib/ae_events/ae_events__exhibit_tracking.ts index 09380087..54d1d818 100644 --- a/src/lib/ae_events/ae_events__exhibit_tracking.ts +++ b/src/lib/ae_events/ae_events__exhibit_tracking.ts @@ -307,6 +307,7 @@ export async function create_ae_obj__exhibit_tracking({ exhibit_id, event_badge_id, external_person_id, + group, try_cache = true, log_lvl = 0 }: { @@ -314,6 +315,7 @@ export async function create_ae_obj__exhibit_tracking({ exhibit_id: string; event_badge_id: string; external_person_id: string; + group?: string; try_cache?: boolean; log_lvl?: number; }): Promise { @@ -323,7 +325,8 @@ export async function create_ae_obj__exhibit_tracking({ fields: { event_exhibit_id: exhibit_id, event_badge_id: event_badge_id, - external_person_id + external_person_id, + group }, log_lvl }); @@ -427,6 +430,8 @@ export async function search__exhibit_tracking({ event_id, event_exhibit_id, fulltext_search_qry_str = null, + qry_group = null, + qry_external_person_id = null, enabled = 'enabled', hidden = 'all', view = 'default', @@ -440,6 +445,8 @@ export async function search__exhibit_tracking({ event_id: string; event_exhibit_id: string; fulltext_search_qry_str?: string | null; + qry_group?: string | null; + qry_external_person_id?: string | null; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; @@ -461,6 +468,9 @@ export async function search__exhibit_tracking({ ] }; + if (qry_group) search_query.and.push({ field: 'group', op: 'eq', value: qry_group }); + if (qry_external_person_id) search_query.and.push({ field: 'external_person_id', op: 'eq', value: qry_external_person_id }); + if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 }); else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 }); diff --git a/src/lib/stores/ae_events_stores.ts b/src/lib/stores/ae_events_stores.ts index 91ecf58b..712703ec 100644 --- a/src/lib/stores/ae_events_stores.ts +++ b/src/lib/stores/ae_events_stores.ts @@ -231,6 +231,7 @@ const events_local_data_struct: key_val = { tracking__qry__remote_first: false, tracking__qry__search_text: '', tracking__qry__sort_order: 'created_desc', + tracking__qry__licensee_email: 'all', // The entered_passcode is the exhibit booths shared passcode for staff. This is used to initially access the lead retrieval service. entered_passcode: null, diff --git a/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/+page.svelte b/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/+page.svelte index 06f47720..f1b0c9f2 100644 --- a/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/+page.svelte +++ b/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/+page.svelte @@ -107,14 +107,24 @@ }); // Standardized Reactive Search Pattern - let search_params = $derived({ - v: $events_loc.leads.tracking__search_version, - str: ($events_loc.leads.tracking__qry__search_text ?? '') - .toLowerCase() - .trim(), - sort: $events_loc.leads.tracking__qry__sort_order, - exhibit_id: page.params.exhibit_id, - remote_first: $events_loc.leads.tracking__qry__remote_first + let search_params = $derived.by(() => { + let licensee_email = $events_loc.leads.tracking__qry__licensee_email; + + // Resolve "My Leads" to actual email + if (licensee_email === 'my') { + licensee_email = $events_loc.leads.auth_exhibit_kv?.[page.params.exhibit_id ?? '']?.key || 'all'; + } + + return { + v: $events_loc.leads.tracking__search_version, + str: ($events_loc.leads.tracking__qry__search_text ?? '') + .toLowerCase() + .trim(), + sort: $events_loc.leads.tracking__qry__sort_order, + licensee_email: licensee_email, + exhibit_id: page.params.exhibit_id, + remote_first: $events_loc.leads.tracking__qry__remote_first + }; }); $effect(() => { @@ -177,6 +187,12 @@ .where('event_exhibit_id') .equals(exhibit_id) .filter((tracking) => { + // 1. Licensee Email Filter + if (params.licensee_email !== 'all') { + if (tracking.external_person_id !== params.licensee_email) return false; + } + + // 2. Text Search Filter if (qry_str) { const name = ( tracking.event_badge_full_name ?? '' @@ -273,6 +289,7 @@ event_id: page.params.event_id || '', event_exhibit_id: exhibit_id, fulltext_search_qry_str: qry_str || null, + qry_external_person_id: params.licensee_email !== 'all' ? params.licensee_email : null, order_by_li, limit: 150 }); diff --git a/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__exhibit_tracking_search.svelte b/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__exhibit_tracking_search.svelte index 4b43c075..eb1b0710 100644 --- a/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__exhibit_tracking_search.svelte +++ b/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__exhibit_tracking_search.svelte @@ -14,8 +14,44 @@ LoaderCircle } from 'lucide-svelte'; + import { untrack } from 'svelte'; import { ae_loc } from '$lib/stores/ae_stores'; import { events_loc, events_sess } from '$lib/stores/ae_events_stores'; + import { liveQuery } from 'dexie'; + import { db_events } from '$lib/ae_events/db_events'; + import { onMount } from 'svelte'; + + let exhibit_obj: any = $state(null); + + onMount(() => { + const observable = liveQuery(() => db_events.exhibit.get(exhibit_id)); + const subscription = observable.subscribe((value) => { + exhibit_obj = value; + }); + return () => subscription.unsubscribe(); + }); + + // Reactive list derived from the exhibit state (Licensed Exhibit Leads Users) + let licensee_li = $derived.by(() => { + try { + const licenses = JSON.parse(exhibit_obj?.license_li_json || '[]'); + return Array.isArray(licenses) ? licenses : []; + } catch (e) { + return []; + } + }); + + // Default selection logic: Aether Admins go to "all", Licensees go to "my" + $effect(() => { + // Wait for object to load + if (!exhibit_obj) return; + + if ($events_loc.leads.tracking__qry__licensee_email === 'all' && !$ae_loc.administrator_access) { + untrack(() => { + $events_loc.leads.tracking__qry__licensee_email = 'my'; + }); + } + }); function handle_search_trigger() { if ($events_loc.leads.tracking__search_version === undefined) { @@ -71,6 +107,20 @@ + +
diff --git a/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_manual_search.svelte b/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_manual_search.svelte index 616385c0..66239994 100644 --- a/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_manual_search.svelte +++ b/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_manual_search.svelte @@ -5,6 +5,7 @@ */ import { page } from '$app/state'; import { ae_api } from '$lib/stores/ae_stores'; + import { events_loc } from '$lib/stores/ae_events_stores'; import { events_func } from '$lib/ae_events_functions'; import { Search, UserPlus, CheckCircle, LoaderCircle } from 'lucide-svelte'; import type { ae_EventBadge } from '$lib/types/ae_types'; @@ -44,19 +45,19 @@ if (!badge.event_badge_id_random) return; adding_id = badge.event_badge_id_random; - // TODO: Get the actual signed-in licensed user's email - const user_email = 'placeholder@exhibitor.com'; + // Use the actual signed-in licensed user's email (stored in auth_exhibit_kv) + const user_email = $events_loc.leads.auth_exhibit_kv?.[exhibit_id]?.key || 'shared_passcode'; - try { - const result = await events_func.create_ae_obj__exhibit_tracking({ - api_cfg: $ae_api, - exhibit_id: exhibit_id, - event_badge_id: badge.event_badge_id_random, - external_person_id: user_email - }); - - if (result && on_lead_added) { - on_lead_added(badge); + try { + const result = await events_func.create_ae_obj__exhibit_tracking({ + api_cfg: $ae_api, + exhibit_id: exhibit_id, + event_badge_id: badge.event_badge_id_random, + external_person_id: user_email, + group: user_email + }); + + if (result && on_lead_added) { on_lead_added(badge); } } catch (e) { console.error('Failed to add lead', e); diff --git a/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_qr_scanner.svelte b/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_qr_scanner.svelte index 8c83128a..e0f72040 100644 --- a/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_qr_scanner.svelte +++ b/src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_qr_scanner.svelte @@ -5,6 +5,7 @@ */ import { page } from '$app/state'; import { ae_api } from '$lib/stores/ae_stores'; + import { events_loc } from '$lib/stores/ae_events_stores'; import { events_func } from '$lib/ae_events_functions'; import Element_qr_scanner_v2 from '$lib/element_qr_scanner_v2.svelte'; import { ae_util } from '$lib/ae_utils/ae_utils'; @@ -51,14 +52,17 @@ if (!found_badge || !found_badge.event_badge_id_random) return; scanning_status = 'adding'; - const user_email = 'placeholder@exhibitor.com'; + + // Use the actual signed-in licensed user's email + const user_email = $events_loc.leads.auth_exhibit_kv?.[exhibit_id]?.key || 'shared_passcode'; try { const result = await events_func.create_ae_obj__exhibit_tracking({ api_cfg: $ae_api, exhibit_id: exhibit_id, event_badge_id: found_badge.event_badge_id_random, - external_person_id: user_email + external_person_id: user_email, + group: user_email }); if (result) {