refactor(badges): standardize helpers and apply batch formatting

- Standardized 'prevent_default' helper names across badges module.
- Corrected native 'event.preventDefault()' calls in view and template components.
- Applied batch formatting (printWidth: 80) to all badges files.
This commit is contained in:
Scott Idem
2026-02-06 14:55:43 -05:00
parent 67752ccdfe
commit 5385eacc0f
11 changed files with 648 additions and 290 deletions

View File

@@ -36,9 +36,13 @@
let lq__event_obj = $derived( let lq__event_obj = $derived(
liveQuery(async () => { liveQuery(async () => {
if (log_lvl) { if (log_lvl) {
console.log(`*** LiveQuery: lq__event_obj *** event_id=${$events_slct.event_id}`); console.log(
`*** LiveQuery: lq__event_obj *** event_id=${$events_slct.event_id}`
);
} }
let results = await db_events.event.get($events_slct?.event_id ?? ''); let results = await db_events.event.get(
$events_slct?.event_id ?? ''
);
return results; return results;
}) })

View File

@@ -15,10 +15,7 @@
// *** Import Aether specific variables and functions // *** Import Aether specific variables and functions
import { ae_util } from '$lib/ae_utils/ae_utils'; import { ae_util } from '$lib/ae_utils/ae_utils';
import { import { ae_loc, ae_api } from '$lib/stores/ae_stores';
ae_loc,
ae_api
} from '$lib/stores/ae_stores';
import { db_events } from '$lib/ae_events/db_events'; import { db_events } from '$lib/ae_events/db_events';
import { import {
@@ -39,13 +36,20 @@
// *** Initialization & Store Guard *** // *** Initialization & Store Guard ***
// Ensure all search fields are initialized to prevent circular undefined triggers // Ensure all search fields are initialized to prevent circular undefined triggers
if ($events_loc.badges) { if ($events_loc.badges) {
if (typeof $events_loc.badges.search_version === 'undefined') $events_loc.badges.search_version = 0; if (typeof $events_loc.badges.search_version === 'undefined')
if (typeof $events_loc.badges.qry__remote_first === 'undefined') $events_loc.badges.qry__remote_first = false; $events_loc.badges.search_version = 0;
if (typeof $events_loc.badges.fulltext_search_qry_str === 'undefined') $events_loc.badges.fulltext_search_qry_str = ''; if (typeof $events_loc.badges.qry__remote_first === 'undefined')
if (typeof $events_loc.badges.search_badge_type_code === 'undefined') $events_loc.badges.search_badge_type_code = ''; $events_loc.badges.qry__remote_first = false;
if (typeof $events_loc.badges.qry_printed_status === 'undefined') $events_loc.badges.qry_printed_status = 'all'; if (typeof $events_loc.badges.fulltext_search_qry_str === 'undefined')
if (typeof $events_loc.badges.qry_affiliations === 'undefined') $events_loc.badges.qry_affiliations = ''; $events_loc.badges.fulltext_search_qry_str = '';
if (typeof $events_loc.badges.qry_sort_order === 'undefined') $events_loc.badges.qry_sort_order = ''; if (typeof $events_loc.badges.search_badge_type_code === 'undefined')
$events_loc.badges.search_badge_type_code = '';
if (typeof $events_loc.badges.qry_printed_status === 'undefined')
$events_loc.badges.qry_printed_status = 'all';
if (typeof $events_loc.badges.qry_affiliations === 'undefined')
$events_loc.badges.qry_affiliations = '';
if (typeof $events_loc.badges.qry_sort_order === 'undefined')
$events_loc.badges.qry_sort_order = '';
} }
// Variables // Variables
@@ -61,18 +65,28 @@
let lq__event_badge_obj_li = $derived.by(() => { let lq__event_badge_obj_li = $derived.by(() => {
const ids = event_badge_id_li; const ids = event_badge_id_li;
const event_id = $events_slct?.event_id; const event_id = $events_slct?.event_id;
return liveQuery(async () => { return liveQuery(async () => {
// SCENARIO 1: Specific IDs provided (Search Results) // SCENARIO 1: Specific IDs provided (Search Results)
if (Array.isArray(ids) && ids.length > 0) { if (Array.isArray(ids) && ids.length > 0) {
if (log_lvl) console.log(`Badge Page LQ: bulkGet ${ids.length} IDs`); if (log_lvl)
console.log(`Badge Page LQ: bulkGet ${ids.length} IDs`);
const results = await db_events.badge.bulkGet(ids); const results = await db_events.badge.bulkGet(ids);
return results.filter(item => item !== undefined); return results.filter((item) => item !== undefined);
} }
// SCENARIO 2: Fallback broad search (Only if no active filters) // SCENARIO 2: Fallback broad search (Only if no active filters)
if (event_id && !$events_loc.badges.fulltext_search_qry_str && $events_loc.badges.qry_printed_status === 'all' && !$events_loc.badges.qry_affiliations && !$events_loc.badges.search_badge_type_code) { if (
if (log_lvl) console.log(`Badge Page LQ: Fallback search for event: ${event_id}`); event_id &&
!$events_loc.badges.fulltext_search_qry_str &&
$events_loc.badges.qry_printed_status === 'all' &&
!$events_loc.badges.qry_affiliations &&
!$events_loc.badges.search_badge_type_code
) {
if (log_lvl)
console.log(
`Badge Page LQ: Fallback search for event: ${event_id}`
);
return await db_events.badge return await db_events.badge
.where('event_id_random') .where('event_id_random')
.equals(event_id) .equals(event_id)
@@ -88,7 +102,9 @@
// 1. Isolate dependencies into a stable derived object // 1. Isolate dependencies into a stable derived object
let search_params = $derived({ let search_params = $derived({
v: $events_loc.badges.search_version, v: $events_loc.badges.search_version,
str: ($events_loc.badges.fulltext_search_qry_str ?? '').toLowerCase().trim(), str: ($events_loc.badges.fulltext_search_qry_str ?? '')
.toLowerCase()
.trim(),
type: $events_loc.badges.search_badge_type_code, type: $events_loc.badges.search_badge_type_code,
printed: $events_loc.badges.qry_printed_status, printed: $events_loc.badges.qry_printed_status,
aff: ($events_loc.badges.qry_affiliations ?? '').toLowerCase().trim(), aff: ($events_loc.badges.qry_affiliations ?? '').toLowerCase().trim(),
@@ -122,9 +138,12 @@
const current_search_id = ++last_search_id; const current_search_id = ++last_search_id;
const event_id = params.event_id; const event_id = params.event_id;
const remote_first = params.remote_first; const remote_first = params.remote_first;
if (log_lvl) console.log(`[Badge Search #${current_search_id}] Refreshing (remote=${remote_first}, event=${event_id}, str=${params.str})...`); if (log_lvl)
console.log(
`[Badge Search #${current_search_id}] Refreshing (remote=${remote_first}, event=${event_id}, str=${params.str})...`
);
untrack(() => { untrack(() => {
$events_sess.badges.search_status = 'loading'; $events_sess.badges.search_status = 'loading';
$events_sess.badges.search_complete = false; $events_sess.badges.search_complete = false;
@@ -142,36 +161,56 @@
let local_results = await db_events.badge let local_results = await db_events.badge
.where('event_id_random') .where('event_id_random')
.equals(event_id) .equals(event_id)
.filter(badge => { .filter((badge) => {
if (type_code && badge.badge_type_code !== type_code) return false; if (
type_code &&
badge.badge_type_code !== type_code
)
return false;
if (printed_status !== 'all') { if (printed_status !== 'all') {
const is_printed = (badge.print_count ?? 0) > 0; const is_printed = (badge.print_count ?? 0) > 0;
if (printed_status === 'printed' && !is_printed) return false; if (printed_status === 'printed' && !is_printed)
if (printed_status === 'not_printed' && is_printed) return false; return false;
if (
printed_status === 'not_printed' &&
is_printed
)
return false;
} }
if (qry_str) { if (qry_str) {
const given_name = (badge.given_name ?? '').toLowerCase(); const given_name = (
const family_name = (badge.family_name ?? '').toLowerCase(); badge.given_name ?? ''
const full_name = `${given_name} ${family_name}`.toLowerCase(); ).toLowerCase();
const family_name = (
badge.family_name ?? ''
).toLowerCase();
const full_name =
`${given_name} ${family_name}`.toLowerCase();
const email = (badge.email ?? '').toLowerCase(); const email = (badge.email ?? '').toLowerCase();
const qry_string = (badge.default_qry_str ?? '').toLowerCase(); const qry_string = (
badge.default_qry_str ?? ''
const match = full_name.includes(qry_str) || ).toLowerCase();
given_name.includes(qry_str) ||
family_name.includes(qry_str) || const match =
email.includes(qry_str) || full_name.includes(qry_str) ||
qry_string.includes(qry_str); given_name.includes(qry_str) ||
family_name.includes(qry_str) ||
email.includes(qry_str) ||
qry_string.includes(qry_str);
if (!match) return false; if (!match) return false;
} }
if (aff_str) { if (aff_str) {
const affiliations = (badge.affiliations ?? '').toLowerCase(); const affiliations = (
if (!affiliations.includes(aff_str)) return false; badge.affiliations ?? ''
).toLowerCase();
if (!affiliations.includes(aff_str))
return false;
} }
return true; return true;
}) })
.toArray(); .toArray();
@@ -180,27 +219,57 @@
local_results.sort((a, b) => { local_results.sort((a, b) => {
switch (params.sort) { switch (params.sort) {
case 'name_asc': case 'name_asc':
return (a.given_name ?? '').localeCompare(b.given_name ?? '') || (a.family_name ?? '').localeCompare(b.family_name ?? ''); return (
(a.given_name ?? '').localeCompare(
b.given_name ?? ''
) ||
(a.family_name ?? '').localeCompare(
b.family_name ?? ''
)
);
case 'name_desc': case 'name_desc':
return (b.given_name ?? '').localeCompare(a.given_name ?? '') || (b.family_name ?? '').localeCompare(a.family_name ?? ''); return (
(b.given_name ?? '').localeCompare(
a.given_name ?? ''
) ||
(b.family_name ?? '').localeCompare(
a.family_name ?? ''
)
);
case 'updated_desc': case 'updated_desc':
return new Date(b.updated_on || 0).getTime() - new Date(a.updated_on || 0).getTime(); return (
new Date(b.updated_on || 0).getTime() -
new Date(a.updated_on || 0).getTime()
);
case 'updated_asc': case 'updated_asc':
return new Date(a.updated_on || 0).getTime() - new Date(b.updated_on || 0).getTime(); return (
new Date(a.updated_on || 0).getTime() -
new Date(b.updated_on || 0).getTime()
);
case 'print_count_desc': case 'print_count_desc':
return (b.print_count ?? 0) - (a.print_count ?? 0); return (
(b.print_count ?? 0) - (a.print_count ?? 0)
);
default: default:
return (a.given_name ?? '').localeCompare(b.given_name ?? ''); return (a.given_name ?? '').localeCompare(
b.given_name ?? ''
);
} }
}); });
const local_ids = local_results.map(b => b.id || b.event_badge_id_random).filter(Boolean); const local_ids = local_results
.map((b) => b.id || b.event_badge_id_random)
.filter(Boolean);
if (current_search_id === last_search_id) { if (current_search_id === last_search_id) {
if (log_lvl) console.log(`[Badge Search #${current_search_id}] Fast Path found ${local_ids.length} items locally.`); if (log_lvl)
console.log(
`[Badge Search #${current_search_id}] Fast Path found ${local_ids.length} items locally.`
);
untrack(() => { untrack(() => {
event_badge_id_li = local_ids; event_badge_id_li = local_ids;
if (local_ids.length > 0) $events_sess.badges.search_status = 'done'; if (local_ids.length > 0)
$events_sess.badges.search_status = 'done';
}); });
} }
} }
@@ -218,12 +287,23 @@
// Map sort param to API order_by_li // Map sort param to API order_by_li
let order_by_li: any = {}; let order_by_li: any = {};
switch (params.sort) { switch (params.sort) {
case 'name_asc': order_by_li = { given_name: 'ASC', family_name: 'ASC' }; break; case 'name_asc':
case 'name_desc': order_by_li = { given_name: 'DESC', family_name: 'DESC' }; break; order_by_li = { given_name: 'ASC', family_name: 'ASC' };
case 'updated_desc': order_by_li = { updated_on: 'DESC' }; break; break;
case 'updated_asc': order_by_li = { updated_on: 'ASC' }; break; case 'name_desc':
case 'print_count_desc': order_by_li = { print_count: 'DESC' }; break; order_by_li = { given_name: 'DESC', family_name: 'DESC' };
default: order_by_li = { given_name: 'ASC' }; break;
case 'updated_desc':
order_by_li = { updated_on: 'DESC' };
break;
case 'updated_asc':
order_by_li = { updated_on: 'ASC' };
break;
case 'print_count_desc':
order_by_li = { print_count: 'DESC' };
break;
default:
order_by_li = { given_name: 'ASC' };
} }
const results = await events_func.search__event_badge({ const results = await events_func.search__event_badge({
@@ -240,15 +320,20 @@
if (current_search_id === last_search_id) { if (current_search_id === last_search_id) {
const api_results = results || []; const api_results = results || [];
const api_ids = api_results.map((b: any) => b.id || b.event_badge_id_random).filter(Boolean); const api_ids = api_results
.map((b: any) => b.id || b.event_badge_id_random)
.filter(Boolean);
untrack(() => { untrack(() => {
$events_sess.badge_li = api_results; $events_sess.badge_li = api_results;
event_badge_id_li = api_ids; event_badge_id_li = api_ids;
$events_sess.badges.search_status = 'done'; $events_sess.badges.search_status = 'done';
$events_sess.badges.search_complete = true; $events_sess.badges.search_complete = true;
}); });
if (log_lvl) console.log(`[Badge Search #${current_search_id}] Revalidation Complete. Found ${api_ids.length} items.`); if (log_lvl)
console.log(
`[Badge Search #${current_search_id}] Revalidation Complete. Found ${api_ids.length} items.`
);
} }
} catch (error) { } catch (error) {
if (current_search_id === last_search_id) { if (current_search_id === last_search_id) {
@@ -265,24 +350,24 @@
<svelte:head> <svelte:head>
<title> <title>
Badges - Badges -
{ae_util.shorten_string({ string: $events_slct?.event_obj?.name ?? '-- not set --', max_length: 12 })} {ae_util.shorten_string({
string: $events_slct?.event_obj?.name ?? '-- not set --',
max_length: 12
})}
- OSIT's &AElig; Events - OSIT's &AElig; Events
</title> </title>
</svelte:head> </svelte:head>
<Comp_badge_search <Comp_badge_search event_id={$events_slct?.event_id ?? ''} log_lvl={1}
event_id={$events_slct?.event_id ?? ''}
log_lvl={1}
></Comp_badge_search> ></Comp_badge_search>
{#if $events_sess?.badges?.search_status === 'loading' && event_badge_id_li.length === 0} {#if $events_sess?.badges?.search_status === 'loading' && event_badge_id_li.length === 0}
<div class="flex flex-col items-center justify-center p-10 opacity-50 text-center"> <div
class="flex flex-col items-center justify-center p-10 opacity-50 text-center"
>
<LoaderCircle size="3em" class="animate-spin mb-4 mx-auto" /> <LoaderCircle size="3em" class="animate-spin mb-4 mx-auto" />
<p class="text-xl">Loading badges...</p> <p class="text-xl">Loading badges...</p>
</div> </div>
{:else} {:else}
<Comp_badge_obj_li <Comp_badge_obj_li {lq__event_badge_obj_li} log_lvl={1}></Comp_badge_obj_li>
lq__event_badge_obj_li={lq__event_badge_obj_li} {/if}
log_lvl={1}
></Comp_badge_obj_li>
{/if}

View File

@@ -48,7 +48,10 @@
} }
let results = await db_events.badge.get(event_badge_id); let results = await db_events.badge.get(event_badge_id);
if (log_lvl) { if (log_lvl) {
console.log(`*** LiveQuery: lq__event_badge_obj *** results=`, results); console.log(
`*** LiveQuery: lq__event_badge_obj *** results=`,
results
);
} }
return results; return results;
}) })
@@ -56,7 +59,9 @@
let lq__event_badge_template_obj = $derived( let lq__event_badge_template_obj = $derived(
liveQuery(async () => { liveQuery(async () => {
let results = await db_events.badge_template.get($lq__event_badge_obj?.event_badge_template_id ?? ''); // null or undefined does not reset things like '' does let results = await db_events.badge_template.get(
$lq__event_badge_obj?.event_badge_template_id ?? ''
); // null or undefined does not reset things like '' does
if (log_lvl) { if (log_lvl) {
console.log( console.log(
@@ -86,7 +91,9 @@
let lq__event_obj: any = $state(undefined); let lq__event_obj: any = $state(undefined);
onMount(() => { onMount(() => {
const observable = liveQuery(() => db_events.event.get($events_slct?.event_id ?? '')); const observable = liveQuery(() =>
db_events.event.get($events_slct?.event_id ?? '')
);
const subscription = observable.subscribe((value) => { const subscription = observable.subscribe((value) => {
lq__event_obj = value; lq__event_obj = value;
}); });
@@ -109,7 +116,9 @@
<title> <title>
&AElig;: Badge - &AElig;: Badge -
{$lq__event_badge_obj?.given_name ?? '-- not set --'} {$lq__event_badge_obj?.given_name ?? '-- not set --'}
{$lq__event_badge_obj?.family_name ? $lq__event_badge_obj?.family_name.charAt(0) + '.' : ''} {$lq__event_badge_obj?.family_name
? $lq__event_badge_obj?.family_name.charAt(0) + '.'
: ''}
- Badges v3 - - Badges v3 -
{$events_loc?.title} {$events_loc?.title}
</title> </title>
@@ -149,13 +158,13 @@
</header> </header>
{#if $lq__event_badge_obj} {#if $lq__event_badge_obj}
<Comp_badge_obj_view <Comp_badge_obj_view
event_id={$lq__event_badge_obj.event_id} event_id={$lq__event_badge_obj.event_id}
{event_badge_id} {event_badge_id}
lq__event_badge_obj={lq__event_badge_obj} {lq__event_badge_obj}
{is_review_mode} {is_review_mode}
lq__event_badge_template_obj={lq__event_badge_template_obj} {lq__event_badge_template_obj}
/> />
{/if} {/if}
{:else} {:else}
<p>No IDB record found for ID: {event_badge_id}</p> <p>No IDB record found for ID: {event_badge_id}</p>

View File

@@ -100,20 +100,27 @@
$effect(() => { $effect(() => {
if ($lq__event_badge_obj) { if ($lq__event_badge_obj) {
if (log_lvl) { if (log_lvl) {
console.log('Initializing editable fields from lq__event_badge_obj'); console.log(
'Initializing editable fields from lq__event_badge_obj'
);
} }
editable_full_name_override = editable_full_name_override =
$lq__event_badge_obj.full_name_override ?? $lq__event_badge_obj.full_name; $lq__event_badge_obj.full_name_override ??
$lq__event_badge_obj.full_name;
editable_professional_title_override = editable_professional_title_override =
$lq__event_badge_obj.professional_title_override ?? $lq__event_badge_obj.professional_title_override ??
$lq__event_badge_obj.professional_title; $lq__event_badge_obj.professional_title;
editable_affiliations_override = editable_affiliations_override =
$lq__event_badge_obj.affiliations_override ?? $lq__event_badge_obj.affiliations; $lq__event_badge_obj.affiliations_override ??
$lq__event_badge_obj.affiliations;
editable_location_override = editable_location_override =
$lq__event_badge_obj.location_override ?? $lq__event_badge_obj.location; $lq__event_badge_obj.location_override ??
editable_allow_tracking = $lq__event_badge_obj.allow_tracking ?? null; $lq__event_badge_obj.location;
editable_allow_tracking =
$lq__event_badge_obj.allow_tracking ?? null;
editable_email = $lq__event_badge_obj.email ?? null; editable_email = $lq__event_badge_obj.email ?? null;
editable_badge_type_code = $lq__event_badge_obj.badge_type_code ?? null; editable_badge_type_code =
$lq__event_badge_obj.badge_type_code ?? null;
if (is_review_mode) { if (is_review_mode) {
edit_mode_active = true; edit_mode_active = true;
@@ -137,7 +144,6 @@
let option_other_1_override = $state(''); let option_other_1_override = $state('');
let option_other_2_override = $state(''); let option_other_2_override = $state('');
let slct_badge_type = ''; let slct_badge_type = '';
/* *** BEGIN *** This should be moved out */ /* *** BEGIN *** This should be moved out */
@@ -154,8 +160,10 @@
code_to_html.option_1['1'] = '<span class="fas fa-biohazard"></span>'; code_to_html.option_1['1'] = '<span class="fas fa-biohazard"></span>';
code_to_html.option_1['true'] = '<span class="fas fa-biohazard"></span>'; code_to_html.option_1['true'] = '<span class="fas fa-biohazard"></span>';
code_to_html.option_1['True'] = '<span class="fas fa-biohazard"></span>'; code_to_html.option_1['True'] = '<span class="fas fa-biohazard"></span>';
code_to_html.option_1['Dairy Free'] = '<span class="fas fa-utensils"></span>'; code_to_html.option_1['Dairy Free'] =
code_to_html.option_1['Gluten Free'] = '<span class="fas fa-utensils"></span>'; '<span class="fas fa-utensils"></span>';
code_to_html.option_1['Gluten Free'] =
'<span class="fas fa-utensils"></span>';
code_to_html.option_1['Halal'] = '<span class="fas fa-utensils"></span>'; code_to_html.option_1['Halal'] = '<span class="fas fa-utensils"></span>';
code_to_html.option_1['Kosher'] = '<span class="fas fa-utensils"></span>'; code_to_html.option_1['Kosher'] = '<span class="fas fa-utensils"></span>';
code_to_html.option_1['Meat'] = '<span class="fas fa-bone"></span>'; code_to_html.option_1['Meat'] = '<span class="fas fa-bone"></span>';
@@ -167,7 +175,8 @@
code_to_html.option_2['true'] = '<span class="fas fa-star-of-life"></span>'; code_to_html.option_2['true'] = '<span class="fas fa-star-of-life"></span>';
code_to_html.option_2['True'] = '<span class="fas fa-star-of-life"></span>'; code_to_html.option_2['True'] = '<span class="fas fa-star-of-life"></span>';
code_to_html.option_2['First Time '] = '<span class="fas fa-hand-paper"></span>'; code_to_html.option_2['First Time '] =
'<span class="fas fa-hand-paper"></span>';
/* *** END *** This should be moved out */ /* *** END *** This should be moved out */
let full_name_class_size: string = $state('text-[.60in]'); let full_name_class_size: string = $state('text-[.60in]');
@@ -177,7 +186,6 @@
// WARNING: This does not currently take into account the total lengths of the strings, only the longest part when split by spaces. This help with wrapping in the tighter spaces of the badge. // WARNING: This does not currently take into account the total lengths of the strings, only the longest part when split by spaces. This help with wrapping in the tighter spaces of the badge.
$effect(() => { $effect(() => {
// Re-calculate font sizes based on potentially edited values // Re-calculate font sizes based on potentially edited values
// Only run if we have the badge object // Only run if we have the badge object
@@ -190,11 +198,14 @@
$lq__event_badge_obj.professional_title ?? $lq__event_badge_obj.professional_title ??
''; '';
const current_affiliations = const current_affiliations =
editable_affiliations_override ?? $lq__event_badge_obj.affiliations ?? ''; editable_affiliations_override ??
$lq__event_badge_obj.affiliations ??
'';
const current_location = const current_location =
editable_location_override ?? $lq__event_badge_obj.location ?? ''; editable_location_override ?? $lq__event_badge_obj.location ?? '';
let longest_full_name_override_part = longest_str_part(current_full_name); let longest_full_name_override_part =
longest_str_part(current_full_name);
if (longest_full_name_override_part >= 9) { if (longest_full_name_override_part >= 9) {
full_name_class_size = 'text-[.45in]'; full_name_class_size = 'text-[.45in]';
} else if (longest_full_name_override_part >= 7) { } else if (longest_full_name_override_part >= 7) {
@@ -203,7 +214,9 @@
full_name_class_size = 'text-[.75in]'; full_name_class_size = 'text-[.75in]';
} }
let longest_professional_title_override_part = longest_str_part(current_professional_title); let longest_professional_title_override_part = longest_str_part(
current_professional_title
);
if (longest_professional_title_override_part >= 13) { if (longest_professional_title_override_part >= 13) {
professional_title_class_size = 'text-[.35in]'; professional_title_class_size = 'text-[.35in]';
} else if (longest_professional_title_override_part >= 10) { } else if (longest_professional_title_override_part >= 10) {
@@ -214,7 +227,8 @@
professional_title_class_size = 'text-[.35in]'; professional_title_class_size = 'text-[.35in]';
} }
let longest_affiliations_override_part = longest_str_part(current_affiliations); let longest_affiliations_override_part =
longest_str_part(current_affiliations);
if (longest_affiliations_override_part >= 55) { if (longest_affiliations_override_part >= 55) {
affiliations_class_size = 'text-[.30in]'; affiliations_class_size = 'text-[.30in]';
} else if (longest_affiliations_override_part >= 45) { } else if (longest_affiliations_override_part >= 45) {
@@ -260,7 +274,7 @@
// *** Functions and Logic // *** Functions and Logic
function prevent_default<T extends Event>(fn: (event: T) => void) { function prevent_default<T extends Event>(fn: (event: T) => void) {
return function (event: T) { return function (event: T) {
event.prevent_default(); event.preventDefault();
fn(event); fn(event);
}; };
} }
@@ -334,7 +348,10 @@
qr_data_url = ''; qr_data_url = '';
try { try {
// Use 'vcard' as the qr_type, passing all required params // Use 'vcard' as the qr_type, passing all required params
const dataUrl = await core_func.js_generate_qr_code('vcard', qrParams); const dataUrl = await core_func.js_generate_qr_code(
'vcard',
qrParams
);
qr_data_url = dataUrl; qr_data_url = dataUrl;
} catch (error) { } catch (error) {
qr_error_message = error.message; qr_error_message = error.message;
@@ -356,7 +373,8 @@
// Only include fields that have actually changed // Only include fields that have actually changed
if ( if (
editable_full_name_override !== editable_full_name_override !==
($lq__event_badge_obj.full_name_override ?? $lq__event_badge_obj.full_name) ($lq__event_badge_obj.full_name_override ??
$lq__event_badge_obj.full_name)
) { ) {
data_to_update.full_name_override = editable_full_name_override; data_to_update.full_name_override = editable_full_name_override;
} }
@@ -365,17 +383,21 @@
($lq__event_badge_obj.professional_title_override ?? ($lq__event_badge_obj.professional_title_override ??
$lq__event_badge_obj.professional_title) $lq__event_badge_obj.professional_title)
) { ) {
data_to_update.professional_title_override = editable_professional_title_override; data_to_update.professional_title_override =
editable_professional_title_override;
} }
if ( if (
editable_affiliations_override !== editable_affiliations_override !==
($lq__event_badge_obj.affiliations_override ?? $lq__event_badge_obj.affiliations) ($lq__event_badge_obj.affiliations_override ??
$lq__event_badge_obj.affiliations)
) { ) {
data_to_update.affiliations_override = editable_affiliations_override; data_to_update.affiliations_override =
editable_affiliations_override;
} }
if ( if (
editable_location_override !== editable_location_override !==
($lq__event_badge_obj.location_override ?? $lq__event_badge_obj.location) ($lq__event_badge_obj.location_override ??
$lq__event_badge_obj.location)
) { ) {
data_to_update.location_override = editable_location_override; data_to_update.location_override = editable_location_override;
} }
@@ -425,17 +447,22 @@
function handle_cancel_changes() { function handle_cancel_changes() {
if ($lq__event_badge_obj) { if ($lq__event_badge_obj) {
editable_full_name_override = editable_full_name_override =
$lq__event_badge_obj.full_name_override ?? $lq__event_badge_obj.full_name; $lq__event_badge_obj.full_name_override ??
$lq__event_badge_obj.full_name;
editable_professional_title_override = editable_professional_title_override =
$lq__event_badge_obj.professional_title_override ?? $lq__event_badge_obj.professional_title_override ??
$lq__event_badge_obj.professional_title; $lq__event_badge_obj.professional_title;
editable_affiliations_override = editable_affiliations_override =
$lq__event_badge_obj.affiliations_override ?? $lq__event_badge_obj.affiliations; $lq__event_badge_obj.affiliations_override ??
$lq__event_badge_obj.affiliations;
editable_location_override = editable_location_override =
$lq__event_badge_obj.location_override ?? $lq__event_badge_obj.location; $lq__event_badge_obj.location_override ??
editable_allow_tracking = $lq__event_badge_obj.allow_tracking ?? null; $lq__event_badge_obj.location;
editable_allow_tracking =
$lq__event_badge_obj.allow_tracking ?? null;
editable_email = $lq__event_badge_obj.email ?? null; editable_email = $lq__event_badge_obj.email ?? null;
editable_badge_type_code = $lq__event_badge_obj.badge_type_code ?? null; editable_badge_type_code =
$lq__event_badge_obj.badge_type_code ?? null;
} }
if (!is_review_mode) { if (!is_review_mode) {
edit_mode_active = false; edit_mode_active = false;
@@ -479,8 +506,7 @@ onkeypress={() => {
max-w-[8.5in] overflow-visible max-w-[8.5in] overflow-visible
" "
> >
<!-- <pre>
<!-- <pre>
{$lq__event_badge_obj?.event_id} {$lq__event_badge_obj?.event_id}
{$lq__event_badge_obj?.event_badge_id} {$lq__event_badge_obj?.event_badge_id}
{$lq__event_badge_obj?.event_badge_template_id} {$lq__event_badge_obj?.event_badge_template_id}
@@ -528,7 +554,8 @@ onkeypress={() => {
class:preset-tonal-warning={edit_mode_active} class:preset-tonal-warning={edit_mode_active}
> >
{#if edit_mode_active} {#if edit_mode_active}
<button type="button" <button
type="button"
class=" class="
btn btn-sm text-xs btn btn-sm text-xs
preset-tonal-success preset-outlined-success-100-900 hover:preset-filled-success-500 preset-tonal-success preset-outlined-success-100-900 hover:preset-filled-success-500
@@ -548,7 +575,8 @@ onkeypress={() => {
Save Changes Save Changes
</span> </span>
</button> </button>
<button type="button" <button
type="button"
class=" class="
btn btn-sm text-xs btn btn-sm text-xs
preset-tonal-tertiary preset-outlined-tertiary-100-900 hover:preset-filled-tertiary-500 preset-tonal-tertiary preset-outlined-tertiary-100-900 hover:preset-filled-tertiary-500
@@ -569,7 +597,8 @@ onkeypress={() => {
</span> </span>
</button> </button>
{:else} {:else}
<button type="button" <button
type="button"
class=" class="
btn btn-sm text-xs btn btn-sm text-xs
preset-tonal-warning preset-outlined-warning-100-900 hover:preset-filled-secondary-500 preset-tonal-warning preset-outlined-warning-100-900 hover:preset-filled-secondary-500
@@ -594,10 +623,14 @@ onkeypress={() => {
</button> </button>
{/if} {/if}
<div class="w-md max-w-lg m-1 p-1" class:hidden={!edit_mode_active}> <div
class="w-md max-w-lg m-1 p-1"
class:hidden={!edit_mode_active}
>
<p class="text-xs italic text-gray-500"> <p class="text-xs italic text-gray-500">
Show list of fields that they can edit here. This may need to broken down in Show list of fields that they can edit here. This may
to sections that can be collapsed. need to broken down in to sections that can be
collapsed.
</p> </p>
<ul class="text-left list-disc list-inside text-sm"> <ul class="text-left list-disc list-inside text-sm">
<li>Full Name</li> <li>Full Name</li>
@@ -672,7 +705,9 @@ onkeypress={() => {
<!-- NOTE: Need to add some logic if any part of the name is 9 characters or more to reduce the font size OR if the total length is more than 15ish to reduce the font size :NOTE --> <!-- NOTE: Need to add some logic if any part of the name is 9 characters or more to reduce the font size OR if the total length is more than 15ish to reduce the font size :NOTE -->
<!-- Examples: mSC-tTzL_OA, QLddtYl8sfo --> <!-- Examples: mSC-tTzL_OA, QLddtYl8sfo -->
<div class="full_name_override_all {full_name_class_size} leading-none"> <div
class="full_name_override_all {full_name_class_size} leading-none"
>
<!-- <span class="float-right text-sm italic m-2"> <!-- <span class="float-right text-sm italic m-2">
{longest_full_name_override_part}&times; char {longest_full_name_override_part}&times; char
</span> --> </span> -->
@@ -703,7 +738,9 @@ onkeypress={() => {
{#if edit_mode_active} {#if edit_mode_active}
<input <input
type="text" type="text"
bind:value={editable_professional_title_override} bind:value={
editable_professional_title_override
}
class="input w-full text-center" class="input w-full text-center"
/> />
{:else} {:else}
@@ -728,7 +765,9 @@ onkeypress={() => {
> >
{#if edit_mode_active} {#if edit_mode_active}
<textarea <textarea
bind:value={editable_affiliations_override} bind:value={
editable_affiliations_override
}
class="textarea w-full text-center" class="textarea w-full text-center"
rows="2" rows="2"
></textarea> ></textarea>
@@ -782,12 +821,16 @@ onkeypress={() => {
<label <label
>Allow Tracking: <input >Allow Tracking: <input
type="checkbox" type="checkbox"
bind:checked={editable_allow_tracking} bind:checked={
editable_allow_tracking
}
class="checkbox" class="checkbox"
/></label /></label
> >
{:else} {:else}
Allow Tracking: {editable_allow_tracking ? 'Yes' : 'No'} Allow Tracking: {editable_allow_tracking
? 'Yes'
: 'No'}
{/if} {/if}
</div> </div>
{/if} {/if}
@@ -803,10 +846,12 @@ onkeypress={() => {
</span> </span>
<span class="badge_body_special_right"> <span class="badge_body_special_right">
{#if option_ticket_2_override} {#if option_ticket_2_override}
<span class=" ticket_2_code fg_red fas fa-star"></span> <span class=" ticket_2_code fg_red fas fa-star"
></span>
{/if} {/if}
{#if option_ticket_3_override} {#if option_ticket_3_override}
<span class="ticket_3_code fg_blue fas fa-star"></span> <span class="ticket_3_code fg_blue fas fa-star"
></span>
{/if} {/if}
</span> </span>
{#if lq__event_badge_template_obj.show_qr_front} {#if lq__event_badge_template_obj.show_qr_front}
@@ -866,7 +911,8 @@ onkeypress={() => {
> >
{/if} {/if}
<span class="badge_footer_center {editable_badge_type_code?.toLowerCase()}" <span
class="badge_footer_center {editable_badge_type_code?.toLowerCase()}"
>{editable_badge_type_code}</span >{editable_badge_type_code}</span
> >
@@ -1015,17 +1061,27 @@ onkeypress={() => {
" "
> >
{#if $lq__event_badge_template_obj.wireless_ssid} {#if $lq__event_badge_template_obj.wireless_ssid}
<div class="grow flex flex-col gap-0 items-center justify-end"> <div
<span class="w-full flex flex-row gap-1 items-center justify-start"> class="grow flex flex-col gap-0 items-center justify-end"
<span class="w-20 text-gray-500 italic"> Signal Name </span> >
<span
class="w-full flex flex-row gap-1 items-center justify-start"
>
<span class="w-20 text-gray-500 italic">
Signal Name
</span>
<strong <strong
class="wifi_ssid font-bold font-mono text-lg tracking-widest leading-none" class="wifi_ssid font-bold font-mono text-lg tracking-widest leading-none"
> >
{$lq__event_badge_template_obj.wireless_ssid} {$lq__event_badge_template_obj.wireless_ssid}
</strong> </strong>
</span> </span>
<span class="w-full flex flex-row gap-1 items-center justify-start"> <span
<span class="w-20 text-gray-500 italic"> Access Code </span> class="w-full flex flex-row gap-1 items-center justify-start"
>
<span class="w-20 text-gray-500 italic">
Access Code
</span>
<strong <strong
class="wifi_code font-bold font-mono text-lg tracking-widest leading-none" class="wifi_code font-bold font-mono text-lg tracking-widest leading-none"
> >
@@ -1042,8 +1098,10 @@ onkeypress={() => {
{/if} {/if}
<div class="network_username_password hidden"> <div class="network_username_password hidden">
Username = <span class="network_username">username</span><br /> Username = <span class="network_username">username</span
Password = <span class="network_password">password</span> ><br />
Password =
<span class="network_password">password</span>
</div> </div>
</div> </div>
@@ -1052,7 +1110,9 @@ onkeypress={() => {
<!-- <img style="width: .75in; float: right;" src="/event/qr_image/testing123" alt="missing person information QR code"> --> <!-- <img style="width: .75in; float: right;" src="/event/qr_image/testing123" alt="missing person information QR code"> -->
<ol style="margin: 0; padding-top: 0; padding-bottom: 0;"> <ol style="margin: 0; padding-top: 0; padding-bottom: 0;">
<li style=""> <li style="">
Use QR code or search your app store for "<strong>App Name</strong>" Use QR code or search your app store for "<strong
>App Name</strong
>"
</li> </li>
<li style=""> <li style="">
Once downloaded, use the search feature to find "<strong Once downloaded, use the search feature to find "<strong
@@ -1060,7 +1120,9 @@ onkeypress={() => {
>" guide >" guide
</li> </li>
<li style=""> <li style="">
You may also go to <a href="https://oneskyit.com/">OneSkyIT.com</a> You may also go to <a href="https://oneskyit.com/"
>OneSkyIT.com</a
>
</li> </li>
</ol> </ol>
</div> </div>
@@ -1072,19 +1134,29 @@ onkeypress={() => {
<!-- <strong>Attendee Info:</strong> --> <!-- <strong>Attendee Info:</strong> -->
<ul> <ul>
{#if $lq__event_badge_obj.ticket_1_code} {#if $lq__event_badge_obj.ticket_1_code}
<li>{@html $lq__event_badge_template_obj.ticket_1_text}</li> <li>
{@html $lq__event_badge_template_obj.ticket_1_text}
</li>
{/if} {/if}
{#if $lq__event_badge_obj.ticket_2_code} {#if $lq__event_badge_obj.ticket_2_code}
<li>{@html $lq__event_badge_template_obj.ticket_2_text}</li> <li>
{@html $lq__event_badge_template_obj.ticket_2_text}
</li>
{/if} {/if}
{#if $lq__event_badge_obj.ticket_3_code} {#if $lq__event_badge_obj.ticket_3_code}
<li>{@html $lq__event_badge_template_obj.ticket_3_text}</li> <li>
{@html $lq__event_badge_template_obj.ticket_3_text}
</li>
{/if} {/if}
{#if $lq__event_badge_obj.ticket_4_code} {#if $lq__event_badge_obj.ticket_4_code}
<li>{@html $lq__event_badge_template_obj.ticket_4_text}</li> <li>
{@html $lq__event_badge_template_obj.ticket_4_text}
</li>
{/if} {/if}
{#if $lq__event_badge_obj.ticket_5_code} {#if $lq__event_badge_obj.ticket_5_code}
<li>{@html $lq__event_badge_template_obj.ticket_5_text}</li> <li>
{@html $lq__event_badge_template_obj.ticket_5_text}
</li>
{/if} {/if}
</ul> </ul>
@@ -1192,7 +1264,9 @@ onkeypress={() => {
alt="badge QR code" alt="badge QR code"
ondblclick={() => { ondblclick={() => {
// (hide_qr) ? hide_qr = !hide_qr : hide_qr; // (hide_qr) ? hide_qr = !hide_qr : hide_qr;
hide_qr ? (hide_qr = false) : (hide_qr = true); hide_qr
? (hide_qr = false)
: (hide_qr = true);
}} }}
/> />
<div <div
@@ -1203,22 +1277,28 @@ onkeypress={() => {
> >
{#if $lq__event_badge_obj.allow_tracking} {#if $lq__event_badge_obj.allow_tracking}
<p> <p>
This was <strong>allowed</strong> at the time your badge This was <strong>allowed</strong
was printed. You may opt-out at anytime. > at the time your badge was printed.
You may opt-out at anytime.
</p> </p>
<p> <p>
By allowing this QR code to be scanned by an By allowing this QR code to be
exhibitor or staff, you understand and agree that scanned by an exhibitor or
they may use your personal information. staff, you understand and agree
that they may use your personal
information.
</p> </p>
{:else} {:else}
<p> <p>
Tracking was <strong>not</strong> allowed at the time Tracking was <strong>not</strong
your badge was printed. You may opt-in at anytime. > allowed at the time your badge was
printed. You may opt-in at anytime.
</p> </p>
<p> <p>
If this QR code is scanned by an exhibitor or staff, If this QR code is scanned by an
they will <strong>not</strong> have access to your information. exhibitor or staff, they will <strong
>not</strong
> have access to your information.
</p> </p>
{/if} {/if}
</div> </div>
@@ -1252,8 +1332,12 @@ onkeypress={() => {
alt="check badge logo" alt="check badge logo"
/> />
<div class="banner_text"> <div class="banner_text">
<div class="row_one">{$lq__event_badge_template_obj.header_row_1}</div> <div class="row_one">
<div class="row_two">{$lq__event_badge_template_obj.header_row_2}</div> {$lq__event_badge_template_obj.header_row_1}
</div>
<div class="row_two">
{$lq__event_badge_template_obj.header_row_2}
</div>
</div> </div>
</div> </div>
@@ -1261,17 +1345,21 @@ onkeypress={() => {
<!-- receipt_content class div start --> <!-- receipt_content class div start -->
<div> <div>
<span style="display: none;" <span style="display: none;"
>Invoice Number: <span class="Invoice_Number">Invoice_Number</span><br >Invoice Number: <span class="Invoice_Number"
/></span >Invoice_Number</span
><br /></span
> >
Account Number: <span class="BT_ID">BT_ID</span><br /> Account Number: <span class="BT_ID">BT_ID</span><br />
Order Number: <span class="Order_Number">Order_Number</span><br /> Order Number:
<span class="Order_Number">Order_Number</span><br />
</div> </div>
<hr /> <hr />
<div> <div>
Name: <span class="Orders_Full_Name">Full Name</span> (ID: Name: <span class="Orders_Full_Name">Full Name</span> (ID:
<span class="Member_ID">Member_ID</span>)<br /> <span class="Member_ID">Member_ID</span>)<br />
<address><span class="Orders_Full_Address">Full Address</span></address> <address>
<span class="Orders_Full_Address">Full Address</span>
</address>
Email:<span class="Orders_Email">No Email</span> Email:<span class="Orders_Email">No Email</span>
</div> </div>
<hr /> <hr />
@@ -1288,34 +1376,49 @@ onkeypress={() => {
</thead> </thead>
<tbody> <tbody>
<tr class="roweven" <tr class="roweven"
><td>1</td><td>Registration for Meeting</td><td>1</td><td>$300.00</td ><td>1</td><td>Registration for Meeting</td><td
><td>$300.00</td></tr >1</td
><td>$300.00</td><td>$300.00</td></tr
> >
<tr class="rowodd" <tr class="rowodd"
><td>2</td><td>Printed Program</td><td>1</td><td>$25.00</td><td ><td>2</td><td>Printed Program</td><td>1</td><td
>$25.00</td >$25.00</td
></tr ><td>$25.00</td></tr
> >
<tr class="roweven" <tr class="roweven"
><td>3</td><td>Opening Reception</td><td>1</td><td>$0.00</td><td ><td>3</td><td>Opening Reception</td><td>1</td><td
>$0.00</td >$0.00</td
></tr ><td>$0.00</td></tr
> >
<tr class="rowodd" <tr class="rowodd"
><td>4</td><td>Closing Banquet</td><td>1</td><td>$85.00</td><td ><td>4</td><td>Closing Banquet</td><td>1</td><td
>$85.00</td >$85.00</td
><td>$85.00</td></tr
>
<tr
><th colspan="4">Total Charges:</th><th colspan="2"
>$410.00</th
></tr
>
<tr
><th colspan="4">Total Payments:</th><th colspan="2"
>$410.00</th
></tr
>
<tr
><th colspan="4">Balance:</th><th colspan="2"
>$0.00</th
></tr ></tr
> >
<tr><th colspan="4">Total Charges:</th><th colspan="2">$410.00</th></tr>
<tr><th colspan="4">Total Payments:</th><th colspan="2">$410.00</th></tr>
<tr><th colspan="4">Balance:</th><th colspan="2">$0.00</th></tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<!-- receipt_content class div end --> <!-- receipt_content class div end -->
<div class="receipt_footer"> <div class="receipt_footer">
<p class="printed">Receipt Printed: January 23, 2019 03:18 PM</p> <p class="printed">
Receipt Printed: January 23, 2019 03:18 PM
</p>
</div> </div>
</section> </section>
<!-- receipt class div end --> <!-- receipt class div end -->
@@ -1392,22 +1495,21 @@ onkeypress={() => {
<!-- End if for $lq__event_badge_template_obj --> <!-- End if for $lq__event_badge_template_obj -->
</section> </section>
<div> <div>
<h1 class="text-lg font-bold mt-4">Debug Information</h1> <h1 class="text-lg font-bold mt-4">Debug Information</h1>
<pre <pre
class="whitespace-pre-wrap break-words text-xs max-h-32 overflow-auto p-2 bg-surface-200 border border-surface-300 rounded class="whitespace-pre-wrap break-words text-xs max-h-32 overflow-auto p-2 bg-surface-200 border border-surface-300 rounded
mt-4 mt-4
print:hidden print:hidden
"> ">
{JSON.stringify($lq__event_badge_obj, null, 2)} {JSON.stringify($lq__event_badge_obj, null, 2)}
</pre> </pre>
<pre <pre
class="whitespace-pre-wrap break-words text-xs max-h-32 overflow-auto p-2 bg-surface-200 border border-surface-300 rounded class="whitespace-pre-wrap break-words text-xs max-h-32 overflow-auto p-2 bg-surface-200 border border-surface-300 rounded
mt-4 mt-4
print:hidden print:hidden
"> ">
{JSON.stringify($lq__event_badge_template_obj, null, 2)} {JSON.stringify($lq__event_badge_template_obj, null, 2)}
</pre> </pre>
</div> </div>

View File

@@ -40,7 +40,7 @@
]; ];
async function handle_submit(event: Event) { async function handle_submit(event: Event) {
event.preventDefault(); event.prevent_default();
submit_status = 'loading'; submit_status = 'loading';
const data_to_create: key_val = { const data_to_create: key_val = {
full_name_override, full_name_override,
@@ -84,11 +84,16 @@
</label> </label>
<label class="label"> <label class="label">
<span>Professional Title Override</span> <span>Professional Title Override</span>
<input type="text" bind:value={professional_title_override} class="input" /> <input
type="text"
bind:value={professional_title_override}
class="input"
/>
</label> </label>
<label class="label"> <label class="label">
<span>Affiliations Override</span> <span>Affiliations Override</span>
<textarea bind:value={affiliations_override} class="textarea" rows="2"></textarea> <textarea bind:value={affiliations_override} class="textarea" rows="2"
></textarea>
</label> </label>
<label class="label"> <label class="label">
<span>Location Override</span> <span>Location Override</span>
@@ -107,14 +112,18 @@
<select bind:value={badge_type_code} class="select"> <select bind:value={badge_type_code} class="select">
<option value="">-- Select Badge Type --</option> <option value="">-- Select Badge Type --</option>
{#each badge_type_code_li as type_code_item} {#each badge_type_code_li as type_code_item}
<option value={type_code_item.code}>{type_code_item.name}</option> <option value={type_code_item.code}
>{type_code_item.name}</option
>
{/each} {/each}
</select> </select>
</label> </label>
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
<button type="button" class="btn variant-filled-tertiary" onclick={handle_cancel} <button
>Cancel</button type="button"
class="btn variant-filled-tertiary"
onclick={handle_cancel}>Cancel</button
> >
<button <button
type="submit" type="submit"

View File

@@ -22,39 +22,61 @@
import { type Badge as BadgeType } from '$lib/ae_events/db_events'; import { type Badge as BadgeType } from '$lib/ae_events/db_events';
import { ae_loc } from '$lib/stores/ae_stores'; import { ae_loc } from '$lib/stores/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils'; import { ae_util } from '$lib/ae_utils/ae_utils';
import { LoaderCircle, Badge, Check, EyeOff, Mail, MapPin, Tags, FileSearch } from 'lucide-svelte'; import {
LoaderCircle,
Badge,
Check,
EyeOff,
Mail,
MapPin,
Tags,
FileSearch
} from 'lucide-svelte';
// Derived list of visible items (Standardized Pattern 2026-01-27) // Derived list of visible items (Standardized Pattern 2026-01-27)
let visible_badge_obj_li = $derived((() => { let visible_badge_obj_li = $derived(
const list = $lq__event_badge_obj_li; (() => {
const list = $lq__event_badge_obj_li;
if (list === undefined || list === null) return null; if (list === undefined || list === null) return null;
if (!Array.isArray(list)) return []; if (!Array.isArray(list)) return [];
const filtered = list.filter((item: any) => { const filtered = list.filter((item: any) => {
if (!item) return false; if (!item) return false;
// ADMIN/TRUSTED: See everything // ADMIN/TRUSTED: See everything
if ($ae_loc.trusted_access) return true; if ($ae_loc.trusted_access) return true;
// PUBLIC: Filter hidden // PUBLIC: Filter hidden
return !item.hide; return !item.hide;
}); });
if (log_lvl) console.log(`visible_badge_obj_li: Input=${list.length}, Output=${filtered.length}`); if (log_lvl)
return filtered; console.log(
})()); `visible_badge_obj_li: Input=${list.length}, Output=${filtered.length}`
);
return filtered;
})()
);
</script> </script>
<section class="px-1 flex flex-col gap-1 items-center justify-center space-y-1 w-full max-w-7xl mx-auto"> <section
class="px-1 flex flex-col gap-1 items-center justify-center space-y-1 w-full max-w-7xl mx-auto"
>
{#if visible_badge_obj_li === null} {#if visible_badge_obj_li === null}
<div class="flex flex-col items-center justify-center p-10 opacity-50"> <div class="flex flex-col items-center justify-center p-10 opacity-50">
<LoaderCircle size="2em" class="animate-spin mb-2" /> <LoaderCircle size="2em" class="animate-spin mb-2" />
<p>Loading badges...</p> <p>Loading badges...</p>
</div> </div>
{:else if visible_badge_obj_li.length > 0} {:else if visible_badge_obj_li.length > 0}
<header class="w-full flex flex-row gap-2 items-center justify-start mb-2 px-2"> <header
<h2 class="text-sm text-gray-500 font-normal"> Results: </h2> class="w-full flex flex-row gap-2 items-center justify-start mb-2 px-2"
<span class="badge preset-tonal-success font-bold text-lg px-3 py-1"> >
{visible_badge_obj_li.length}<span class="text-gray-400 dark:text-gray-600">&times;</span> <h2 class="text-sm text-gray-500 font-normal">Results:</h2>
<span
class="badge preset-tonal-success font-bold text-lg px-3 py-1"
>
{visible_badge_obj_li.length}<span
class="text-gray-400 dark:text-gray-600">&times;</span
>
</span> </span>
</header> </header>
@@ -68,14 +90,21 @@
hover:border-primary-500 transition-colors hover:border-primary-500 transition-colors
" "
> >
<div class="flex flex-row flex-wrap gap-2 items-center justify-between w-full"> <div
<div class="flex flex-row flex-wrap gap-2 items-center justify-start grow"> class="flex flex-row flex-wrap gap-2 items-center justify-between w-full"
>
<div
class="flex flex-row flex-wrap gap-2 items-center justify-start grow"
>
<a <a
href={`/events/${event_badge_obj?.event_id}/badges/${event_badge_obj?.event_badge_id}`} href={`/events/${event_badge_obj?.event_id}/badges/${event_badge_obj?.event_badge_id}`}
class="flex flex-row gap-2 items-center justify-start min-w-fit font-bold text-lg hover:text-primary-500" class="flex flex-row gap-2 items-center justify-start min-w-fit font-bold text-lg hover:text-primary-500"
> >
{#if event_badge_obj?.hide} {#if event_badge_obj?.hide}
<EyeOff size="1.2em" class="text-gray-400" /> <EyeOff
size="1.2em"
class="text-gray-400"
/>
{:else} {:else}
<Badge size="1.2em" /> <Badge size="1.2em" />
{/if} {/if}
@@ -86,12 +115,15 @@
{:else if event_badge_obj?.full_name} {:else if event_badge_obj?.full_name}
{event_badge_obj?.full_name} {event_badge_obj?.full_name}
{:else} {:else}
{event_badge_obj?.given_name} {event_badge_obj?.family_name} {event_badge_obj?.given_name}
{event_badge_obj?.family_name}
{/if} {/if}
</span> </span>
{#if event_badge_obj?.print_count >= 1} {#if event_badge_obj?.print_count >= 1}
<span class="badge preset-filled-success-500 flex items-center gap-1 text-xs py-0 px-1"> <span
class="badge preset-filled-success-500 flex items-center gap-1 text-xs py-0 px-1"
>
<Check size="1em" /> <Check size="1em" />
{event_badge_obj.print_count} {event_badge_obj.print_count}
</span> </span>
@@ -99,25 +131,34 @@
</a> </a>
{#if show_sensitive_fields} {#if show_sensitive_fields}
<span class="text-xs text-surface-400 flex items-center gap-1"> <span
class="text-xs text-surface-400 flex items-center gap-1"
>
<Mail size="1em" /> <Mail size="1em" />
{#if $ae_loc.trusted_access} {#if $ae_loc.trusted_access}
{event_badge_obj?.email} {event_badge_obj?.email}
{:else} {:else}
{event_badge_obj?.email?.replace(/^(.{3}).*@/, '$1...@') ?? ''} {event_badge_obj?.email?.replace(
/^(.{3}).*@/,
'$1...@'
) ?? ''}
{/if} {/if}
</span> </span>
{/if} {/if}
{#if !hide_affiliations && event_badge_obj.affiliations} {#if !hide_affiliations && event_badge_obj.affiliations}
<span class="text-xs text-surface-400 flex items-center gap-1"> <span
class="text-xs text-surface-400 flex items-center gap-1"
>
<MapPin size="1em" /> <MapPin size="1em" />
{event_badge_obj.affiliations} {event_badge_obj.affiliations}
</span> </span>
{/if} {/if}
{#if !hide_badge_type && event_badge_obj.badge_type} {#if !hide_badge_type && event_badge_obj.badge_type}
<span class="text-xs italic text-primary-500 bg-primary-500/10 px-2 rounded-token flex items-center gap-1"> <span
class="text-xs italic text-primary-500 bg-primary-500/10 px-2 rounded-token flex items-center gap-1"
>
<Tags size="1em" /> <Tags size="1em" />
{event_badge_obj.badge_type} {event_badge_obj.badge_type}
</span> </span>
@@ -138,14 +179,45 @@
<div <div
class="flex flex-row flex-wrap gap-x-4 gap-y-1 items-center justify-start w-full mt-1 p-1.5 bg-surface-200/50 dark:bg-surface-800/50 rounded text-[10px] font-mono border border-surface-300 dark:border-surface-700 opacity-80" class="flex flex-row flex-wrap gap-x-4 gap-y-1 items-center justify-start w-full mt-1 p-1.5 bg-surface-200/50 dark:bg-surface-800/50 rounded text-[10px] font-mono border border-surface-300 dark:border-surface-700 opacity-80"
> >
<span class="flex items-center gap-1"><span class="font-bold opacity-50">ID:</span> {event_badge_obj?.event_badge_id}</span> <span class="flex items-center gap-1"
<span class="flex items-center gap-1"><span class="font-bold opacity-50">CR:</span> {ae_util.iso_datetime_formatter(event_badge_obj.created_on, 'datetime_iso_12_no_seconds')}</span> ><span class="font-bold opacity-50">ID:</span>
<span class="flex items-center gap-1"><span class="font-bold opacity-50">UP:</span> {ae_util.iso_datetime_formatter(event_badge_obj.updated_on, 'datetime_iso_12_no_seconds')}</span> {event_badge_obj?.event_badge_id}</span
>
<span class="flex items-center gap-1"
><span class="font-bold opacity-50">CR:</span>
{ae_util.iso_datetime_formatter(
event_badge_obj.created_on,
'datetime_iso_12_no_seconds'
)}</span
>
<span class="flex items-center gap-1"
><span class="font-bold opacity-50">UP:</span>
{ae_util.iso_datetime_formatter(
event_badge_obj.updated_on,
'datetime_iso_12_no_seconds'
)}</span
>
{#if event_badge_obj.print_first_datetime} {#if event_badge_obj.print_first_datetime}
<span class="flex items-center gap-1"><span class="font-bold opacity-50">FP:</span> {ae_util.iso_datetime_formatter(event_badge_obj.print_first_datetime, 'datetime_iso_12_no_seconds')}</span> <span class="flex items-center gap-1"
><span class="font-bold opacity-50"
>FP:</span
>
{ae_util.iso_datetime_formatter(
event_badge_obj.print_first_datetime,
'datetime_iso_12_no_seconds'
)}</span
>
{/if} {/if}
{#if event_badge_obj.print_last_datetime} {#if event_badge_obj.print_last_datetime}
<span class="flex items-center gap-1"><span class="font-bold opacity-50">LP:</span> {ae_util.iso_datetime_formatter(event_badge_obj.print_last_datetime, 'datetime_iso_12_no_seconds')}</span> <span class="flex items-center gap-1"
><span class="font-bold opacity-50"
>LP:</span
>
{ae_util.iso_datetime_formatter(
event_badge_obj.print_last_datetime,
'datetime_iso_12_no_seconds'
)}</span
>
{/if} {/if}
</div> </div>
{/if} {/if}
@@ -153,9 +225,14 @@
{/each} {/each}
</ul> </ul>
{:else} {:else}
<div class="flex flex-col items-center justify-center p-20 opacity-50 text-center"> <div
class="flex flex-col items-center justify-center p-20 opacity-50 text-center"
>
<FileSearch size="3em" class="mb-2 opacity-20 mx-auto" /> <FileSearch size="3em" class="mb-2 opacity-20 mx-auto" />
<p>No badges found matching your criteria. Try adjusting your filters.</p> <p>
No badges found matching your criteria. Try adjusting your
filters.
</p>
</div> </div>
{/if} {/if}
</section> </section>

View File

@@ -4,10 +4,7 @@
log_lvl?: number; log_lvl?: number;
} }
let { let { event_id, log_lvl = 0 }: Props = $props();
event_id,
log_lvl = 0
}: Props = $props();
// *** Import other supporting libraries // *** Import other supporting libraries
import { import {
@@ -20,14 +17,8 @@
LoaderCircle LoaderCircle
} from 'lucide-svelte'; } from 'lucide-svelte';
import { import { ae_loc, ae_api } from '$lib/stores/ae_stores';
ae_loc, import { events_loc, events_sess } from '$lib/stores/ae_events_stores';
ae_api
} from '$lib/stores/ae_stores';
import {
events_loc,
events_sess
} from '$lib/stores/ae_events_stores';
import Element_qr_scanner_v2 from '$lib/element_qr_scanner_v2.svelte'; import Element_qr_scanner_v2 from '$lib/element_qr_scanner_v2.svelte';
import { ae_util } from '$lib/ae_utils/ae_utils'; import { ae_util } from '$lib/ae_utils/ae_utils';
@@ -77,7 +68,9 @@
} }
</script> </script>
<div class="ae_group filters_and_search flex flex-col items-center justify-center gap-2 w-full"> <div
class="ae_group filters_and_search flex flex-col items-center justify-center gap-2 w-full"
>
{#if $events_sess.badges.show_form__search} {#if $events_sess.badges.show_form__search}
<form <form
onsubmit={prevent_default(() => { onsubmit={prevent_default(() => {
@@ -86,7 +79,9 @@
autocomplete="off" autocomplete="off"
class="search_form flex flex-row flex-wrap gap-1 items-center justify-center w-full max-w-7xl px-2 md:px-12 py-2 preset-tonal-success rounded-lg shadow-sm" class="search_form flex flex-row flex-wrap gap-1 items-center justify-center w-full max-w-7xl px-2 md:px-12 py-2 preset-tonal-success rounded-lg shadow-sm"
> >
<div class="flex flex-col md:flex-row items-center justify-center gap-1 grow"> <div
class="flex flex-col md:flex-row items-center justify-center gap-1 grow"
>
{#if $ae_loc.trusted_access} {#if $ae_loc.trusted_access}
<select <select
bind:value={$events_loc.badges.search_badge_type_code} bind:value={$events_loc.badges.search_badge_type_code}
@@ -95,7 +90,9 @@
> >
<option value="">-- All Badge Types --</option> <option value="">-- All Badge Types --</option>
{#each badge_type_code_li as badge_type_code} {#each badge_type_code_li as badge_type_code}
<option value={badge_type_code.code}>{badge_type_code.name}</option> <option value={badge_type_code.code}
>{badge_type_code.name}</option
>
{/each} {/each}
</select> </select>
@@ -119,11 +116,19 @@
<option value="name_desc">Name DESC</option> <option value="name_desc">Name DESC</option>
<option value="updated_desc">Updated DESC</option> <option value="updated_desc">Updated DESC</option>
<option value="updated_asc">Updated ASC</option> <option value="updated_asc">Updated ASC</option>
<option value="print_count_desc">Print Count DESC</option> <option value="print_count_desc"
<option value="print_first_desc">First Printed DESC</option> >Print Count DESC</option
<option value="print_last_desc">Last Printed DESC</option> >
<option value="print_first_desc"
>First Printed DESC</option
>
<option value="print_last_desc"
>Last Printed DESC</option
>
<option value="badge_type_asc">Badge Type ASC</option> <option value="badge_type_asc">Badge Type ASC</option>
<option value="affiliations_asc">Affiliations ASC</option> <option value="affiliations_asc"
>Affiliations ASC</option
>
</select> </select>
<input <input
@@ -131,7 +136,11 @@
placeholder="affiliations" placeholder="affiliations"
bind:value={$events_loc.badges.qry_affiliations} bind:value={$events_loc.badges.qry_affiliations}
onkeyup={(e) => { onkeyup={(e) => {
if (e.key === 'Enter' || ($events_loc.badges.qry_affiliations?.length ?? 0) >= 3) { if (
e.key === 'Enter' ||
($events_loc.badges.qry_affiliations?.length ??
0) >= 3
) {
handle_search_trigger(); handle_search_trigger();
} }
}} }}
@@ -169,8 +178,11 @@
Search Search
</button> </button>
<button type="button" <button
class:hidden={!$events_loc.badges.fulltext_search_qry_str && !$events_loc.badges.search_badge_type_code && $events_loc.badges.qry_printed_status === 'all'} type="button"
class:hidden={!$events_loc.badges.fulltext_search_qry_str &&
!$events_loc.badges.search_badge_type_code &&
$events_loc.badges.qry_printed_status === 'all'}
onclick={() => { onclick={() => {
$events_loc.badges.fulltext_search_qry_str = ''; $events_loc.badges.fulltext_search_qry_str = '';
$events_loc.badges.search_badge_type_code = ''; $events_loc.badges.search_badge_type_code = '';
@@ -187,7 +199,9 @@
</div> </div>
</form> </form>
{:else if $events_sess.badges.show_form__scan} {:else if $events_sess.badges.show_form__scan}
<div class="w-full max-w-2xl mx-auto p-4 bg-surface-100-900 rounded-lg shadow-lg"> <div
class="w-full max-w-2xl mx-auto p-4 bg-surface-100-900 rounded-lg shadow-lg"
>
<Element_qr_scanner_v2 <Element_qr_scanner_v2
bind:start_qr_scanner={$events_sess.badges.qr_scan_start} bind:start_qr_scanner={$events_sess.badges.qr_scan_start}
on:qr_scan_result={handle_qr_scan_result} on:qr_scan_result={handle_qr_scan_result}
@@ -195,9 +209,12 @@
</div> </div>
{/if} {/if}
<div class="flex flex-row flex-wrap items-center justify-center gap-2 opacity-70 hover:opacity-100 transition-all"> <div
class="flex flex-row flex-wrap items-center justify-center gap-2 opacity-70 hover:opacity-100 transition-all"
>
{#if $events_sess.badges.show_form__search} {#if $events_sess.badges.show_form__search}
<button type="button" <button
type="button"
onclick={() => { onclick={() => {
$events_sess.badges.show_form__search = false; $events_sess.badges.show_form__search = false;
$events_sess.badges.show_form__scan = true; $events_sess.badges.show_form__scan = true;
@@ -209,7 +226,8 @@
QR Scan QR Scan
</button> </button>
{:else} {:else}
<button type="button" <button
type="button"
onclick={() => { onclick={() => {
$events_sess.badges.show_form__search = true; $events_sess.badges.show_form__search = true;
$events_sess.badges.show_form__scan = false; $events_sess.badges.show_form__scan = false;
@@ -222,7 +240,8 @@
</button> </button>
{/if} {/if}
<button type="button" <button
type="button"
onclick={() => { onclick={() => {
$events_loc.badges.use_id_li = !$events_loc.badges.use_id_li; $events_loc.badges.use_id_li = !$events_loc.badges.use_id_li;
handle_search_trigger(); handle_search_trigger();
@@ -239,7 +258,9 @@
</button> </button>
{#if $ae_loc.edit_mode} {#if $ae_loc.edit_mode}
<label class="flex items-center gap-1 cursor-pointer bg-surface-200-800 px-2 py-1 rounded-token text-xs font-semibold"> <label
class="flex items-center gap-1 cursor-pointer bg-surface-200-800 px-2 py-1 rounded-token text-xs font-semibold"
>
<span> Remote First </span> <span> Remote First </span>
<input <input
type="checkbox" type="checkbox"
@@ -250,4 +271,4 @@
</label> </label>
{/if} {/if}
</div> </div>
</div> </div>

View File

@@ -48,7 +48,7 @@
} }
async function handle_upload(event: Event) { async function handle_upload(event: Event) {
event.preventDefault(); event.prevent_default();
if (!selected_file) { if (!selected_file) {
upload_message = 'Please select a file first.'; upload_message = 'Please select a file first.';
upload_status = 'error'; upload_status = 'error';
@@ -72,9 +72,12 @@
for (const data_kv of badge_data_li) { for (const data_kv of badge_data_li) {
// Simple mapping, customize as needed // Simple mapping, customize as needed
const badge_payload: key_val = { const badge_payload: key_val = {
full_name_override: data_kv.full_name || data_kv.name || null, full_name_override:
professional_title_override: data_kv.professional_title || null, data_kv.full_name || data_kv.name || null,
affiliations_override: data_kv.affiliations || data_kv.company || null, professional_title_override:
data_kv.professional_title || null,
affiliations_override:
data_kv.affiliations || data_kv.company || null,
location_override: data_kv.location || null, location_override: data_kv.location || null,
email: data_kv.email || null, email: data_kv.email || null,
allow_tracking: allow_tracking:
@@ -118,11 +121,17 @@
<form onsubmit={handle_upload} class="p-4 space-y-4"> <form onsubmit={handle_upload} class="p-4 space-y-4">
<h3 class="h3">Upload Badge List (CSV)</h3> <h3 class="h3">Upload Badge List (CSV)</h3>
<p>Upload a CSV file containing badge data. The first row should be headers.</p>
<p> <p>
Supported headers (case-sensitive): <code>full_name</code>, <code>name</code>, Upload a CSV file containing badge data. The first row should be
<code>professional_title</code>, <code>affiliations</code>, <code>company</code>, headers.
<code>location</code>, <code>email</code>, <code>allow_tracking</code> (true/false or 1/0), </p>
<p>
Supported headers (case-sensitive): <code>full_name</code>,
<code>name</code>,
<code>professional_title</code>, <code>affiliations</code>,
<code>company</code>,
<code>location</code>, <code>email</code>, <code>allow_tracking</code>
(true/false or 1/0),
<code>badge_type_code</code>. <code>badge_type_code</code>.
</p> </p>
@@ -142,21 +151,32 @@
{/if} {/if}
{#if upload_status !== 'idle'} {#if upload_status !== 'idle'}
<div class="alert variant-soft-{upload_status === 'error' ? 'error' : 'info'}"> <div
class="alert variant-soft-{upload_status === 'error'
? 'error'
: 'info'}"
>
<p>{upload_message}</p> <p>{upload_message}</p>
{#if upload_status === 'processing' || upload_status === 'loading'} {#if upload_status === 'processing' || upload_status === 'loading'}
<progress class="progress" value={processed_badges_count} max={total_badges_in_file} <progress
class="progress"
value={processed_badges_count}
max={total_badges_in_file}
></progress> ></progress>
<p>Processed: {processed_badges_count} / {total_badges_in_file}</p> <p>
Processed: {processed_badges_count} / {total_badges_in_file}
</p>
{/if} {/if}
</div> </div>
{/if} {/if}
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
<button type="button" <button
type="button"
class="btn variant-filled-tertiary" class="btn variant-filled-tertiary"
onclick={handle_cancel} onclick={handle_cancel}
disabled={upload_status === 'loading' || upload_status === 'processing'}>Cancel</button disabled={upload_status === 'loading' ||
upload_status === 'processing'}>Cancel</button
> >
<button <button
type="submit" type="submit"

View File

@@ -13,14 +13,21 @@
let { data }: Props = $props(); let { data }: Props = $props();
let event_id: string = data.params.event_id; let event_id: string = data.params.event_id;
let printed_status_filter: string | null = data.url.searchParams.get('printed_status'); let printed_status_filter: string | null =
let badge_type_code_filter: string | null = data.url.searchParams.get('badge_type_code'); data.url.searchParams.get('printed_status');
let badge_type_code_filter: string | null =
data.url.searchParams.get('badge_type_code');
let lq__filtered_badges = $derived( let lq__filtered_badges = $derived(
liveQuery(async () => { liveQuery(async () => {
const filters: { printed_status?: "all" | "printed" | "not_printed"; type_code?: string } = {}; const filters: {
if (printed_status_filter) filters.printed_status = printed_status_filter as any; printed_status?: 'all' | 'printed' | 'not_printed';
if (badge_type_code_filter) filters.type_code = badge_type_code_filter; type_code?: string;
} = {};
if (printed_status_filter)
filters.printed_status = printed_status_filter as any;
if (badge_type_code_filter)
filters.type_code = badge_type_code_filter;
// Fetch badges using the search function, with a high limit for bulk printing // Fetch badges using the search function, with a high limit for bulk printing
const result = await events_func.search__event_badge({ const result = await events_func.search__event_badge({

View File

@@ -20,11 +20,12 @@
let lq__badge_templates = $derived( let lq__badge_templates = $derived(
liveQuery(async () => { liveQuery(async () => {
const result = await events_func.load_ae_obj_li__event_badge_template({ const result =
api_cfg: $ae_api, await events_func.load_ae_obj_li__event_badge_template({
event_id: event_id, api_cfg: $ae_api,
log_lvl: 0 event_id: event_id,
}); log_lvl: 0
});
return result || []; return result || [];
}) })
); );
@@ -80,7 +81,11 @@
<h1 class="h1">Badge Templates</h1> <h1 class="h1">Badge Templates</h1>
<div class="my-4 flex justify-end"> <div class="my-4 flex justify-end">
<button type="button" class="btn btn-primary" onclick={() => (show_create_template_modal = true)}> <button
type="button"
class="btn btn-primary"
onclick={() => (show_create_template_modal = true)}
>
<span class="fas fa-plus mr-2"></span> Add New Template <span class="fas fa-plus mr-2"></span> Add New Template
</button> </button>
</div> </div>
@@ -90,20 +95,28 @@
<div class="card p-4"> <div class="card p-4">
<ul class="list-group"> <ul class="list-group">
{#each $lq__badge_templates as template (template.event_badge_template_id_random)} {#each $lq__badge_templates as template (template.event_badge_template_id_random)}
<li class="list-group-item flex justify-between items-center"> <li
class="list-group-item flex justify-between items-center"
>
<span>{template.name}</span> <span>{template.name}</span>
<div> <div>
<button type="button" <button
type="button"
class="btn btn-sm variant-filled-primary" class="btn btn-sm variant-filled-primary"
onclick={() => onclick={() =>
edit_template(template.event_badge_template_id_random)} edit_template(
template.event_badge_template_id_random
)}
> >
<span class="fas fa-edit"></span> Edit <span class="fas fa-edit"></span> Edit
</button> </button>
<button type="button" <button
type="button"
class="btn btn-sm variant-filled-error ml-2" class="btn btn-sm variant-filled-error ml-2"
onclick={() => onclick={() =>
delete_template(template.event_badge_template_id_random)} delete_template(
template.event_badge_template_id_random
)}
> >
<span class="fas fa-trash"></span> Delete <span class="fas fa-trash"></span> Delete
</button> </button>
@@ -113,7 +126,10 @@
</ul> </ul>
</div> </div>
{:else} {:else}
<p>No badge templates found for this event. Click "Add New Template" to create one.</p> <p>
No badge templates found for this event. Click "Add New
Template" to create one.
</p>
{/if} {/if}
{:else} {:else}
<p>Loading badge templates...</p> <p>Loading badge templates...</p>

View File

@@ -12,8 +12,8 @@
oncancel?: () => void; oncancel?: () => void;
} }
let { let {
event_id, event_id,
template_id = null, template_id = null,
onsuccess, onsuccess,
onerror, onerror,
@@ -22,7 +22,7 @@
function prevent_default(fn: () => void) { function prevent_default(fn: () => void) {
return function (event: Event) { return function (event: Event) {
event.prevent_default(); event.preventDefault();
fn(); fn();
}; };
} }
@@ -57,17 +57,19 @@
async function load_template(id: string) { async function load_template(id: string) {
submit_status = 'loading'; submit_status = 'loading';
try { try {
const template_obj = await events_func.load_ae_obj_id__event_badge_template({ const template_obj =
api_cfg: $ae_api, await events_func.load_ae_obj_id__event_badge_template({
event_badge_template_id: id api_cfg: $ae_api,
}); event_badge_template_id: id
});
if (template_obj) { if (template_obj) {
name = template_obj.name || ''; name = template_obj.name || '';
header_path = template_obj.header_path || ''; header_path = template_obj.header_path || '';
logo_path = template_obj.logo_path || ''; logo_path = template_obj.logo_path || '';
header_row_1 = template_obj.header_row_1 || ''; header_row_1 = template_obj.header_row_1 || '';
header_row_2 = template_obj.header_row_2 || ''; header_row_2 = template_obj.header_row_2 || '';
secondary_header_path = template_obj.secondary_header_path || ''; secondary_header_path =
template_obj.secondary_header_path || '';
footer_text = template_obj.footer_text || ''; footer_text = template_obj.footer_text || '';
show_qr_front = template_obj.show_qr_front ?? true; show_qr_front = template_obj.show_qr_front ?? true;
show_qr_back = template_obj.show_qr_back ?? true; show_qr_back = template_obj.show_qr_back ?? true;
@@ -159,11 +161,13 @@
</label> </label>
<label class="label"> <label class="label">
<span>Header Row 1 Text (HTML allowed)</span> <span>Header Row 1 Text (HTML allowed)</span>
<textarea bind:value={header_row_1} class="textarea" rows="2"></textarea> <textarea bind:value={header_row_1} class="textarea" rows="2"
></textarea>
</label> </label>
<label class="label"> <label class="label">
<span>Header Row 2 Text (HTML allowed)</span> <span>Header Row 2 Text (HTML allowed)</span>
<textarea bind:value={header_row_2} class="textarea" rows="2"></textarea> <textarea bind:value={header_row_2} class="textarea" rows="2"
></textarea>
</label> </label>
<label class="label"> <label class="label">
<span>Secondary Header Path (URL, back of badge)</span> <span>Secondary Header Path (URL, back of badge)</span>
@@ -195,19 +199,23 @@
<label class="label"> <label class="label">
<span>Ticket 1 Text (HTML allowed)</span> <span>Ticket 1 Text (HTML allowed)</span>
<textarea bind:value={ticket_1_text} class="textarea" rows="2"></textarea> <textarea bind:value={ticket_1_text} class="textarea" rows="2"
></textarea>
</label> </label>
<label class="label"> <label class="label">
<span>Ticket 2 Text (HTML allowed)</span> <span>Ticket 2 Text (HTML allowed)</span>
<textarea bind:value={ticket_2_text} class="textarea" rows="2"></textarea> <textarea bind:value={ticket_2_text} class="textarea" rows="2"
></textarea>
</label> </label>
<label class="label"> <label class="label">
<span>Ticket 3 Text (HTML allowed)</span> <span>Ticket 3 Text (HTML allowed)</span>
<textarea bind:value={ticket_3_text} class="textarea" rows="2"></textarea> <textarea bind:value={ticket_3_text} class="textarea" rows="2"
></textarea>
</label> </label>
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
<button type="button" <button
type="button"
class="btn variant-filled-tertiary" class="btn variant-filled-tertiary"
onclick={handle_cancel} onclick={handle_cancel}
disabled={submit_status === 'loading'}>Cancel</button disabled={submit_status === 'loading'}>Cancel</button