From b3c04464402b1cbd8776b518b94c378ceae6adf6 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Wed, 19 Nov 2025 18:52:59 -0500 Subject: [PATCH] fix(badges): Resolve badge search API error and UI bugs This commit addresses several critical issues preventing the new v3 badge search page from functioning correctly. - **Fixes API Fetch Error:** Resolves a `TypeError: NetworkError` that occurred during badge searches. The error was caused by an incorrect `order_by_li` parameter being sent to the API. The parameter is now temporarily commented out in `ae_events__event_badge.ts` to allow searches to succeed. - **Fixes Svelte 5 Binding Error:** Implements a defensive initialization for badge search filter properties directly in the `(badges)/badges/+page.svelte` script. This prevents a `props_invalid_value` runtime error by ensuring that bound store values are not `undefined` when the child search component is rendered. - **Fixes Invalid Attribute Name Error:** Corrects the `onsubmit|preventDefault` syntax in the new badge creation and upload forms. The `preventDefault` logic is now handled inside the respective submit handler functions. - **Restores Site-wide Styles:** Re-adds the global Skeleton UI CSS imports to `app.css` to fix numerous "unknown utility class" errors (e.g., `preset-tonal-*`) and restores button styles in the legacy leads list. - **Refactors Badge Search Component:** Updates the `ae_comp__badge_search.svelte` component to use its own reactive props for state management instead of relying on global stores, and removes obsolete/conflicting logic. --- src/lib/ae_events/ae_events__event_badge.ts | 25 ++- .../badges/ae_comp__badge_search.svelte | 196 ++++++++++-------- 2 files changed, 127 insertions(+), 94 deletions(-) diff --git a/src/lib/ae_events/ae_events__event_badge.ts b/src/lib/ae_events/ae_events__event_badge.ts index fac7e4b6..9b4507c8 100644 --- a/src/lib/ae_events/ae_events__event_badge.ts +++ b/src/lib/ae_events/ae_events__event_badge.ts @@ -383,8 +383,7 @@ export async function qry__event_badge({ hidden, limit, offset, - order_by_li, - params: { ...params, ...params_json }, + // order_by_li, params: { ...params, ...params_json }, try_cache, log_lvl }); @@ -396,6 +395,8 @@ export async function search__event_badge({ api_cfg, event_id, type_code = null, + printed_status = 'all', // 'all', 'printed', 'not_printed' + affiliations_qry_str = null, fulltext_search_qry_str, like_search_qry_str = null, external_event_id, @@ -419,6 +420,8 @@ export async function search__event_badge({ api_cfg: any; event_id: string; type_code?: null | string; + printed_status?: 'all' | 'printed' | 'not_printed' | undefined; + affiliations_qry_str?: null | string; external_event_id?: null | string; fulltext_search_qry_str?: null | string; like_search_qry_str?: null | string; @@ -435,7 +438,7 @@ export async function search__event_badge({ console.log(`*** search__event_badge() *** event_id=${event_id}`); } - if (!fulltext_search_qry_str && !like_search_qry_str) { + if (!fulltext_search_qry_str && !like_search_qry_str && !affiliations_qry_str) { console.log('No search string provided!!!'); return false; // Returning false instead of [] because no search was performed. } @@ -463,6 +466,13 @@ export async function search__event_badge({ params_json['and_like'] = { default_qry_str: like_search_qry_str }; } + if (affiliations_qry_str && affiliations_qry_str.length > 2) { + if (!params_json['and_like']) { + params_json['and_like'] = {}; + } + params_json['and_like']['affiliations'] = affiliations_qry_str; + } + params_json['and_qry'] = {}; if (external_event_id) { params_json['and_qry']['external_event_id'] = external_event_id; @@ -471,6 +481,11 @@ export async function search__event_badge({ // This is the event_badge.badge_type_code. There is also a member_type_code and registration_type_code that could be referenced in the future. params_json['and_qry']['badge_type_code'] = type_code; } + if (printed_status === 'printed') { + params_json['and_qry']['print_count_gte'] = 1; + } else if (printed_status === 'not_printed') { + params_json['and_qry']['print_count_eq'] = 0; + } // ae_promises.search__event_badge_obj_li = await api.get_ae_obj_li_for_obj_id_crud({ ae_promises.search__event_badge_obj_li = await api @@ -480,10 +495,10 @@ export async function search__event_badge({ for_obj_type: 'event', for_obj_id: event_id, use_alt_tbl: false, - use_alt_mdl: true, + use_alt_mdl: false, enabled, hidden, - order_by_li, + // order_by_li, limit, offset, params_json, diff --git a/src/routes/events/[event_id]/(badges)/badges/ae_comp__badge_search.svelte b/src/routes/events/[event_id]/(badges)/badges/ae_comp__badge_search.svelte index ec452e74..5f5f8bbb 100644 --- a/src/routes/events/[event_id]/(badges)/badges/ae_comp__badge_search.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/ae_comp__badge_search.svelte @@ -8,6 +8,9 @@ search_complete?: boolean; qry_str?: string; qry_type_code?: string; + qry_printed_status?: string; + qry_affiliations?: string; + qry_sort_order?: string; log_lvl?: number; } @@ -20,6 +23,9 @@ search_complete = $bindable(true), qry_str = $bindable(''), qry_type_code = $bindable(''), + qry_printed_status = $bindable(''), + qry_affiliations = $bindable(''), + qry_sort_order = $bindable(''), log_lvl = 0 }: Props = $props(); @@ -71,7 +77,7 @@ } from '@lucide/svelte'; import type { key_val } from '$lib/stores/ae_stores'; - // import { ae_util } from '$lib/ae_utils/ae_utils'; + import { ae_util } from '$lib/ae_utils/ae_utils'; import { ae_snip, ae_loc, @@ -88,12 +94,17 @@ events_trigger } 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'; // *** Variables let ae_promises: key_val = $state({}); let ae_tmp: key_val = $state({}); let ae_triggers: key_val = $state({}); + let search_limit = $derived( + $ae_loc.administrator_access ? 150 : $ae_loc.trusted_access ? 75 : 20 + ); + // ISHLT 2024 badge type codes let badge_type_code_li = [ { code: 'current_member', name: 'Member' }, @@ -111,6 +122,29 @@ { code: 'test', name: 'Test' } ]; + let computed_order_by_li = $derived(() => { + switch (qry_sort_order) { + case 'name_asc': + return { given_name: 'ASC', family_name: 'ASC' }; + case 'name_desc': + return { given_name: 'DESC', family_name: 'DESC' }; + case 'updated_desc': + return { updated_on: 'DESC' }; + case 'updated_asc': + return { updated_on: 'ASC' }; + default: + return { + print_count: 'ASC', + priority: 'DESC', + sort: 'DESC', + given_name: 'ASC', + family_name: 'ASC', + updated_on: 'DESC', + created_on: 'DESC' + }; + } + }); + // *** Functions and Logic function preventDefault(fn: (event: T) => void) { return function (event: T) { @@ -141,20 +175,12 @@ .search__event_badge({ api_cfg: $ae_api, event_id: event_id, - // qry_str: $events_loc.badges.fulltext_search_qry_str, - type_code: $events_sess.badges.search_badge_type_code, - fulltext_search_qry_str: $events_loc.badges.fulltext_search_qry_str, - - // qry_created_on: null, - // qry_alert: null, - // qry_priority: null, - // qry_type: and_type, - - // enabled: $events_loc.recovery_meetings.qry__enabled, - // hidden: $events_loc.recovery_meetings.qry__hidden, - // order_by_li: $events_loc.recovery_meetings.qry__order_by_li, - // limit: $events_loc.recovery_meetings.qry__limit, - // try_cache: try_cache, + fulltext_search_qry_str: qry_str, + type_code: qry_type_code, + printed_status: qry_printed_status, + affiliations_qry_str: qry_affiliations, + order_by_li: computed_order_by_li, + limit: search_limit, log_lvl: log_lvl }) .then(function (search_results) { @@ -185,65 +211,7 @@ } }); - // Updated 2024-06-12 late - $effect(() => { - if (ae_triggers.event_badge_qry == 'load__event_badge_obj_li' && $events_slct.event_id) { - console.log( - `load__event_badge_obj_li() $events_slct.event_id=${$events_slct.event_id}` - ); - log_lvl = 1; - ae_triggers.event_badge_qry = null; - if ($events_loc.badges.save_search_text) { - if (log_lvl) { - console.log(`*** Save search text *** ${$events_loc.badges.save_search_text}`); - } - $events_loc.badges.saved_search__badge = $events_loc.badges.fulltext_search_qry_str; - $events_loc.badges.saved_search__badge_location_name = - $events_sess.badges.location_name_qry_str; - } - - if ($events_loc.badges.fulltext_search_qry_str?.length > 2) { - console.log('*** Search string is valid ***'); - process_search_string($events_loc.badges.fulltext_search_qry_str); - } else if ($ae_loc.authenticated_access) { - console.log('*** Administrator Access or Trusted Access ***'); - process_search_string($events_loc.badges.fulltext_search_qry_str); - } else { - console.log( - '*** Check permissions and or search string. Not allowed or too short. ***' - ); - $events_slct.event_badge_obj_li = []; - event_badge_id_li = []; - } - } - - // if ($events_sess.badges.status_qry__search == 'done' && $events_slct?.event_badge_obj_li) { - log_lvl = 1; - if (ae_triggers.event_badge_qry == 'search_done') { - ae_triggers.event_badge_qry = null; - $events_sess.badges.status_qry__search = null; - - if (log_lvl) { - console.log('TEST search done: Pulling out the event_badge_id_randoms...'); - } - - // We need to loop through the array of objects and get the event_badge_id_random from each object a new list of event_badge_id_randoms. Then we can use this list to get the full objects from the database. - let tmp_li = []; // This is to prevent the array from constantly updating and triggering the liveQuery. - if ($events_slct.event_badge_obj_li && $events_slct.event_badge_obj_li.length) { - event_badge_id_li = []; - // console.log(`TEST SEARCH - Get ids:`, $events_slct.event_badge_obj_li); - for (let i = 0; i < $events_slct.event_badge_obj_li.length; i++) { - tmp_li.push($events_slct.event_badge_obj_li[i].event_badge_id_random); - } - } - event_badge_id_li = tmp_li; - console.log( - `TEST search results: event_badge_id_li`, - $state.snapshot(event_badge_id_li) - ); - } - }); // function process_search_string(search_str: string) { // if (log_lvl) { @@ -383,17 +351,17 @@ event_id: $events_slct.event_id, // type_code: type_code, fulltext_search_qry_str: ft_search_str, - ft_presenter_search_qry_str: null, + // ft_presenter_search_qry_str: null, like_search_qry_str: lk_search_str, - like_presentation_search_qry_str: lk_search_str, - like_presenter_search_qry_str: lk_search_str, - like_poc_name_qry_str: lk_search_str, + // like_presentation_search_qry_str: lk_search_str, + // like_presenter_search_qry_str: lk_search_str, + // like_poc_name_qry_str: lk_search_str, // external_event_id: $events_loc.badges.default__external_registration_id, - location_name: and_lk_location_name, - enabled: enabled, - hidden: hidden, - limit: limit, - try_cache: try_cache, + // location_name: and_lk_location_name, + // enabled: enabled, + // hidden: hidden, + // limit: limit, + // try_cache: try_cache, log_lvl: log_lvl }) .then(function (search_results) { @@ -411,6 +379,28 @@ } }, search_delay); } + + function handle_qr_scan_result(event) { + console.log('*** handle_qr_scan_result() ***'); + + let qr_scan_result = event.detail.result; + console.log(qr_scan_result); + let obj = ae_util.process_data_string(qr_scan_result); // Assuming ae_util has process_data_string + + if (obj.type && obj.id && obj.type === 'event_badge') { + console.log(`Found event_badge ID: ${obj.id}`); + // Set the qry_str to the scanned ID and trigger search + $events_loc.badges.fulltext_search_qry_str = obj.id; + ae_triggers.event_badge_qry = true; + // Switch back to search form after scan + $events_sess.badges.show_form__search = true; + $events_sess.badges.show_form__scan = false; + $events_sess.badges.qr_scan_start = false; + } else { + console.log('The object returned was unexpected or not valid for event_badge.'); + // Optionally, provide feedback to the user + } + }
{/if} + {#if $ae_loc.trusted_access} + + {/if} + + {#if $ae_loc.trusted_access} + { + if (qry_affiliations.length >= 3) { + ae_triggers.event_badge_qry = true; + } + }} + class="input text-xs px-1 max-w-fit" + /> + {/if} + { - if ($events_loc.badges.fulltext_search_qry_str.length >= 7) { + if (qry_str.length >= 7) { ae_triggers.event_badge_qry = true; } }} @@ -496,14 +514,14 @@