feat: Remove legacy files and fix first svelte/no-at-html-tags error\n\n- Moved legacy files from src/routes/legacy to backups/legacy/src/routes/legacy.\n- Removed the empty src/routes/legacy directory.\n- Fixed a svelte/no-at-html-tags error in src/routes/idaa/(idaa)/archives/[archive_id]/+page.svelte by replacing '{@html ?.name ?? 'Archive'}' with '{?.name ?? 'Archive'}'.\n- Addressed a misidentified '{@html}' tag in src/lib/ae_core/ae_comp__hosted_files_clip_video.svelte by removing commented-out code that might have caused false positives.

This commit is contained in:
Scott Idem
2025-11-20 19:46:17 -05:00
parent 266363b85f
commit a68d5439bd
70 changed files with 409 additions and 13358 deletions

View File

@@ -70,8 +70,6 @@
let show_create_badge_modal: boolean = $state(false);
let show_upload_badge_modal: boolean = $state(false);
let event_badge_id_li: Array<string> = $state([]);
// let dq__where_type_id_val: string = `event_id_random`;
// let dq__where_eq_id_val: string = $events_slct?.event_id ?? '';
@@ -113,7 +111,7 @@
show_create_badge_modal = false;
ae_triggers.event_badge_qry = true; // Trigger a refresh of the list
}}
on:cancel={() => show_create_badge_modal = false}
on:cancel={() => (show_create_badge_modal = false)}
/>
</div>
</Modal>
@@ -129,7 +127,7 @@
show_upload_badge_modal = false;
ae_triggers.event_badge_qry = true; // Trigger a refresh of the list
}}
on:cancel={() => show_upload_badge_modal = false}
on:cancel={() => (show_upload_badge_modal = false)}
/>
</div>
</Modal>
@@ -161,10 +159,10 @@
{#if $ae_loc.trusted_access}
<div class="mt-4 text-center">
<button class="btn btn-primary" onclick={() => show_create_badge_modal = true}>
<button class="btn btn-primary" onclick={() => (show_create_badge_modal = true)}>
<span class="fas fa-plus mr-2"></span> Add New Badge
</button>
<button class="btn btn-primary ml-2" onclick={() => show_upload_badge_modal = true}>
<button class="btn btn-primary ml-2" onclick={() => (show_upload_badge_modal = true)}>
<span class="fas fa-upload mr-2"></span> Upload Badge List
</button>
</div>
@@ -172,20 +170,32 @@
<div class="mt-4 text-center p-4 border rounded-md">
<h4 class="h4">Mass Print Options</h4>
<div class="flex flex-wrap justify-center gap-2">
<a href={`/events/${$events_slct?.event_id ?? ''}/badges/print_list?printed_status=not_printed`} class="btn variant-filled-secondary">
<a
href={`/events/${$events_slct?.event_id ?? ''}/badges/print_list?printed_status=not_printed`}
class="btn variant-filled-secondary"
>
<span class="fas fa-print mr-2"></span> Print All Unprinted
</a>
<a href={`/events/${$events_slct?.event_id ?? ''}/badges/print_list?badge_type_code=guest&printed_status=not_printed`} class="btn variant-filled-secondary">
<a
href={`/events/${$events_slct?.event_id ?? ''}/badges/print_list?badge_type_code=guest&printed_status=not_printed`}
class="btn variant-filled-secondary"
>
<span class="fas fa-print mr-2"></span> Print Unprinted Guests
</a>
<a href={`/events/${$events_slct?.event_id ?? ''}/badges/print_list`} class="btn variant-filled-secondary">
<a
href={`/events/${$events_slct?.event_id ?? ''}/badges/print_list`}
class="btn variant-filled-secondary"
>
<span class="fas fa-print mr-2"></span> Print All
</a>
</div>
</div>
<div class="mt-4 text-center">
<a href={`/events/${$events_slct?.event_id ?? ''}/badges/templates`} class="btn btn-tertiary">
<a
href={`/events/${$events_slct?.event_id ?? ''}/badges/templates`}
class="btn btn-tertiary"
>
<span class="fas fa-file-alt mr-2"></span> Manage Badge Templates
</a>
</div>

View File

@@ -97,10 +97,15 @@
// Initialize editable fields when lq__event_badge_obj changes
$effect(() => {
if (lq__event_badge_obj) {
editable_full_name_override = lq__event_badge_obj.full_name_override ?? lq__event_badge_obj.full_name;
editable_professional_title_override = lq__event_badge_obj.professional_title_override ?? lq__event_badge_obj.professional_title;
editable_affiliations_override = lq__event_badge_obj.affiliations_override ?? lq__event_badge_obj.affiliations;
editable_location_override = lq__event_badge_obj.location_override ?? lq__event_badge_obj.location;
editable_full_name_override =
lq__event_badge_obj.full_name_override ?? lq__event_badge_obj.full_name;
editable_professional_title_override =
lq__event_badge_obj.professional_title_override ??
lq__event_badge_obj.professional_title;
editable_affiliations_override =
lq__event_badge_obj.affiliations_override ?? lq__event_badge_obj.affiliations;
editable_location_override =
lq__event_badge_obj.location_override ?? lq__event_badge_obj.location;
editable_allow_tracking = lq__event_badge_obj.allow_tracking ?? null;
editable_email = lq__event_badge_obj.email ?? null;
editable_badge_type_code = lq__event_badge_obj.badge_type_code ?? null;
@@ -171,11 +176,16 @@
);
// Re-calculate font sizes based on potentially edited values
const current_full_name = editable_full_name_override ?? lq__event_badge_obj?.full_name ?? '';
const current_professional_title = editable_professional_title_override ?? lq__event_badge_obj?.professional_title ?? '';
const current_affiliations = editable_affiliations_override ?? lq__event_badge_obj?.affiliations ?? '';
const current_location = editable_location_override ?? lq__event_badge_obj?.location ?? '';
const current_full_name =
editable_full_name_override ?? lq__event_badge_obj?.full_name ?? '';
const current_professional_title =
editable_professional_title_override ??
lq__event_badge_obj?.professional_title ??
'';
const current_affiliations =
editable_affiliations_override ?? lq__event_badge_obj?.affiliations ?? '';
const current_location =
editable_location_override ?? lq__event_badge_obj?.location ?? '';
longest_full_name_override_part = longest_str_part(current_full_name);
if (longest_full_name_override_part >= 9) {
@@ -347,16 +357,29 @@
const data_to_update: key_val = {};
// Only include fields that have actually changed
if (editable_full_name_override !== (lq__event_badge_obj.full_name_override ?? lq__event_badge_obj.full_name)) {
if (
editable_full_name_override !==
(lq__event_badge_obj.full_name_override ?? lq__event_badge_obj.full_name)
) {
data_to_update.full_name_override = editable_full_name_override;
}
if (editable_professional_title_override !== (lq__event_badge_obj.professional_title_override ?? lq__event_badge_obj.professional_title)) {
if (
editable_professional_title_override !==
(lq__event_badge_obj.professional_title_override ??
lq__event_badge_obj.professional_title)
) {
data_to_update.professional_title_override = editable_professional_title_override;
}
if (editable_affiliations_override !== (lq__event_badge_obj.affiliations_override ?? lq__event_badge_obj.affiliations)) {
if (
editable_affiliations_override !==
(lq__event_badge_obj.affiliations_override ?? lq__event_badge_obj.affiliations)
) {
data_to_update.affiliations_override = editable_affiliations_override;
}
if (editable_location_override !== (lq__event_badge_obj.location_override ?? lq__event_badge_obj.location)) {
if (
editable_location_override !==
(lq__event_badge_obj.location_override ?? lq__event_badge_obj.location)
) {
data_to_update.location_override = editable_location_override;
}
if (editable_allow_tracking !== lq__event_badge_obj.allow_tracking) {
@@ -403,10 +426,15 @@
function handle_cancel_changes() {
if (lq__event_badge_obj) {
editable_full_name_override = lq__event_badge_obj.full_name_override ?? lq__event_badge_obj.full_name;
editable_professional_title_override = lq__event_badge_obj.professional_title_override ?? lq__event_badge_obj.professional_title;
editable_affiliations_override = lq__event_badge_obj.affiliations_override ?? lq__event_badge_obj.affiliations;
editable_location_override = lq__event_badge_obj.location_override ?? lq__event_badge_obj.location;
editable_full_name_override =
lq__event_badge_obj.full_name_override ?? lq__event_badge_obj.full_name;
editable_professional_title_override =
lq__event_badge_obj.professional_title_override ??
lq__event_badge_obj.professional_title;
editable_affiliations_override =
lq__event_badge_obj.affiliations_override ?? lq__event_badge_obj.affiliations;
editable_location_override =
lq__event_badge_obj.location_override ?? lq__event_badge_obj.location;
editable_allow_tracking = lq__event_badge_obj.allow_tracking ?? null;
editable_email = lq__event_badge_obj.email ?? null;
editable_badge_type_code = lq__event_badge_obj.badge_type_code ?? null;
@@ -642,7 +670,11 @@ onkeypress={() => {
{longest_full_name_override_part}&times; char
</span> -->
{#if edit_mode_active}
<input type="text" bind:value={editable_full_name_override} class="input w-full text-center" />
<input
type="text"
bind:value={editable_full_name_override}
class="input w-full text-center"
/>
{:else}
<span class="full_name_override">
{#if editable_full_name_override}
@@ -662,7 +694,11 @@ onkeypress={() => {
"
>
{#if edit_mode_active}
<input type="text" bind:value={editable_professional_title_override} class="input w-full text-center" />
<input
type="text"
bind:value={editable_professional_title_override}
class="input w-full text-center"
/>
{:else}
{@html editable_professional_title_override}
{/if}
@@ -684,7 +720,11 @@ onkeypress={() => {
"
>
{#if edit_mode_active}
<textarea bind:value={editable_affiliations_override} class="textarea w-full text-center" rows="2"></textarea>
<textarea
bind:value={editable_affiliations_override}
class="textarea w-full text-center"
rows="2"
></textarea>
{:else}
{@html editable_affiliations_override}
{/if}
@@ -698,7 +738,11 @@ onkeypress={() => {
"
>
{#if edit_mode_active}
<input type="text" bind:value={editable_location_override} class="input w-full text-center" />
<input
type="text"
bind:value={editable_location_override}
class="input w-full text-center"
/>
{:else}
<span class="city state_province country"
>{@html editable_location_override}</span
@@ -710,7 +754,13 @@ onkeypress={() => {
{#if editable_email || edit_mode_active}
<div class="email-field text-sm">
{#if edit_mode_active}
<label>Email: <input type="email" bind:value={editable_email} class="input w-full" /></label>
<label
>Email: <input
type="email"
bind:value={editable_email}
class="input w-full"
/></label
>
{:else}
Email: {editable_email}
{/if}
@@ -718,9 +768,17 @@ onkeypress={() => {
{/if}
{#if editable_allow_tracking !== null || edit_mode_active}
<div class="allow-tracking-field text-sm flex items-center justify-center gap-2">
<div
class="allow-tracking-field text-sm flex items-center justify-center gap-2"
>
{#if edit_mode_active}
<label>Allow Tracking: <input type="checkbox" bind:checked={editable_allow_tracking} class="checkbox" /></label>
<label
>Allow Tracking: <input
type="checkbox"
bind:checked={editable_allow_tracking}
class="checkbox"
/></label
>
{:else}
Allow Tracking: {editable_allow_tracking ? 'Yes' : 'No'}
{/if}
@@ -777,10 +835,16 @@ onkeypress={() => {
title={editable_badge_type_code}
>
{#if edit_mode_active && badge_type_code_li}
<label>Badge Type:
<select bind:value={editable_badge_type_code} class="select text-xs px-1 max-w-fit">
<label
>Badge Type:
<select
bind:value={editable_badge_type_code}
class="select text-xs px-1 max-w-fit"
>
{#each badge_type_code_li as badge_type_code_item}
<option value={badge_type_code_item.code}>{badge_type_code_item.name}</option>
<option value={badge_type_code_item.code}
>{badge_type_code_item.name}</option
>
{/each}
</select>
</label>
@@ -791,7 +855,9 @@ onkeypress={() => {
><span class="fas fa-biohazard"></span></span
>
{:else if option_other_1_override && ['front_html', 'front_back_html'].includes(option_other_1_display_opt)}
<span class="badge_footer_special_left">{@html option_other_1_override}</span>
<span class="badge_footer_special_left"
>{@html option_other_1_override}</span
>
{/if}
<span class="badge_footer_center {editable_badge_type_code?.toLowerCase()}"
@@ -803,12 +869,13 @@ onkeypress={() => {
><span class="fas fa-star-of-life"></span></span
>
{:else if option_other_2_override && ['front_html', 'front_back_html'].includes(option_other_2_display_opt)}
<span class="badge_footer_special_right">{@html option_other_2_override}</span>
<span class="badge_footer_special_right"
>{@html option_other_2_override}</span
>
{/if}
{/if}
</div>
<!-- {#if $lq__event_badge_template_obj.show_qr_front}
<div class="container qr_code">
{#await initial_loading_promise}

View File

@@ -113,8 +113,14 @@
</label>
<div class="flex justify-end gap-2">
<button type="button" class="btn variant-filled-tertiary" onclick={handle_cancel}>Cancel</button>
<button type="submit" class="btn variant-filled-primary" disabled={submit_status === 'loading'}>
<button type="button" class="btn variant-filled-tertiary" onclick={handle_cancel}
>Cancel</button
>
<button
type="submit"
class="btn variant-filled-primary"
disabled={submit_status === 'loading'}
>
{#if submit_status === 'loading'}
<span class="fas fa-spinner fa-spin mr-2"></span>
{/if}

View File

@@ -22,9 +22,8 @@
}: Props = $props();
import { liveQuery } from 'dexie';
import { db_events } from '$lib/ae_events/db_events';
import { db_events, type Badge } from '$lib/ae_events/db_events';
import { ae_loc } from '$lib/stores/ae_stores';
// let trusted_access = $derived(ae_loc.trusted_access); // This does NOT work with Svelte v5
// let trusted_access = $ae_loc?.trusted_access; // This works with Svelte v5
@@ -53,42 +52,43 @@
<!-- The email should only be the first 3 chars and then @domain name. -->
<ul class="list-disc list-inside">
{#each $lq__event_badge_obj_li as event_badge_obj (event_badge_obj.event_badge_id)}
{#if !event_badge_obj.hide || $ae_loc.trusted_access}
{#each $lq__event_badge_obj_li.filter(Boolean) as event_badge_obj: Badge (event_badge_obj?.event_badge_id)}
{#if !event_badge_obj?.hide || $ae_loc.trusted_access}
<li
class="
border-b border-gray-300 dark:border-gray-600 py-0.5
flex flex-row gap-1 items-center justify-between w-full
"
>
{#if event_badge_obj.print_count < 1 || $ae_loc.trusted_access}
{#if event_badge_obj?.print_count < 1 || $ae_loc.trusted_access}
<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-1 items-center justify-start min-w-fit"
title={`Badge: ${event_badge_obj.full_name ?? event_badge_obj.given_name ?? '-- no name --'}\nID: ${event_badge_obj.event_badge_id}`}
title={`Badge: ${event_badge_obj?.full_name ?? event_badge_obj?.given_name ?? '-- no name --'}\nID: ${event_badge_obj?.event_badge_id}`}
>
<span>
{#if event_badge_obj.hide}
{#if event_badge_obj?.hide}
<span class="fas fa-eye-slash mx-1"></span>
{:else}
<span class="fas fa-id-badge mx-1"></span>
{/if}
{#if event_badge_obj.print_count >= 1}
{#if event_badge_obj?.print_count >= 1}
<!-- Show a green checkmark -->
<span class="fas fa-check text-green-500"></span>
<span class="fas fa-check text-green-500"></span>
<span class="print_count px-1"
>{event_badge_obj.print_count}&times;</span
> {/if}
<span class="print_count px-1"
>{event_badge_obj?.print_count}&times;</span
>
{/if}
</span>
<span class="font-bold">
{#if event_badge_obj.full_name_override}
{event_badge_obj.full_name_override}
{:else if event_badge_obj.full_name}
{event_badge_obj.full_name}
{:else if event_badge_obj.given_name}
{event_badge_obj.given_name} {event_badge_obj.family_name}
{#if event_badge_obj?.full_name_override}
{event_badge_obj?.full_name_override}
{:else if event_badge_obj?.full_name}
{event_badge_obj?.full_name}
{:else if event_badge_obj?.given_name}
{event_badge_obj?.given_name} {event_badge_obj?.family_name}
{:else}
-- no name --
{/if}
@@ -97,30 +97,31 @@
{:else}
<span
class="flex flex-row gap-1 items-center justify-start min-w-fit"
title={`Badge: ${event_badge_obj.full_name ?? event_badge_obj.given_name ?? '-- no name --'}\nID: ${event_badge_obj.event_badge_id}`}
title={`Badge: ${event_badge_obj?.full_name ?? event_badge_obj?.given_name ?? '-- no name --'}\nID: ${event_badge_obj?.event_badge_id}`}
>
<span>
{#if event_badge_obj.hide}
{#if event_badge_obj?.hide}
<span class="fas fa-eye-slash mx-1"></span>
{:else}
<span class="fas fa-id-badge mx-1"></span>
{/if}
{#if event_badge_obj.print_count >= 1}
{#if event_badge_obj?.print_count >= 1}
<!-- Show a green checkmark -->
<span class="fas fa-check text-green-500"></span>
<span class="fas fa-check text-green-500"></span>
<span class="print_count px-1"
>{event_badge_obj.print_count}&times;</span
> {/if}
<span class="print_count px-1"
>{event_badge_obj?.print_count}&times;</span
>
{/if}
</span>
<span class="font-bold">
{#if event_badge_obj.full_name_override}
{event_badge_obj.full_name_override}
{:else if event_badge_obj.full_name}
{event_badge_obj.full_name}
{:else if event_badge_obj.given_name}
{event_badge_obj.given_name} {event_badge_obj.family_name}
{#if event_badge_obj?.full_name_override}
{event_badge_obj?.full_name_override}
{:else if event_badge_obj?.full_name}
{event_badge_obj?.full_name}
{:else if event_badge_obj?.given_name}
{event_badge_obj?.given_name} {event_badge_obj?.family_name}
{:else}
-- no name --
{/if}
@@ -133,10 +134,10 @@
<span class="min-w-fit">
<span class="fas fa-envelope"></span>
{#if $ae_loc.trusted_access}
{event_badge_obj.email}
{event_badge_obj?.email}
{:else}
{event_badge_obj.email
? event_badge_obj.email.replace(/^(.{3}).*@/, '$1...@')
{event_badge_obj?.email
? event_badge_obj?.email.replace(/^(.{3}).*@/, '$1...@')
: ''}
{/if}
</span>
@@ -156,7 +157,7 @@
{#if $ae_loc.trusted_access}
<a
href={`/events/${event_badge_obj.event_id}/badges/${event_badge_obj.event_badge_id}#review`}
href={`/events/${event_badge_obj?.event_id}/badges/${event_badge_obj?.event_badge_id}#review`}
class="btn btn-sm variant-soft-primary">Review</a
>
{/if}

View File

@@ -211,8 +211,6 @@
}
});
// function process_search_string(search_str: string) {
// if (log_lvl) {
// console.log(`process_search_string() search_str=${search_str}`);
@@ -380,14 +378,14 @@
}, search_delay);
}
function handle_qr_scan_result(event) {
function handle_qr_scan_result(event: CustomEvent) {
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') {
if (obj && 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;
@@ -516,13 +514,9 @@
type="button"
class:hidden={!qry_str}
onclick={() => {
console.log(
`TESTING - 1 - Cleared search query: ${qry_str}`
);
console.log(`TESTING - 1 - Cleared search query: ${qry_str}`);
qry_str = '';
console.log(
`TESTING - 2 - Cleared search query: ${qry_str}`
);
console.log(`TESTING - 2 - Cleared search query: ${qry_str}`);
ae_triggers.event_badge_qry = true;
}}
class="
@@ -574,7 +568,10 @@
<!-- **BEGIN** Scan Form -->
{:else if $events_sess.badges.show_form__scan}
<Element_qr_scanner_v2 bind:start_qr_scanner={$events_sess.badges.qr_scan_start} on:qr_scan_result={handle_qr_scan_result} />
<Element_qr_scanner_v2
bind:start_qr_scanner={$events_sess.badges.qr_scan_start}
on:qr_scan_result={handle_qr_scan_result}
/>
{/if}
<div class="opacity-50 hover:opacity-100 transition-all">

View File

@@ -24,9 +24,9 @@
const lines = text.trim().split('\n');
if (lines.length === 0) return [];
const headers = lines[0].split(',').map(h => h.trim());
const data = lines.slice(1).map(line => {
const values = line.split(',').map(v => v.trim());
const headers = lines[0].split(',').map((h) => h.trim());
const data = lines.slice(1).map((line) => {
const values = line.split(',').map((v) => v.trim());
const obj: key_val = {};
headers.forEach((header, index) => {
obj[header] = values[index];
@@ -77,7 +77,10 @@
affiliations_override: data_kv.affiliations || data_kv.company || null,
location_override: data_kv.location || null,
email: data_kv.email || null,
allow_tracking: data_kv.allow_tracking === 'true' || data_kv.allow_tracking === '1' || false,
allow_tracking:
data_kv.allow_tracking === 'true' ||
data_kv.allow_tracking === '1' ||
false,
badge_type_code: data_kv.badge_type_code || 'guest' // Default to 'guest' if not provided
};
@@ -92,7 +95,6 @@
upload_status = 'success';
upload_message = `Successfully uploaded ${processed_badges_count} out of ${total_badges_in_file} badges.`;
dispatch('success');
} catch (error) {
upload_status = 'error';
upload_message = `Error processing file: ${error.message}`;
@@ -117,11 +119,22 @@
<form onsubmit={handle_upload} class="p-4 space-y-4">
<h3 class="h3">Upload Badge List (CSV)</h3>
<p>Upload a CSV file containing badge data. The first row should be headers.</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>.</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>.
</p>
<label class="label">
<span>Select CSV File</span>
<input type="file" accept=".csv" bind:this={file_input} onchange={handle_file_change} class="input" />
<input
type="file"
accept=".csv"
bind:this={file_input}
onchange={handle_file_change}
class="input"
/>
</label>
{#if selected_file}
@@ -132,15 +145,27 @@
<div class="alert variant-soft-{upload_status === 'error' ? 'error' : 'info'}">
<p>{upload_message}</p>
{#if upload_status === 'processing' || upload_status === 'loading'}
<progress class="progress" value={processed_badges_count} max={total_badges_in_file}></progress>
<progress class="progress" value={processed_badges_count} max={total_badges_in_file}
></progress>
<p>Processed: {processed_badges_count} / {total_badges_in_file}</p>
{/if}
</div>
{/if}
<div class="flex justify-end gap-2">
<button type="button" class="btn variant-filled-tertiary" onclick={handle_cancel} disabled={upload_status === 'loading' || upload_status === 'processing'}>Cancel</button>
<button type="submit" class="btn variant-filled-primary" disabled={!selected_file || upload_status === 'loading' || upload_status === 'processing'}>
<button
type="button"
class="btn variant-filled-tertiary"
onclick={handle_cancel}
disabled={upload_status === 'loading' || upload_status === 'processing'}>Cancel</button
>
<button
type="submit"
class="btn variant-filled-primary"
disabled={!selected_file ||
upload_status === 'loading' ||
upload_status === 'processing'}
>
{#if upload_status === 'loading' || upload_status === 'processing'}
<span class="fas fa-spinner fa-spin mr-2"></span>
{/if}

View File

@@ -32,7 +32,7 @@
return result || [];
})
);
// Function to trigger browser print
function trigger_print() {
window.print();
@@ -84,7 +84,7 @@
{#each badges_to_print as badge_obj (badge_obj.event_badge_id_random)}
<div class="badge-print-container">
<Comp_badge_obj_view
event_id={event_id}
{event_id}
event_badge_id={badge_obj.event_badge_id_random}
lq__event_badge_obj={badge_obj}
is_review_mode={false}

View File

@@ -53,7 +53,11 @@
}
async function delete_template(template_id: string) {
if (confirm('Are you sure you want to delete this badge template? This action cannot be undone.')) {
if (
confirm(
'Are you sure you want to delete this badge template? This action cannot be undone.'
)
) {
try {
await events_func.delete_ae_obj_id__event_badge_template({
api_cfg: $ae_api,
@@ -76,7 +80,7 @@
<h1 class="h1">Badge Templates</h1>
<div class="my-4 flex justify-end">
<button class="btn btn-primary" onclick={() => show_create_template_modal = true}>
<button class="btn btn-primary" onclick={() => (show_create_template_modal = true)}>
<span class="fas fa-plus mr-2"></span> Add New Template
</button>
</div>
@@ -91,10 +95,18 @@
<li class="list-group-item flex justify-between items-center">
<span>{template.name}</span>
<div>
<button class="btn btn-sm variant-filled-primary" onclick={() => edit_template(template.event_badge_template_id_random)}>
<button
class="btn btn-sm variant-filled-primary"
onclick={() =>
edit_template(template.event_badge_template_id_random)}
>
<span class="fas fa-edit"></span> Edit
</button>
<button class="btn btn-sm variant-filled-error ml-2" onclick={() => delete_template(template.event_badge_template_id_random)}>
<button
class="btn btn-sm variant-filled-error ml-2"
onclick={() =>
delete_template(template.event_badge_template_id_random)}
>
<span class="fas fa-trash"></span> Delete
</button>
</div>
@@ -114,7 +126,7 @@
<Modal bind:show={show_create_template_modal}>
<div class="card p-4">
<Comp_badge_template_form
event_id={event_id}
{event_id}
on:success={handle_create_success}
on:cancel={handle_cancel}
/>
@@ -126,7 +138,7 @@
<Modal bind:show={show_edit_template_modal}>
<div class="card p-4">
<Comp_badge_template_form
event_id={event_id}
{event_id}
template_id={selected_template_id}
on:success={handle_edit_success}
on:cancel={handle_cancel}

View File

@@ -187,8 +187,17 @@
</label>
<div class="flex justify-end gap-2">
<button type="button" class="btn variant-filled-tertiary" onclick={handle_cancel} disabled={submit_status === 'loading'}>Cancel</button>
<button type="submit" class="btn variant-filled-primary" disabled={submit_status === 'loading'}>
<button
type="button"
class="btn variant-filled-tertiary"
onclick={handle_cancel}
disabled={submit_status === 'loading'}>Cancel</button
>
<button
type="submit"
class="btn variant-filled-primary"
disabled={submit_status === 'loading'}
>
{#if submit_status === 'loading'}
<span class="fas fa-spinner fa-spin mr-2"></span>
{/if}

View File

@@ -1,9 +1,11 @@
# Aether (AE) Event Lead Retrieval Module (v3)
## Overview
This module provides a comprehensive solution for event exhibitors to capture and manage leads. It supports exhibitor login, badge scanning for lead capture, manual lead entry, lead qualification (ranking/priority), and data export functionalities. It integrates with the Aether API for data synchronization and utilizes local caching for performance and offline capabilities.
## Key Features
- **Exhibitor Login:** Secure access for exhibitors using a shared passcode or individual license keys (email-based).
- **Lead Capture:** Efficiently add new leads by scanning attendee badge QR codes or through manual data entry.
- **Lead Management:** A dedicated interface for exhibitors to view, sort, and manage their collected leads.
@@ -17,7 +19,9 @@ This module provides a comprehensive solution for event exhibitors to capture an
The core data structures managed by this module are `Exhibit` and `Exhibit_tracking`.
### Exhibit
Represents an exhibitor's presence at an event. It contains configuration for lead retrieval, such as:
- `event_exhibit_id_random`: Unique identifier for the exhibit (primary key).
- `code`, `name`, `description`: Basic information about the exhibit.
- `staff_passcode`: For staff login.
@@ -26,7 +30,9 @@ Represents an exhibitor's presence at an event. It contains configuration for le
- `license_max`, `license_li_json`: Details regarding lead retrieval licenses.
### Exhibit_tracking
Represents a single lead captured by an exhibitor. It links an exhibitor to an attendee (badge) and stores details about the interaction:
- `event_exhibit_tracking_id_random`: Unique identifier for the captured lead (primary key).
- `event_exhibit_id_random`: Links to the `Exhibit` that captured the lead.
- `event_badge_id_random`: Links to the attendee's `Badge` information.
@@ -37,6 +43,7 @@ Represents a single lead captured by an exhibitor. It links an exhibitor to an a
## Routing and Components
### Routes
- `/events/[event_id]/(leads)`: The main entry point for the Leads module within a specific event, typically displays a list of available exhibits.
- `+page.svelte`: Renders the list of exhibits.
- `+page.ts`: Loads the data for available exhibits using `events_func.handle_load_ae_obj_li__exhibit`.
@@ -46,6 +53,7 @@ Represents a single lead captured by an exhibitor. It links an exhibitor to an a
- `+page.ts`: Loads specific `Exhibit` data and associated `Exhibit_tracking` (leads) using `events_func.handle_load_ae_obj_id__exhibit` and `events_func.handle_load_ae_obj_li__exhibit_tracking`.
### Core Components (within `src/routes/events/[event_id]/(leads)/exhibit/[slug]/`)
- `leads_add_scan.svelte`: Handles the process of adding new leads, either by scanning QR codes (badge) or manual entry.
- `leads_list.svelte`: Displays a sortable and filterable list of captured leads for the current exhibitor.
- `leads_manage.svelte`: Provides functionalities for managing individual leads, potentially including editing notes or qualification status.

View File

@@ -52,7 +52,7 @@
};
}
async function handle_submit_form(event) {
async function handle_submit_form(event: SubmitEvent) {
console.log('*** handle_submit_form() ***');
$events_sess.pres_mgmt.disable_submit__opt_out = true;

View File

@@ -496,9 +496,11 @@
class="inline-block select text-sm w-44 px-1 m-1 ae_btn_info"
bind:value={$events_loc.pres_mgmt.qry__files_sort}
onchange={(event) => {
if (event.target.value) {
// rpt__sort = event.target.value;
$events_loc.pres_mgmt.qry__files_sort = event.target.value;
if ((event.target as HTMLInputElement).value) {
// rpt__sort = (event.target as HTMLInputElement).value;
$events_loc.pres_mgmt.qry__files_sort = (
event.target as HTMLInputElement
).value;
} else {
// rpt__sort = 'created_on';
$events_loc.pres_mgmt.qry__files_sort = 'created_on';

View File

@@ -372,8 +372,8 @@
class="inline-block select text-sm w-36 px-1 m-1 ae_btn_info"
bind:value={rpt__sort}
onchange={(event) => {
if (event.target.value) {
rpt__sort = event.target.value;
if ((event.target as HTMLInputElement).value) {
rpt__sort = (event.target as HTMLInputElement).value;
} else {
rpt__sort = 'updated_on';
}

View File

@@ -51,7 +51,7 @@
};
}
async function handle_submit_form(event) {
async function handle_submit_form(event: SubmitEvent) {
console.log('*** handle_submit_form() ***');
$events_sess.pres_mgmt.disable__session_submit_opt_out = true;

View File

@@ -380,8 +380,7 @@
ae_promises[event_file_obj?.event_file_id] =
api.download_hosted_file({
api_cfg: $ae_api,
hosted_file_id:
event_file_obj?.hosted_file_id,
hosted_file_id: event_file_obj?.hosted_file_id,
return_file: true,
filename: event_file_obj?.filename,
auto_download: true,

View File

@@ -78,7 +78,7 @@
};
}
async function handle_submit_form_files(event) {
async function handle_submit_form_files(event: SubmitEvent) {
console.log('*** handle_submit_form() ***');
$events_sess.files.disable_submit__event_file_obj = true;

View File

@@ -502,9 +502,8 @@
person_obj_kv[''] = '-- Select a person --';
person_obj_li.forEach((person_obj) => {
let option_text = `${person_obj.full_name} (${person_obj.primary_email})`;
person_obj_kv[
person_obj.person_id
] = option_text;
person_obj_kv[person_obj.person_id] =
option_text;
});
$slct.person_obj_kv = person_obj_kv;
}