There have been a lot of changes. For some reason the commit is not working? Trying again.

This commit is contained in:
Scott Idem
2025-11-19 18:56:58 -05:00
parent b3c0446440
commit 10cc435146
20 changed files with 6362 additions and 292 deletions

View File

@@ -91,6 +91,12 @@ const events_local_data_struct: key_val = {
fulltext_search_qry_str: null,
search_badge_type_code: null,
// New additions for filter states
qry_printed_status: 'all', // Default to all
qry_affiliations: null, // Default to null for no filter
qry_sort_order: '', // Default to empty string for default sort
status_qry__search: null,
use_id_li: true,
search_status: null,

View File

@@ -11,14 +11,14 @@
// import { goto } from '$app/navigation';
// *** Import other supporting libraries
// import { browser } from '$app/environment';
import { browser } from '$app/environment';
import { liveQuery } from 'dexie';
// *** Import Aether specific variables and functions
// import type { key_val } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
// import { core_func } from '$lib/ae_core_functions';
// import { ae_snip, ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
import { ae_loc } from '$lib/stores/ae_stores';
// import Element_ae_crud from '$lib/element_ae_crud
// import Element_data_store from '$lib/element_data_store_v2.svelte';
@@ -58,14 +58,31 @@
})
);
let is_review_mode: boolean = $state(false);
// *** Functions and Logic
// if (browser) {
// console.log('Browser environment detected.');
import { onMount } from 'svelte';
let lq__event_obj = $state(null);
// let url_test_val = data.url.searchParams.get('test_val');
// console.log(`URL test_val = ${url_test_val}`);
// }
onMount(() => {
const observable = liveQuery(() => db_events.event.get($events_slct?.event_id ?? ''));
const subscription = observable.subscribe((value) => {
lq__event_obj = value;
});
if (browser && window.location.hash === '#review') {
is_review_mode = true;
$ae_loc.edit_mode = true;
} else {
is_review_mode = false;
$ae_loc.edit_mode = false;
}
return () => {
subscription.unsubscribe();
};
});
</script>
<svelte:head>
@@ -116,6 +133,7 @@
event_id={$lq__event_badge_obj.event_id}
{event_badge_id}
{lq__event_badge_obj}
{is_review_mode}
/>
<!-- {/if} -->
{:else}

View File

@@ -5,6 +5,7 @@
lq__event_badge_obj?: any;
update_status?: string;
update_complete?: boolean;
is_review_mode?: boolean;
log_lvl?: number;
}
@@ -14,6 +15,7 @@
lq__event_badge_obj,
update_status = $bindable('idle'),
update_complete = $bindable(true),
is_review_mode = false,
log_lvl = 0
}: Props = $props();
@@ -23,27 +25,7 @@
// *** Import other supporting libraries
import { liveQuery } from 'dexie';
// import {
// ArrowDown01, ArrowDown10, ArrowDownUp,
// BetweenVerticalEnd, BetweenVerticalStart,
// BookHeart, BookImage, Bookmark, BookOpenText, BriefcaseBusiness,
// Check, Copy,
// Expand, Eye, EyeOff,
// Flag, FlagOff, FilePlus, Fingerprint,
// Globe,
// Library,
// MessageSquareWarning, Minus,
// Notebook,
// Pencil, Plus,
// RemoveFormatting,
// SquareLibrary,
// Shapes, Share2, ShieldCheck, ShieldMinus, Siren, Skull,
// Tags, Target, ToggleLeft, ToggleRight, Trash2, TypeOutline,
// X
// } from '@lucide/svelte';
import type { key_val } from '$lib/stores/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
import { core_func } from '$lib/ae_core/ae_core_functions';
import {
ae_snip,
@@ -100,90 +82,57 @@
let show_event_badge_tools_modal: boolean = $state(false);
let show_restricted_fields: boolean = $state(false);
let allow_tracking: null | boolean = $state(null);
let show_allow_tracking: boolean = $state(false);
// Editable fields
let editable_full_name_override: string | null = $state(null);
let editable_professional_title_override: string | null = $state(null);
let editable_affiliations_override: string | null = $state(null);
let editable_location_override: string | null = $state(null);
let editable_allow_tracking: boolean | null = $state(null);
let editable_email: string | null = $state(null);
let editable_badge_type_code: string | null = $state(null);
let edit_full_name_override = $state(false);
let edit_professional_title_override = $state(false);
let edit_affiliations_override = $state(false);
let edit_location_override = $state(false);
// Manage edit state locally
let edit_mode_active: boolean = $state(false);
// 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_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;
if (is_review_mode) {
edit_mode_active = true;
$ae_loc.edit_mode = true;
} else {
edit_mode_active = false; // Ensure it starts off if not in review mode
$ae_loc.edit_mode = false;
}
}
});
let show_print_msg: null | boolean = $state(null);
let hide_qr: null | boolean = $state(null);
let use_badge_type = $state(null);
let use_badge_type_code = $state('');
// let use_badge_type_code_list = [];
// use_badge_type_code_list.push({code: 'current_member', name: 'Member'});
// use_badge_type_code_list.push({code: 'inactive_member', name: 'Non-Member'});
// use_badge_type_code_list.push({code: 'MBR', name: 'Member'});
// use_badge_type_code_list.push({code: 'AHMB', name: 'Member'});
// use_badge_type_code_list.push({code: 'SNMB', name: 'Student/Trainee Non-Member'});
// use_badge_type_code_list.push({code: 'SMBR', name: 'Student/Trainee Member'});
// use_badge_type_code_list.push({code: 'NMBR', name: 'Non-Member'});
// use_badge_type_code_list.push({code: 'ANHM', name: 'Non-Member'});
// use_badge_type_code_list.push({code: 'INMB', name: 'Non-Member'});
// use_badge_type_code_list.push({code: 'EXO', name: 'Exhibitor Booth Staff'});
// use_badge_type_code_list.push({code: 'EXALL', name: 'Exhibitor All Access'});
// use_badge_type_code_list.push({code: 'GUEST', name: 'Guest'});
// use_badge_type_code_list.push({code: 'HEART', name: 'HFTX Core'});
// use_badge_type_code_list.push({code: 'LUNG', name: 'LTX Core'});
// use_badge_type_code_list.push({code: 'STAFF', name: 'Staff'});
// use_badge_type_code_list.push({code: 'VIP', name: 'VIP'});
// use_badge_type_code_list.push({code: 'VOL', name: 'Volunteer'});
let full_name_override = $state(null); // Usually set by the person or similar
let longest_full_name_override_part = 0;
let full_name = $state(null); // Usually auto generated
let professional_title_override = $state(null);
let longest_professional_title_override_part = 0;
let affiliations_override = $state(null);
let longest_affiliations_override_part = 0;
let location_override = $state(null);
let longest_location_override_part = 0;
let option_other_1_display_opt: any = $state(null);
let option_other_1_override: any = $state(null);
let option_other_2_display_opt: any = $state(null);
let option_other_2_override: any = $state(null);
let option_ticket_1_display_opt: any = $state(null);
let option_ticket_1_override: any = $state(null);
let option_ticket_2_display_opt: any = $state(null);
let option_ticket_2_override: any = $state(null);
let option_ticket_3_display_opt: any = $state(null);
let option_ticket_3_override: any = $state(null);
// let option_ticket_4_display_opt = $state(null);
// let option_ticket_5_display_opt = $state(null);
// let option_ticket_6_display_opt = $state(null);
// let option_ticket_7_display_opt = $state(null);
// let option_ticket_8_display_opt = $state(null);
// These variables seem unused or redundant now with editable_ fields
// let use_badge_type = $state(null);
// let use_badge_type_code = $state('');
let slct_badge_type = '';
// let qr_type = 'mecard';
// let qr_img_src = $state(null);
// let img_obj_url = $state(null);
/* *** BEGIN *** This should be moved out */
// display options: 'front_bool', 'front_html', 'back_bool', 'back_html'
option_ticket_1_display_opt = 'front_bool';
option_ticket_2_display_opt = 'front_bool';
option_ticket_3_display_opt = 'front_bool';
let option_ticket_1_display_opt = 'front_bool';
let option_ticket_2_display_opt = 'front_bool';
let option_ticket_3_display_opt = 'front_bool';
option_other_1_display_opt = 'back_html';
option_other_2_display_opt = 'back_html';
let option_other_1_display_opt = 'back_html';
let option_other_2_display_opt = 'back_html';
let code_to_html: any = { option_1: {}, option_2: {} };
code_to_html.option_1['1'] = '<span class="fas fa-biohazard"></span>';
@@ -203,12 +152,6 @@
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['1-5'] = '<span class="fas fa-grimace"></span>';
// code_to_html.option_2['6-10'] = '<span class="fas fa-grimace"></span>';
// code_to_html.option_2['11-15'] = '<span class="fas fa-grimace"></span>';
// code_to_html.option_2['16-29'] = '<span class="fas fa-grimace"></span>';
// code_to_html.option_2['30+'] = '<span class="fas fa-grimace"></span>';
// code_to_html.option_2['Unknown'] = '<span class="fas fa-radiation"></span>';
/* *** END *** This should be moved out */
let full_name_class_size: string = $state('text-[.60in]');
@@ -227,10 +170,14 @@
$lq__event_badge_obj?.event_badge_template_id
);
full_name_override =
$lq__event_badge_obj?.full_name_override ?? $lq__event_badge_obj?.full_name;
longest_full_name_override_part = longest_str_part(full_name_override ?? '');
// 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 ?? '';
longest_full_name_override_part = longest_str_part(current_full_name);
if (longest_full_name_override_part >= 9) {
full_name_class_size = 'text-[.45in]';
} else if (longest_full_name_override_part >= 7) {
@@ -239,12 +186,7 @@
full_name_class_size = 'text-[.75in]';
}
professional_title_override =
$lq__event_badge_obj?.professional_title_override ??
$lq__event_badge_obj?.professional_title;
longest_professional_title_override_part = longest_str_part(
professional_title_override ?? ''
);
longest_professional_title_override_part = longest_str_part(current_professional_title);
if (longest_professional_title_override_part >= 13) {
professional_title_class_size = 'text-[.35in]';
} else if (longest_professional_title_override_part >= 10) {
@@ -255,9 +197,7 @@
professional_title_class_size = 'text-[.35in]';
}
affiliations_override =
$lq__event_badge_obj?.affiliations_override ?? $lq__event_badge_obj?.affiliations;
longest_affiliations_override_part = longest_str_part(affiliations_override ?? '');
longest_affiliations_override_part = longest_str_part(current_affiliations);
if (longest_affiliations_override_part >= 55) {
affiliations_class_size = 'text-[.30in]';
} else if (longest_affiliations_override_part >= 45) {
@@ -277,9 +217,7 @@
affiliations_class_size = full_name_class_size;
}
location_override =
$lq__event_badge_obj?.location_override ?? $lq__event_badge_obj?.location;
longest_location_override_part = longest_str_part(location_override ?? '');
longest_location_override_part = longest_str_part(current_location);
if (longest_location_override_part >= 55) {
location_class_size = 'text-[.30in]';
} else if (longest_location_override_part >= 45) {
@@ -301,27 +239,12 @@
professional_title_class_size = location_class_size;
}
option_other_1_override =
$lq__event_badge_obj?.option_other_1_override ??
$lq__event_badge_obj?.option_other_1;
option_other_2_override =
$lq__event_badge_obj?.option_other_2_override ??
$lq__event_badge_obj?.option_other_2;
option_ticket_1_override =
$lq__event_badge_obj?.option_ticket_1_override ??
$lq__event_badge_obj?.option_ticket_1;
option_ticket_2_override =
$lq__event_badge_obj?.option_ticket_2_override ??
$lq__event_badge_obj?.option_ticket_2;
option_ticket_3_override =
$lq__event_badge_obj?.option_ticket_3_override ??
$lq__event_badge_obj?.option_ticket_3;
// option_ticket_4_override = $lq__event_badge_obj?.option_ticket_4_override ?? $lq__event_badge_obj?.option_ticket_4;
// option_ticket_5_override = $lq__event_badge_obj?.option_ticket_5_override ?? $lq__event_badge_obj?.option_ticket_5;
// option_ticket_6_override = $lq__event_badge_obj?.option_ticket_6_override ?? $lq__event_badge_obj?.option_ticket_6;
// option_ticket_7_override = $lq__event_badge_obj?.option_ticket_7_override ?? $lq__event_badge_obj?.option_ticket_7;
// option_ticket_8_override = $lq__event_badge_obj?.option_ticket_8_override ?? $lq__event_badge_obj?.option_ticket_8;
// These are no longer needed as we use the editable fields directly
// option_other_1_override = $lq__event_badge_obj?.option_other_1_override ?? $lq__event_badge_obj?.option_other_1;
// option_other_2_override = $lq__event_badge_obj?.option_other_2_override ?? $lq__event_badge_obj?.option_other_2;
// option_ticket_1_override = $lq__event_badge_obj?.option_ticket_1_override ?? $lq__event_badge_obj?.option_ticket_1;
// option_ticket_2_override = $lq__event_badge_obj?.option_ticket_2_override ?? $lq__event_badge_obj?.option_ticket_2;
// option_ticket_3_override = $lq__event_badge_obj?.option_ticket_3_override ?? $lq__event_badge_obj?.option_ticket_3;
return results;
})
@@ -411,6 +334,90 @@
console.error(error);
}
}
async function handle_save_changes() {
if (!lq__event_badge_obj?.event_badge_id_random) {
console.error('Cannot save changes: event_badge_id_random is missing.');
return;
}
update_status = 'loading';
update_complete = false;
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)) {
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)) {
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)) {
data_to_update.affiliations_override = editable_affiliations_override;
}
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) {
data_to_update.allow_tracking = editable_allow_tracking;
}
if (editable_email !== lq__event_badge_obj.email) {
data_to_update.email = editable_email;
}
if (editable_badge_type_code !== lq__event_badge_obj.badge_type_code) {
data_to_update.badge_type_code = editable_badge_type_code;
}
if (Object.keys(data_to_update).length === 0) {
console.log('No changes to save.');
update_status = 'done';
update_complete = true;
if (!is_review_mode) {
edit_mode_active = false;
$ae_loc.edit_mode = false;
}
return;
}
try {
await events_func.update_ae_obj__event_badge({
api_cfg: $ae_api,
event_badge_id: lq__event_badge_obj.event_badge_id_random,
data_kv: data_to_update,
log_lvl: log_lvl
});
update_status = 'done';
update_complete = true;
if (!is_review_mode) {
edit_mode_active = false;
$ae_loc.edit_mode = false;
}
// Optionally, refresh the lq__event_badge_obj if needed, though Dexie might handle it
} catch (error) {
console.error('Error saving changes:', error);
update_status = 'error';
update_complete = true;
}
}
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_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;
}
if (!is_review_mode) {
edit_mode_active = false;
$ae_loc.edit_mode = false;
}
update_status = 'idle';
update_complete = true;
}
</script>
<!--
@@ -482,42 +489,77 @@ onkeypress={() => {
transition-all group
flex flex-col gap-1 items-center justify-center
"
class:preset-outlined-warning-200-800={$ae_loc.edit_mode}
class:preset-tonal-warning={$ae_loc.edit_mode}
class:preset-outlined-warning-200-800={edit_mode_active}
class:preset-tonal-warning={edit_mode_active}
>
<button
class="
btn btn-sm text-xs
preset-tonal-warning preset-outlined-warning-100-900 hover:preset-filled-secondary-500
transition-all group
"
onclick={() => {
show_event_badge_tools_modal = true;
$ae_loc.edit_mode = !$ae_loc.edit_mode;
}}
title="Edit Badge Information"
>
{#if $ae_loc.edit_mode}
<span class="fas fa-times m-1"></span>
{:else}
<span class="fas fa-edit m-1"></span>
{/if}
<span
{#if edit_mode_active}
<button
class="
hidden
group-hover:inline-block
text-xs
btn btn-sm text-xs
preset-tonal-success preset-outlined-success-100-900 hover:preset-filled-success-500
transition-all group
"
onclick={handle_save_changes}
title="Save Changes"
>
{#if $ae_loc.edit_mode}
Close Edit
{:else}
<span class="fas fa-save m-1"></span>
<span
class="
hidden
group-hover:inline-block
text-xs
"
>
Save Changes
</span>
</button>
<button
class="
btn btn-sm text-xs
preset-tonal-tertiary preset-outlined-tertiary-100-900 hover:preset-filled-tertiary-500
transition-all group
"
onclick={handle_cancel_changes}
title="Cancel Editing"
>
<span class="fas fa-times m-1"></span>
<span
class="
hidden
group-hover:inline-block
text-xs
"
>
Cancel
</span>
</button>
{:else}
<button
class="
btn btn-sm text-xs
preset-tonal-warning preset-outlined-warning-100-900 hover:preset-filled-secondary-500
transition-all group
"
onclick={() => {
edit_mode_active = true;
$ae_loc.edit_mode = true;
}}
title="Edit Badge Information"
>
<span class="fas fa-edit m-1"></span>
<span
class="
hidden
group-hover:inline-block
text-xs
"
>
Edit Badge Information
{/if}
</span>
</button>
</span>
</button>
{/if}
<div class="w-md max-w-lg m-1 p-1" class:hidden={!$ae_loc.edit_mode}>
<div class="w-md max-w-lg m-1 p-1" class:hidden={!edit_mode_active}>
<p class="text-xs italic text-gray-500">
Show list of fields that they can edit here. This may need to broken down in
to sections that can be collapsed.
@@ -599,78 +641,97 @@ onkeypress={() => {
<!-- <span class="float-right text-sm italic m-2">
{longest_full_name_override_part}&times; char
</span> -->
<!-- {#if $lq__event_badge_obj.title_names}<span class="title_names">{$lq__event_badge_obj.title_names}</span>{/if} -->
<span class="full_name_override">
{#if full_name_override}
{@html full_name_override.trim()}
{:else}
-- no name --
{/if}
</span>
<!-- {#if $lq__event_badge_obj.designations}<span class="designations">{$lq__event_badge_obj.designations}</span>{/if} -->
{#if edit_mode_active}
<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}
{@html editable_full_name_override.trim()}
{:else}
-- no name --
{/if}
</span>
{/if}
</div>
{#if professional_title_override}
{#if editable_professional_title_override || edit_mode_active}
<div
class="professional_title
{professional_title_class_size} leading-none
italic
"
>
{@html professional_title_override}
{#if edit_mode_active}
<input type="text" bind:value={editable_professional_title_override} class="input w-full text-center" />
{:else}
{@html editable_professional_title_override}
{/if}
</div>
{/if}
</div>
<!-- {#if $lq__event_badge_obj.pronouns}
<div class="pronouns">
<span class="pronouns">{@html $lq__event_badge_obj.pronouns}</span>
</div>
{/if} -->
<!-- {#if $lq__event_badge_obj.professional_title}
<div class="professional_title">
<span class="professional_title" class:str_25={$lq__event_badge_obj.professional_title.length>25}>{@html $lq__event_badge_obj.professional_title}</span>
</div>
{/if} -->
{#if affiliations_override || location_override}
{#if editable_affiliations_override || editable_location_override || edit_mode_active || editable_email || edit_mode_active || editable_allow_tracking !== null || edit_mode_active}
<div
class="affiliations_location
max-h-[3.0in] m-0 p-0
hover:outline-2 hover:outline-dashed hover:outline-gray-500/75
"
>
{#if affiliations_override}
{#if editable_affiliations_override || edit_mode_active}
<div
class="affiliations
{affiliations_class_size} leading-none
"
>
{@html affiliations_override}
{#if edit_mode_active}
<textarea bind:value={editable_affiliations_override} class="textarea w-full text-center" rows="2"></textarea>
{:else}
{@html editable_affiliations_override}
{/if}
</div>
{/if}
{#if location_override}
{#if editable_location_override || edit_mode_active}
<div
class="location
{location_class_size} leading-none
"
>
<span class="city state_province country"
>{@html location_override}</span
>
{#if edit_mode_active}
<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
>
{/if}
</div>
{/if}
{#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>
{:else}
Email: {editable_email}
{/if}
</div>
{/if}
{#if editable_allow_tracking !== null || edit_mode_active}
<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>
{:else}
Allow Tracking: {editable_allow_tracking ? 'Yes' : 'No'}
{/if}
</div>
{/if}
</div>
{/if}
{#if ['front_bool', 'front_back_bool'].includes(option_ticket_1_display_opt) || ['front_bool', 'front_back_bool'].includes(option_ticket_2_display_opt) || ['front_bool', 'front_back_bool'].includes(option_ticket_3_display_opt) || $lq__event_badge_template_obj.show_qr_front}
{#if ['front_bool', 'front_back_bool'].includes(option_ticket_1_display_opt) || ['front_bool', 'front_back_bool'].includes(option_ticket_2_display_opt) || ['front_bool', 'front_back_bool'].includes(option_ticket_3_display_opt) || $lq__event_badge_template_obj.show_qr_front || edit_mode_active}
<div class="special">
<span class="badge_body_special_left">
<!-- {#if option_ticket_1_override}<span class="ticket_1_code fg_red fas fa-star"></span>{/if} -->
{#if option_ticket_1_override}<span
class="ticket_1_code fg_green fas fa-star"
></span>{/if}
@@ -678,7 +739,6 @@ onkeypress={() => {
<span class="badge_body_special_right">
{#if option_ticket_2_override}
<span class=" ticket_2_code fg_red fas fa-star"></span>
<!-- <span class=" ticket_2_code fg_gold fas fa-star"></span> -->
{/if}
{#if option_ticket_3_override}
<span class="ticket_3_code fg_blue fas fa-star"></span>
@@ -704,7 +764,7 @@ onkeypress={() => {
<div
class="badge_footer
{use_badge_type_code.toLowerCase()}
{editable_badge_type_code?.toLowerCase()}
justify-self-end
min-h-[.25in]
max-h-[.50in]
@@ -714,34 +774,41 @@ onkeypress={() => {
flex flex-row gap-1 items-center justify-center
hover:outline-2 hover:outline-dashed hover:outline-gray-500/75
"
title={use_badge_type_code}
title={editable_badge_type_code}
>
THE FOOTER
{#if option_other_1_override && ['front_bool', 'front_back_bool'].includes(option_other_1_display_opt)}
<span class="badge_footer_special_left"
><span class="fas fa-biohazard"></span></span
{#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">
{#each badge_type_code_li as badge_type_code_item}
<option value={badge_type_code_item.code}>{badge_type_code_item.name}</option>
{/each}
</select>
</label>
{:else}
THE FOOTER
{#if option_other_1_override && ['front_bool', 'front_back_bool'].includes(option_other_1_display_opt)}
<span class="badge_footer_special_left"
><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>
{/if}
<span class="badge_footer_center {editable_badge_type_code?.toLowerCase()}"
>{editable_badge_type_code}</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>
{/if}
<span class="badge_footer_center {use_badge_type_code.toLowerCase()}"
>{@html use_badge_type}</span
>
<!-- {#if $lq__event_badge_obj.other_2}
<span class="badge_footer_special_right"><span class="fas fa-star-of-life"></span></span>
{/if} -->
{#if option_other_2_override && ['front_bool', 'front_back_bool'].includes(option_other_2_display_opt)}
<span class="badge_footer_special_right"
><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>
{#if option_other_2_override && ['front_bool', 'front_back_bool'].includes(option_other_2_display_opt)}
<span class="badge_footer_special_right"
><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>
{/if}
{/if}
</div>
<!-- {#if $lq__event_badge_template_obj.show_qr_front}
<div class="container qr_code">
{#await initial_loading_promise}

View File

@@ -53,72 +53,114 @@
<ul class="list-disc list-inside">
{#each $lq__event_badge_obj_li as event_badge_obj (event_badge_obj.event_badge_id_random)}
<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
"
>
<a
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}`}
{#if !event_badge_obj.hide || 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
"
>
<span>
{#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}
<!-- Show a green checkmark -->
<span class="fas fa-check text-green-500"></span>
{#if event_badge_obj.print_count < 1 || trusted_access}
<a
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}`}
>
<span>
{#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}
<!-- Show a green checkmark -->
<span class="fas fa-check text-green-500"></span>
<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}
{:else}
-- no name --
{/if}
</span>
</a>
{: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}`}
>
<span>
{#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}
<!-- Show a green checkmark -->
<span class="fas fa-check text-green-500"></span>
<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}
{:else}
-- no name --
{/if}
</span>
</span>
{/if}
{#if show_sensitive_fields}
-
<span class="min-w-fit">
<span class="fas fa-envelope"></span>
{#if trusted_access}
<span class="print_count preset-tonal-warning px-1"
>{event_badge_obj.print_count}&times;</span
>
{event_badge_obj.email}
{:else}
{event_badge_obj.email
? event_badge_obj.email.replace(/^(.{3}).*@/, '$1...@')
: ''}
{/if}
{/if}
</span>
</span>
{/if}
{#if !hide_affiliations}
-
{event_badge_obj?.affiliations ?? '-- no affiliations --'}
{/if}
{#if !hide_location}
-
{event_badge_obj?.location ?? '-- no location --'}
{/if}
{#if !hide_badge_type}
-
<span class="italic">{event_badge_obj?.badge_type}</span>
{/if}
<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}
{:else}
-- no name --
{/if}
</span>
</a>
{#if show_sensitive_fields}
-
<span class="min-w-fit">
<!-- The email should only be the first 3 chars and then @domain name. -->
<!-- Example: original: scott.idem@oneskyit.com obscured: sco...@oneskyit.com -->
<span class="fas fa-envelope"></span>
{event_badge_obj.email
? event_badge_obj.email.replace(/^(.{3}).*@/, '$1...@')
: ''}
</span>
{/if}
{#if !hide_affiliations}
-
{event_badge_obj?.affiliations ?? '-- no affiliations --'}
{/if}
{#if !hide_location}
-
{event_badge_obj?.location ?? '-- no location --'}
{/if}
{#if !hide_badge_type}
-
<span class="italic">{event_badge_obj?.badge_type}</span>
{/if}
</li>
{#if trusted_access}
<a
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}
</li>
{/if}
{/each}
</ul>

View File

@@ -0,0 +1,102 @@
<script lang="ts">
import { liveQuery } from 'dexie';
import { events_func } from '$lib/ae_events_functions';
import { ae_api } from '$lib/stores/ae_stores';
import { events_slct } from '$lib/stores/ae_events_stores';
import Comp_badge_obj_view from '../[badge_id]/ae_comp__badge_obj_view.svelte';
interface Props {
data: any; // PageData from SvelteKit
}
let { data }: Props = $props();
let event_id: string = data.params.event_id;
let printed_status_filter: string | null = 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(
liveQuery(async () => {
const filters: { printed_status?: string; type_code?: string } = {};
if (printed_status_filter) filters.printed_status = printed_status_filter;
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
const result = await events_func.search__event_badge({
api_cfg: $ae_api,
event_id: event_id,
limit: 5000, // A high limit to fetch all relevant badges for printing
...filters,
log_lvl: 0
});
return result || [];
})
);
// Function to trigger browser print
function trigger_print() {
window.print();
}
</script>
<svelte:head>
<title>Bulk Print Badges for Event {event_id}</title>
<style>
/* Print-specific styles */
@media print {
body {
margin: 0;
padding: 0;
}
.print-button {
display: none;
}
/* Customize how badges are laid out for printing */
.badge-print-container {
page-break-after: always; /* Each badge on a new page or arrange multiple per page */
/* Adjust width/height for optimal badge size on print media */
width: 4in; /* Example width */
height: 6in; /* Example height */
margin: 0.25in; /* Example margin */
border: 1px solid #ccc; /* Optional: for visual separation on print */
}
}
</style>
</svelte:head>
<section class="p-4">
<h1 class="h1">Bulk Print Badges</h1>
<div class="print-button my-4">
<button class="btn btn-primary" onclick={trigger_print}>
<span class="fas fa-print mr-2"></span> Print Badges
</button>
<a href={`/events/${event_id}/badges`} class="btn btn-tertiary ml-2">
<span class="fas fa-arrow-left mr-2"></span> Back to Search
</a>
</div>
{#await lq__filtered_badges}
<p>Loading badges for printing...</p>
{:then badges_to_print}
{#if badges_to_print.length > 0}
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{#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_badge_id={badge_obj.event_badge_id_random}
lq__event_badge_obj={badge_obj}
is_review_mode={false}
log_lvl={0}
/>
</div>
{/each}
</div>
{:else}
<p>No badges found matching your criteria for printing.</p>
{/if}
{:catch error}
<p class="text-error-500">Error loading badges: {error.message}</p>
{/await}
</section>

View File

@@ -0,0 +1,136 @@
<script lang="ts">
import { liveQuery } from 'dexie';
import { events_func } from '$lib/ae_events_functions';
import { ae_api } from '$lib/stores/ae_stores';
import { events_slct } from '$lib/stores/ae_events_stores';
import { Modal } from '@skeletonlabs/skeleton';
import Comp_badge_template_form from './ae_comp__badge_template_form.svelte';
interface Props {
data: any; // PageData from SvelteKit
}
let { data }: Props = $props();
let event_id: string = data.params.event_id;
let show_create_template_modal: boolean = $state(false);
let selected_template_id: string | null = $state(null);
let show_edit_template_modal: boolean = $state(false);
let lq__badge_templates = $derived(
liveQuery(async () => {
const result = await events_func.load_ae_obj_li__event_badge_template({
api_cfg: $ae_api,
event_id: event_id,
log_lvl: 0
});
return result || [];
})
);
function handle_create_success() {
show_create_template_modal = false;
// Trigger a refresh of the list (by updating a store or re-fetching)
// For now, relying on liveQuery to react to DB changes
}
function handle_edit_success() {
show_edit_template_modal = false;
selected_template_id = null;
// Trigger a refresh of the list
}
function handle_cancel() {
show_create_template_modal = false;
show_edit_template_modal = false;
selected_template_id = null;
}
function edit_template(template_id: string) {
selected_template_id = template_id;
show_edit_template_modal = true;
}
async function delete_template(template_id: string) {
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,
event_badge_template_id: template_id
});
// Rely on liveQuery to refresh list
} catch (error) {
console.error('Error deleting template:', error);
alert('Failed to delete template.');
}
}
}
</script>
<svelte:head>
<title>Badge Templates - Event {event_id}</title>
</svelte:head>
<section class="p-4">
<h1 class="h1">Badge Templates</h1>
<div class="my-4 flex justify-end">
<button class="btn btn-primary" onclick={() => show_create_template_modal = true}>
<span class="fas fa-plus mr-2"></span> Add New Template
</button>
</div>
{#await lq__badge_templates}
<p>Loading badge templates...</p>
{:then templates}
{#if templates.length > 0}
<div class="card p-4">
<ul class="list-group">
{#each templates as template (template.event_badge_template_id_random)}
<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)}>
<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)}>
<span class="fas fa-trash"></span> Delete
</button>
</div>
</li>
{/each}
</ul>
</div>
{:else}
<p>No badge templates found for this event. Click "Add New Template" to create one.</p>
{/if}
{:catch error}
<p class="text-error-500">Error loading templates: {error.message}</p>
{/await}
</section>
{#if show_create_template_modal}
<Modal bind:show={show_create_template_modal}>
<div class="card p-4">
<Comp_badge_template_form
event_id={event_id}
on:success={handle_create_success}
on:cancel={handle_cancel}
/>
</div>
</Modal>
{/if}
{#if show_edit_template_modal}
<Modal bind:show={show_edit_template_modal}>
<div class="card p-4">
<Comp_badge_template_form
event_id={event_id}
template_id={selected_template_id}
on:success={handle_edit_success}
on:cancel={handle_cancel}
/>
</div>
</Modal>
{/if}

View File

@@ -0,0 +1,204 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import type { key_val } from '$lib/stores/ae_stores';
import { events_func } from '$lib/ae_events_functions';
import { ae_api } from '$lib/stores/ae_stores';
interface Props {
event_id: string;
template_id?: string | null; // Null for creation, string for editing
}
let { event_id, template_id = null }: Props = $props();
const dispatch = createEventDispatcher();
// Form fields
let name: string = '';
let header_path: string = '';
let logo_path: string = '';
let header_row_1: string = '';
let header_row_2: string = '';
let secondary_header_path: string = '';
let footer_text: string = '';
let show_qr_front: boolean = true;
let show_qr_back: boolean = true;
let wireless_ssid: string = '';
let wireless_password: string = '';
let ticket_1_text: string = '';
let ticket_2_text: string = '';
let ticket_3_text: string = '';
let submit_status: string = 'idle'; // idle, loading, success, error
// Load template data if in edit mode
$effect(async () => {
if (template_id) {
submit_status = 'loading';
try {
const template_obj = await events_func.load_ae_obj_id__event_badge_template({
api_cfg: $ae_api,
event_badge_template_id: template_id
});
if (template_obj) {
name = template_obj.name || '';
header_path = template_obj.header_path || '';
logo_path = template_obj.logo_path || '';
header_row_1 = template_obj.header_row_1 || '';
header_row_2 = template_obj.header_row_2 || '';
secondary_header_path = template_obj.secondary_header_path || '';
footer_text = template_obj.footer_text || '';
show_qr_front = template_obj.show_qr_front ?? true;
show_qr_back = template_obj.show_qr_back ?? true;
wireless_ssid = template_obj.wireless_ssid || '';
wireless_password = template_obj.wireless_password || '';
ticket_1_text = template_obj.ticket_1_text || '';
ticket_2_text = template_obj.ticket_2_text || '';
ticket_3_text = template_obj.ticket_3_text || '';
submit_status = 'idle';
} else {
submit_status = 'error';
console.error('Template not found for editing.');
}
} catch (error) {
submit_status = 'error';
console.error('Error loading template for editing:', error);
}
}
});
async function handle_submit() {
submit_status = 'loading';
const data_to_save: key_val = {
name,
header_path,
logo_path,
header_row_1,
header_row_2,
secondary_header_path,
footer_text,
show_qr_front,
show_qr_back,
wireless_ssid,
wireless_password,
ticket_1_text,
ticket_2_text,
ticket_3_text
};
try {
let result;
if (template_id) {
result = await events_func.update_ae_obj__event_badge_template({
api_cfg: $ae_api,
event_badge_template_id: template_id,
data_kv: data_to_save
});
} else {
result = await events_func.create_ae_obj__event_badge_template({
api_cfg: $ae_api,
event_id: event_id,
data_kv: data_to_save
});
}
if (result) {
submit_status = 'success';
dispatch('success', result);
} else {
submit_status = 'error';
dispatch('error', 'Failed to save template');
}
} catch (error) {
submit_status = 'error';
console.error('Error saving template:', error);
dispatch('error', error);
}
}
function handle_cancel() {
dispatch('cancel');
}
</script>
<form onsubmit|preventDefault={handle_submit} class="p-4 space-y-4">
<h3 class="h3">{template_id ? 'Edit' : 'Create New'} Badge Template</h3>
<label class="label">
<span>Template Name</span>
<input type="text" bind:value={name} class="input" required />
</label>
<label class="label">
<span>Header Path (URL)</span>
<input type="text" bind:value={header_path} class="input" />
</label>
<label class="label">
<span>Logo Path (URL, if no Header Path)</span>
<input type="text" bind:value={logo_path} class="input" />
</label>
<label class="label">
<span>Header Row 1 Text (HTML allowed)</span>
<textarea bind:value={header_row_1} class="textarea" rows="2"></textarea>
</label>
<label class="label">
<span>Header Row 2 Text (HTML allowed)</span>
<textarea bind:value={header_row_2} class="textarea" rows="2"></textarea>
</label>
<label class="label">
<span>Secondary Header Path (URL, back of badge)</span>
<input type="text" bind:value={secondary_header_path} class="input" />
</label>
<label class="label">
<span>Footer Text (HTML allowed)</span>
<textarea bind:value={footer_text} class="textarea" rows="2"></textarea>
</label>
<label class="label flex items-center gap-2">
<input type="checkbox" bind:checked={show_qr_front} class="checkbox" />
<span>Show QR Code on Front</span>
</label>
<label class="label flex items-center gap-2">
<input type="checkbox" bind:checked={show_qr_back} class="checkbox" />
<span>Show QR Code on Back</span>
</label>
<label class="label">
<span>Wireless SSID</span>
<input type="text" bind:value={wireless_ssid} class="input" />
</label>
<label class="label">
<span>Wireless Password</span>
<input type="text" bind:value={wireless_password} class="input" />
</label>
<label class="label">
<span>Ticket 1 Text (HTML allowed)</span>
<textarea bind:value={ticket_1_text} class="textarea" rows="2"></textarea>
</label>
<label class="label">
<span>Ticket 2 Text (HTML allowed)</span>
<textarea bind:value={ticket_2_text} class="textarea" rows="2"></textarea>
</label>
<label class="label">
<span>Ticket 3 Text (HTML allowed)</span>
<textarea bind:value={ticket_3_text} class="textarea" rows="2"></textarea>
</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'}>
{#if submit_status === 'loading'}
<span class="fas fa-spinner fa-spin mr-2"></span>
{/if}
{template_id ? 'Save Changes' : 'Create Template'}
</button>
</div>
</form>
{#if submit_status === 'success'}
<p class="text-green-500">Template saved successfully!</p>
{:else if submit_status === 'error'}
<p class="text-red-500">Error saving template. Please try again.</p>
{/if}

View File

@@ -1331,7 +1331,7 @@
bodyClass="p-0 space-y-0 overflow-y-auto flex flex-col gap-1 items-center justify-center"
headerClass={`fixed top-0 right-0 left-0 p-1 md:p-2 flex flex-row items-center ${$events_loc.launcher.controller == 'remote' ? 'hidden' : ''} bg-white dark:bg-gray-800 opacity-50 ${$events_loc.launcher.hide__modal_header_title ? 'justify-center' : 'justify-between'}`}
footerClass="text-center hidden"
onclose={async () => {
on:close={async () => {
$events_sess.launcher.modal__open_event_file_id = null;
if (
$events_loc.launcher.controller == 'local_push' &&

View File

@@ -1,4 +1,4 @@
# Events - Badges Module
# Events - Badges Module (version 2)
This document describes the **Events - Badges** module, which is a sub-module of the Events module. It provides functionality for finding, reviewing, and printing badges for event attendees.

View File

@@ -0,0 +1,260 @@
<script lang="ts">
// *** Import Svelte core
import { onMount } from 'svelte';
// *** Import Aether core variables and functions
import { Element_modal_v3 } from 'aether_npm_lib';
import { client, page, slct, slct_trigger, ae_com, ae_events, tbl_event, tbl_event_badge, tbl_event_badge_template } from '../../stores_mod_events';
// import {} from '../stores_event.js';
import { get_event_obj, get_event_badge_template_obj_li } from '../stores_event_api.js';
// *** Import Aether module components
import Event_badge_obj_form from './20_event_badge_form.svelte';
import Event_badge_search_main from './20_event_badge_search_main.svelte';
import Event_badge_upload_form from './20_event_badge_upload_form.svelte';
// import Event_badge_view_main from './20_event_badge_view_main.svelte';
// *** Export/Exposed variables and functions for component
export let event_id: string = $page['page_for']['event_id'];
$slct.event_id = event_id;
$slct_trigger = 'event';
let event_obj_get_promise = null;
let event_badge_template_obj_li_get_promise = null;
let show_add_edit_event_badge_obj_form: boolean = false; // For form
// let show_event_badge_search_main: boolean = false;
// let show_event_badge_view_main: boolean = false;
let show_event_badge_list_upload_form: boolean = false;
let event_badge_edit_id: string = null; // Need to look up details with ID
onMount(() => {
console.log('** Component Mounted: ** Event Badge Main');
});
$: if ($slct_trigger == 'event' && $slct.event_id) {
console.log(`Selected Event: ${$slct.event_id}`);
$slct_trigger = null;
handle_load_event_obj({event_id: $slct.event_id, try_cache: true});
}
$: if (!$ae_com.administrator_access || !$client.administrator_access) {
document.getElementById('Site-Nav-Menu').style.display = 'none';
} else {
document.getElementById('Site-Nav-Menu').style.display = 'flex';
}
async function handle_load_event_obj({event_id, try_cache=false}) {
console.log('*** handle_load_event_obj() ***');
if (!event_id) {
return;
}
if (try_cache) {
// let event_obj_cache = await tbl_event.getItem(event_id);
// if (event_obj_cache) {
// console.log('Selected Event Object (from cache)', event_obj_cache);
// $slct.event_obj = JSON.parse(event_obj_cache);
// console.log('Selected Event Object (from cache)', $slct.event_obj);
// if ($slct.event_obj.event_cfg.mod_badges_json) {
// $ae_events.badges.badge_id_only_search = $slct.event_obj.event_cfg.mod_badges_json.badge_id_only_search;
// $ae_events.badges.enable_mass_print = $slct.event_obj.event_cfg.mod_badges_json.enable_mass_print;
// $ae_events.badges.enable_add_badge_btn = $slct.event_obj.event_cfg.mod_badges_json.enable_add_badge_btn;
// $ae_events.badges.enable_upload_badge_li_btn = $slct.event_obj.event_cfg.mod_badges_json.enable_upload_badge_li_btn;
// $ae_events.badges.enable_search_qr = $slct.event_obj.event_cfg.mod_badges_json.enable_search_qr;
// $ae_events.badges.qr_type = $slct.event_obj.event_cfg.mod_badges_json.qr_type;
// }
// }
// let event_obj_cache = window.sessionStorage.getItem('slct_event_obj');
// if (event_obj_cache) {
// $slct.event_obj = JSON.parse(event_obj_cache);
// console.log('Selected Event Object (from cache)', $slct.event_obj);
// if ($slct.event_obj.event_cfg.mod_badges_json) {
// $ae_events.badges.enable_mass_print = $slct.event_obj.event_cfg.mod_badges_json.enable_mass_print;
// $ae_events.badges.enable_add_badge_btn = $slct.event_obj.event_cfg.mod_badges_json.enable_add_badge_btn;
// $ae_events.badges.enable_upload_badge_li_btn = $slct.event_obj.event_cfg.mod_badges_json.enable_upload_badge_li_btn;
// $ae_events.badges.enable_search_qr = $slct.event_obj.event_cfg.mod_badges_json.enable_search_qr;
// }
// }
// let event_badge_template_obj_li_cache = window.sessionStorage.getItem('slct_event_badge_template_obj_li');
// if (event_badge_template_obj_li_cache) {
// console.log('Selected Event Badge Template Object List (from cache)', event_badge_template_obj_li_cache);
// $slct.event_badge_template_obj_li = JSON.parse(event_badge_template_obj_li_cache);
// console.log('Selected Event Badge Template Object List (from cache)', $slct.event_badge_template_obj_li);
// }
}
event_obj_get_promise = get_event_obj({event_id: event_id, inc_event_cfg: true})
.then(function (event_obj_result) {
if (!event_obj_result) {
console.log('The result was null or false when trying to get the event.');
return;
}
// $slct.event_obj = event_obj_result;
$slct.event_obj = event_obj_result;
console.log('Selected Event Object', $slct.event_obj);
if ($slct.event_obj.event_cfg.mod_badges_json) {
$ae_events.badges.badge_id_only_search = $slct.event_obj.event_cfg.mod_badges_json.badge_id_only_search;
$ae_events.badges.enable_mass_print = $slct.event_obj.event_cfg.mod_badges_json.enable_mass_print;
$ae_events.badges.enable_add_badge_btn = $slct.event_obj.event_cfg.mod_badges_json.enable_add_badge_btn;
$ae_events.badges.enable_upload_badge_li_btn = $slct.event_obj.event_cfg.mod_badges_json.enable_upload_badge_li_btn;
$ae_events.badges.enable_search_qr = $slct.event_obj.event_cfg.mod_badges_json.enable_search_qr;
}
window.sessionStorage.setItem('slct_event_id', event_id);
window.sessionStorage.setItem('slct_event_obj', JSON.stringify($slct.event_obj));
tbl_event.setItem($slct.event_obj.event_id_random, JSON.stringify($slct.event_obj));
})
.catch(function (error) {
console.log('Something went wrong loading the event.');
console.log(error);
return false;
});
// NOTE: For now handling the badge template list separately. The API needs to be updated.
event_badge_template_obj_li_get_promise = get_event_badge_template_obj_li({event_id: event_id, inc_event_badge_list: false})
.then(function (event_badge_template_obj_li_result) {
if (!event_badge_template_obj_li_result) {
console.log('The result was null or false when trying to get the event_badge_template_obj_li.');
return;
}
$slct.event_badge_template_obj_li = event_badge_template_obj_li_result;
console.log('Selected Event Badge Template Object List', $slct.event_badge_template_obj_li);
window.sessionStorage.setItem('slct_event_badge_template_obj_li', JSON.stringify($slct.event_badge_template_obj_li));
// NOTE: Need to loop through the badge template list (array) and set the table key to the id_random value and value to the JSON string.
$slct.event_badge_template_obj_li.forEach(event_badge_template => {
tbl_event_badge_template.setItem(event_badge_template.event_badge_template_id_random, JSON.stringify(event_badge_template));
});
})
.catch(function (error) {
console.log('Something went wrong loading the event badge template list.');
console.log(error);
return false;
});
return event_obj_get_promise;
}
function handle_event_badge_file_uploaded(event) {
console.log(event.detail.element_id);
console.log(event.detail.file_upload_list);
}
</script>
<section id="Main-Content" class="event_badge_main">
<h1>Badges</h1>
{#if $client.trusted_access || $ae_com.trusted_access }
<section class="event_badge_options">
{#if $ae_events.badges.enable_add_badge_btn && ($client.trusted_access || $ae_com.trusted_access) }
<button on:click={() => show_add_edit_event_badge_obj_form=true} class="ae_btn btn_sm btn_warning"><span class="fas fa-plus"></span> Add Attendee Badge</button>
{/if}
{#if $ae_events.badges.enable_upload_badge_li_btn && ($client.administrator_access || $ae_com.administrator_access) }
<button on:click={() => show_event_badge_list_upload_form=true} class="ae_btn btn_sm btn_warning"><span class="fas fa-upload"></span> Upload Badge List</button>
{/if}
</section>
{/if}
{#if $ae_events.badges.enable_mass_print && $client.administrator_access }
<section class="event_badge_list">
<!-- <h3>Badge Lists</h3> -->
<!-- <fieldset> -->
<!-- <legend style="text-align: center;">Badge Lists</legend> -->
<div>Badge Lists:
<div>
Not Marked as Printed:
<a href="badge/view_badge_list?badge_type_code=attendee" class="ae_btn btn_sm btn_primary"><span class="fas fa-list"></span> Attendee List</a>
<a href="badge/view_badge_list?badge_type_code=exhibitor" class="ae_btn btn_sm btn_primary"><span class="fas fa-list"></span> Exhibitors List</a>
<a href="badge/view_badge_list?badge_type_code=exhibit_only" class="ae_btn btn_sm btn_primary"><span class="fas fa-list"></span> Exhibit Only List</a>
<a href="badge/view_badge_list?badge_type_code=guest" class="ae_btn btn_sm btn_primary"><span class="fas fa-list"></span> Guest List</a>
<a href="badge/view_badge_list" class="ae_btn btn_sm btn_primary"><span class="fas fa-list"></span> All (Mixed)</a>
</div>
<div>
Marked as Printed:
<a href="badge/view_badge_list?badge_type_code=attendee&printed=printed" class="ae_btn btn_sm btn_default"><span class="fas fa-list"></span> Printed Attendee List</a>
<a href="badge/view_badge_list?badge_type_code=exhibitor&printed=printed" class="ae_btn btn_sm btn_default"><span class="fas fa-list"></span> Printed Exhibitors List</a>
<a href="badge/view_badge_list?badge_type_code=exhibit_only&printed=printed" class="ae_btn btn_sm btn_default"><span class="fas fa-list"></span> Printed Exhibit Only List</a>
<a href="badge/view_badge_list?badge_type_code=guest&printed=printed" class="ae_btn btn_sm btn_default"><span class="fas fa-list"></span> Printed Guest List</a>
</div>
</div>
<!-- </fieldset> -->
</section>
{/if}
<section class="event_badge_search">
<Event_badge_search_main>
<span slot="external_id_label">Record Number</span>
</Event_badge_search_main>
</section>
</section>
{#if show_add_edit_event_badge_obj_form}
<Element_modal_v3
show = { true }
modal_cover_body = { true }
on:close={ () => {show_add_edit_event_badge_obj_form = false;} }
>
<span slot="header_title">
Add or Edit Event Badge for Attendee
</span>
<!-- <span slot="header_text">
</span> -->
<span slot="body">
<Event_badge_obj_form event_badge_id=event_badge_edit_id use_badge_template_obj_list={$slct.event_badge_template_obj_li} />
</span>
<span slot="footer_text">
<div class="load_datetime"><span class="label">Loaded:</span> <span class="datetime">{new Date()}</span></div>
</span>
</Element_modal_v3>
{/if}
{#if show_event_badge_list_upload_form}
<Element_modal_v3
show = { true }
modal_cover_body = { true }
on:close={ () => {show_event_badge_list_upload_form=false;} }
>
<span slot="header_title">Badge List File Upload</span>
<span slot="body">
<Event_badge_upload_form on:event_badge_file_uploaded={handle_event_badge_file_uploaded} />
</span>
</Element_modal_v3>
{/if}
<style>
</style>

View File

@@ -0,0 +1,282 @@
<script lang="ts">
import { onMount } from 'svelte';
import { ae, Element_input } from 'aether_npm_lib';
import { cfg, client, page, slct, slct_trigger, ae_com } from '../../stores_mod_events';
// import {} from '../stores_event.js';
import { get_event_badge_search, email_event_badge_review_url } from '../stores_event_api.js';
export let event_id: string = $page['page_for']['event_id'];
$slct.event_id = event_id;
$slct_trigger = 'event';
let max_results: number = 10;
let search_badge_type_code: string = null;
let search_query_str: string = null;
// let search_given_name: string = null;
// let search_family_name: string = null;
// let search_email: string = null;
// let event_obj: object = null
// let event_obj_get_promise = null;
let event_badge_search_data: object = {};
let event_badge_obj_li_get_promise = null;
let event_badge_obj_li: object = null;
let show_event_badge_search_main: boolean = false;
let show_event_badge_view_main: boolean = false;
let event_badge_obj_get_promise = null;
// let event_badge_obj_get_promise = Promise.resolve([]);
let event_badge_qr_get_promise = null;
let event_badge_id_qr_get_promise = null;
let event_badge_all_promise = null;
let auto_select: boolean = null;
let auto_view: boolean = true;
let auto_search: boolean = true;
onMount(() => {
console.log('** Component Mounted: ** Event Badge Review Search Main');
});
$: if (!$ae_com.trusted_access || !$client.trusted_access) {
document.getElementById('Site-Nav-Menu').style.display = 'none';
} else {
document.getElementById('Site-Nav-Menu').style.display = 'flex';
}
async function handle_get_event_badge_search() {
console.log('*** handle_get_event_badge_search() ***');
let params = {};
if ($client.administrator_access || $ae_com.administrator_access) {
params['enabled'] = 'all';
params['hidden'] = 'all';
} else {
params['enabled'] = 'enabled';
}
event_badge_obj_li_get_promise = get_event_badge_search({event_id: $slct.event_id, type_code: search_badge_type_code, query_str: search_query_str, params: params});
event_badge_obj_li_get_promise.then(function (event_badge_obj_li_result) {
console.log('GET DONE get_event_badge_search');
console.log(event_badge_obj_li_result);
event_badge_obj_li = event_badge_obj_li_result;
return event_badge_obj_li_result;
})
.catch(function (error) {
console.log(error);
return false;
// return error;
});
}
function handle_cancel_form() {
console.log('*** handle_cancel_form() ***');
}
function handle_submit_form(event) {
console.log('*** handle_submit_form() ***');
}
function handle_oninput_search_query_str(event) {
console.log('*** handle_oninput_search_query_str() ***');
console.log(event);
search_query_str = event.detail.value.trim();
handle_get_event_badge_search();
}
async function handle_email_event_badge_review_url(event_badge_id) {
console.log('*** handle_email_event_badge_review_url() ***');
// let params = event_badge_search_data;
let params = {};
let root_url = $page.current_url_root;
let event_badge_obj_email_promise = await email_event_badge_review_url({event_badge_id:event_badge_id, root_url:root_url});
return event_badge_obj_email_promise;
}
$: if ($client.administrator_access || $ae_com.administrator_access) {
max_results = 150;
} else if ($client.trusted_access || $ae_com.trusted_access) {
max_results = 50;
} else {
max_results = 10;
}
</script>
<section id="Main-Content" class="event_badge_review_search_main search_and_results">
<h1>Review and Update Badge</h1>
<!-- {#if $client.administrator_access || $ae_com.administrator_access}
<div><a class="ae_btn btn_sm" href="event/ZDzTBlevhZs/badge"><span class="fas fa-print"></span> Badge Printing</a></div>
{/if} -->
<section class="search_options">
<form on:submit|preventDefault={handle_submit_form} on:keydown={e => e.key === 'Escape' && handle_cancel_form} class="search_form">
<!-- <label>Auto Search? <input type="checkbox" bind:checked={auto_search} value="true"></label> -->
<fieldset>
<legend>Attendee Search</legend>
<div class="search_fields">
<div class="search_by_text">
<Element_input {...ae.input_template.event_badge.search_query_str} value={search_query_str} use_name_prefix={true} content_layout={'floating_input'} container_class_li={['mb-1', 'col-md-12', 'col-lg-12']} focus={true} on:oninput={handle_oninput_search_query_str} />
</div>
</div>
<div class="how_to_message">
<ol>
<li>Start typing.</li>
<li>Results will appear as you type.</li>
<li>Click your name to send an email with a link to review your badge.</li>
</ol>
</div>
</fieldset>
</form>
</section>
<section class="search_results">
{#if (Array.isArray(event_badge_obj_li) && event_badge_obj_li.length <= max_results)}
<table class="ae_data table_borders table_alt_rows table_100w results_table">
<thead>
<tr>
<th>Email Badge Review URL</th>
<th>Details</th>
<!-- <th>Email</th> -->
<!-- <th>Affiliations or Location</th> -->
<!-- <th>Type</th> -->
</tr>
</thead>
<tbody>
{#each event_badge_obj_li.sort(ae.util.dynamic_sort_multiple('print_count ASC', 'given_name', 'family_name', 'created_on DESC', 'updated_on DESC')) as event_badge_obj, index}
<tr>
<td>
<div class="email_person_container">
<button
class="ae_btn btn_lg btn_primary email_badge_review_btn"
on:click={async () => {
if (confirm('Send email with URL to review this badge?')){
} else {
return false;
}
let emailing_promise = handle_email_event_badge_review_url(event_badge_obj.event_badge_id_random)
.then(function (result) {
alert('The email with the link to review this badge has been sent and should arrive within a few minutes.');
});
}}
>
<span class="fas fa-id-badge"></span>
<span class="fas fa-envelope"></span>
{#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.family_name}
{event_badge_obj.given_name} {event_badge_obj.family_name}
{:else if event_badge_obj.given_name}
{event_badge_obj.given_name}
{:else}
-- no name --
{/if}
{#if event_badge_obj.print_count >= 1}
<span class="print_count">{event_badge_obj.print_count}</span>
{/if}
</button>
{#if event_badge_obj.print_count >= 1}
<span class="badge_printed_container">
Badge Printed:
{ae.util.iso_datetime_formatter(event_badge_obj.print_last_datetime, 'week_long')}
@
{ae.util.iso_datetime_formatter(event_badge_obj.print_last_datetime, 'time_short_no_leading')}
</span>
{/if}
</div>
</td>
<td>
<div class="person_detail_container">
<span class="email">
<!-- <td class="fs_smaller"> -->
{#if event_badge_obj.email && event_badge_obj.email.length}
{event_badge_obj.email.substring(0,1)}<span class="asterisks">{'*'.repeat(event_badge_obj.email.indexOf('@')-2)}</span>{event_badge_obj.email.substring(event_badge_obj.email.indexOf('@')-1, event_badge_obj.email.indexOf('@'))}{@html event_badge_obj.email.substring(event_badge_obj.email.indexOf('@')).replace('@', '<wbr>@')}
{:else}
-- no email address --
{/if}
<!-- </td> -->
</span>
<span class="affiliations_location">
<!-- <td class="fs_smaller"> -->
{#if event_badge_obj.affiliations && event_badge_obj.affiliations.length}
{event_badge_obj.affiliations}
{:else if event_badge_obj.location}
{event_badge_obj.location}
{:else if event_badge_obj.city && event_badge_obj.state_province}
{event_badge_obj.city}, {event_badge_obj.state_province}
{:else if event_badge_obj.city}
{event_badge_obj.city}
{:else if event_badge_obj.state_province}
{event_badge_obj.state_province}
{:else}
<!-- -- no affiliations or location -- -->
{/if}
<!-- </td> -->
</span>
<span class="registration_type">
<!-- <td class="fs_smaller"> -->
<span title={event_badge_obj.registration_type}>{event_badge_obj.badge_type}</span>
<!-- </td> -->
</span>
</div>
</td>
</tr>
{/each}
</tbody>
</table>
{:else if (Array.isArray(event_badge_obj_li) && event_badge_obj_li.length > max_results)}
<div class="results_message warning"><span class="fas fa-search"></span> Too many results (max {max_results}). Please narrow down your search.</div>
{:else}
{#if search_query_str && search_query_str.length > 0}
<div class="results_message warning"><span class="fas fa-search"></span> No results.</div>
{/if}
{/if}
{#await event_badge_obj_li_get_promise}
searching...
{:then}
{#if event_badge_obj_li_get_promise}
<!-- done! -->
{:else}
<!-- nothing yet -->
{/if}
{/await}
</section>
</section>
<!-- <Access_type_element /> -->
<style>
</style>

View File

@@ -0,0 +1,457 @@
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';
import { each } from 'svelte/internal';
import { ae, Element_input, Element_modal_v3 } from 'aether_npm_lib';
import { page } from '../../stores_mod_events';
import { slct_event_badge_template_id, slct_event_badge_template_obj, slct_event_badge_template_obj_li } from '../stores_event.js';
import { load_event_badge_template_obj, get_event_badge_template_obj_li, update_event_badge_template_obj } from '../stores_event_api.js';
// let event_badge_template_obj_get_promise = undefined;
// let event_badge_template_obj_li_get_promise = undefined;
// let event_badge_template_obj_update_promise = undefined;
// let edit_event_badge_template_title: boolean = false;
// let event_badge_template_title: string = '';
// let edit_event_badge_template_body: boolean = false;
// let event_badge_template_body: string = '';
// let event_badge_template_obj = { event_badge_template_id_random: '', event_id_random: '', event_badge_template_title: '', event_badge_template_header: '', event_badge_template_body: '' };
let event_badge_template_obj_get_promise = undefined;
let event_badge_template_obj_li_get_promise = undefined;
let event_badge_template_obj_update_promise = undefined;
let slct_obj_prop: { obj_id: string, obj_type: string, name: string, value: any, index: number };
const dispatch = createEventDispatcher();
onMount(() => {
console.log('Event Badge Template Main component has mounted');
if ($page.page_for.event_id) {
handle_get_event_badge_template_obj_li($page.page_for.event_id);
}
});
async function handle_get_event_badge_template_obj_li(event_id) {
console.log('*** handle_get_event_badge_template_obj_li() ***');
let params = { };
event_badge_template_obj_li_get_promise = await get_event_badge_template_obj_li({ event_id: event_id, inc_event_badge_list: false, params: params, log_lvl: 2 });
slct_event_badge_template_obj_li.set(event_badge_template_obj_li_get_promise);
return $slct_event_badge_template_obj_li;
}
async function handle_update_event_badge_template_field(event_badge_template_id, field_name , value) {
console.log('*** handle_update_event_badge_template_field() ***');
console.log(`Field Name: ${field_name}; Value: ${value}`);
let data = {};
if (field_name) {
data[field_name] = value;
} else {
return false;
}
event_badge_template_obj_update_promise = await update_event_badge_template_obj({event_badge_template_id:event_badge_template_id, data: data, log_lvl: 2});
// event_badge_template_obj[field_name] = value;
// slct_event_badge_template_obj.set(event_badge_template_obj);
// console.log($slct_event_badge_template_obj);
dispatch(
'event_badge_template_obj_updated',
{
event_badge_template_id: event_badge_template_id,
// event_badge_template_obj: event_badge_template_obj,
}
);
return event_badge_template_obj_update_promise;
}
</script>
<section id="Main-Content" class="event_badge_template_main">
<head>
<h1>Manage Event Badge Templates</h1>
</head>
{#await event_badge_template_obj_li_get_promise}
Getting list...
{:then result}
{#if $slct_event_badge_template_obj_li}
<h2>Badge Template(s) for Event</h2>
{#each $slct_event_badge_template_obj_li as event_badge_template_obj, index}
{@const obj_template = ae.input_template.event_badge_template}
<section class="ae_obj obj_event_badge_template">
<h3>{event_badge_template_obj.name}</h3>
<div class="ae_prop prop_name">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.name.obj_type;
slct_obj_prop.name = obj_template.name.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.name;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.name.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.name}
<pre>{event_badge_template_obj.name}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_logo_path">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.logo_path.obj_type;
slct_obj_prop.name = obj_template.logo_path.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.logo_path;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.logo_path.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.logo_path}
<pre>{event_badge_template_obj.logo_path}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_header_path">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.header_path.obj_type;
slct_obj_prop.name = obj_template.header_path.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.header_path;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.header_path.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.header_path}
<pre>{event_badge_template_obj.header_path}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_secondary_header_path">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.secondary_header_path.obj_type;
slct_obj_prop.name = obj_template.secondary_header_path.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.secondary_header_path;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.secondary_header_path.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.secondary_header_path}
<pre>{event_badge_template_obj.secondary_header_path}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_layout">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.layout.obj_type;
slct_obj_prop.name = obj_template.layout.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.layout;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.layout.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.layout}
<pre>{event_badge_template_obj.layout}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_style_href">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.style_href.obj_type;
slct_obj_prop.name = obj_template.style_href.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.style_href;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.style_href.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.style_href}
<pre>{event_badge_template_obj.style_href}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_badge_type_list">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.badge_type_list.obj_type;
slct_obj_prop.name = obj_template.badge_type_list.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.badge_type_list;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.badge_type_list.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.badge_type_list}
<pre>{event_badge_template_obj.badge_type_list}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_wireless_ssid">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.wireless_ssid.obj_type;
slct_obj_prop.name = obj_template.wireless_ssid.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.wireless_ssid;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.wireless_ssid.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.wireless_ssid}
<pre>{event_badge_template_obj.wireless_ssid}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_wireless_password">
<button
on:click={() => {
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.wireless_password.obj_type;
slct_obj_prop.name = obj_template.wireless_password.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.wireless_password;
slct_obj_prop.index = index;
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.wireless_password.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.wireless_password}
<pre>{event_badge_template_obj.wireless_password}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_show_qr_front">
<button
on:click={() => {
console.log('HERE HERE HERE');
console.log(obj_template.show_qr_front);
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.show_qr_front.obj_type;
slct_obj_prop.name = obj_template.show_qr_front.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.show_qr_front;
slct_obj_prop.index = index;
console.log(slct_obj_prop);
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.show_qr_front.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.show_qr_front}
<pre>{event_badge_template_obj.show_qr_front}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
<div class="ae_prop prop_show_qr_back">
<button
on:click={() => {
console.log('HERE HERE HERE');
console.log(obj_template.show_qr_back);
slct_obj_prop = {};
slct_obj_prop.obj_id = event_badge_template_obj.event_badge_template_id_random;
slct_obj_prop.obj_type = obj_template.show_qr_back.obj_type;
slct_obj_prop.name = obj_template.show_qr_back.obj_prop_name;
slct_obj_prop.value = event_badge_template_obj.show_qr_back;
slct_obj_prop.index = index;
console.log(slct_obj_prop);
}}
class="ae_btn btn_sm btn_seamless show_modal_btn"
title="Show"
>
<span class="fas fa-expand"></span>
<span class="ae_btn_text">Show</span>
</button>
<span class="ae_prop_label">{obj_template.show_qr_back.label}:</span>
<span class="ae_prop_value">
{#if event_badge_template_obj.show_qr_back}
<pre>{event_badge_template_obj.show_qr_back}</pre>
{:else}
<span class="ae_prop_value_none">-- not set --</span>
{/if}
</span>
</div>
</section>
{/each}
{/if}
{/await}
</section>
{#if slct_obj_prop}
<Element_modal_v3
show={ true }
on:close={ () => {slct_obj_prop=null;} }
>
<span slot="header_title">Edit Property</span>
<span slot="body">
<!-- {@debug slct_obj_prop} -->
<Element_input
{...ae.input_template[slct_obj_prop.obj_type][slct_obj_prop.name]}
label=""
bind:value={slct_obj_prop.value}
use_name_prefix={true}
required
class_li={[]}
container_class_li={[]}
/>
<button
class="ae_btn btn_warning"
on:click={async () => {
let saving_promise = handle_update_event_badge_template_field(slct_obj_prop.obj_id, slct_obj_prop.name, slct_obj_prop.value)
.then(function (result) {
$slct_event_badge_template_obj_li[slct_obj_prop.index][slct_obj_prop.name] = slct_obj_prop.value
slct_obj_prop = null;
});
}}
>
{#await event_badge_template_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
</span>
</Element_modal_v3>
{/if}
<style>
</style>

View File

@@ -0,0 +1,155 @@
<script lang="ts">
import { onMount } from 'svelte';
import { ae, api, Element_modal_v3 } from 'aether_npm_lib';
import { account_id, cfg, client, page } from '../../stores_mod_events';
export let event_badge_id: string = null;
export let event_badge_obj = { event_badge_id_random: '', given_name: '', family_name: '', full_name: '', full_name_override: '', professional_title: '', affiliations: '', location: '', state_province: '', full_address: '', email: '', ticket_1_code: '', ticket_2_code: '', ticket_3_code: '', badge_type_code: '', allow_tracking: '', event_badge_template: { logo_path: '' } };
let event_badge_obj_get_promise = null;
// let event_badge_obj_get_promise = Promise.resolve([]);
let event_badge_qr_get_promise = null;
let event_badge_id_qr_get_promise = null;
let event_badge_all_promise = null;
let full_name = null;
let email = null;
let full_address = null;
/* BEGIN: Lifecycle functions (onMount, beforeUpdate, afterUpdate,
onDestroy, tick) */
onMount(async () => {
console.log('Event Badge Details component has mounted');
// if (event_badge_id) {
// event_badge_all_promise = await handle_load_event_badge_obj();
// }
let endpoint: string;
let params: object;
if (event_badge_obj.full_name) {
console.log(`Using full_name: ${event_badge_obj.full_name}`);
full_name = event_badge_obj.full_name;
} else if (event_badge_obj.full_name_override) {
console.log('Using full_name_override');
full_name = event_badge_obj.full_name_override;
} else if (event_badge_obj.given_name && event_badge_obj.family_name) {
console.log('Using given_name family_name');
full_name = `${event_badge_obj.given_name} ${event_badge_obj.family_name}`;
} else if (event_badge_obj.given_name) {
console.log('Using given_name');
full_name = `${event_badge_obj.given_name}`;
} else {
console.log('Using no name');
full_name = 'no name'
}
email = event_badge_obj.email;
full_address = event_badge_obj.full_address;
endpoint = `/event/qr_image/${event_badge_id}/gen_send`
params = {};
params['qr_type'] = 'mecard';
params['qr_send'] = false;
params['n'] = full_name;
params['email'] = email;
params['adr'] = full_address;
event_badge_qr_get_promise = await api.get_object({api_cfg:$cfg.app, endpoint: endpoint, params: params});
endpoint = `/event/qr_image/${event_badge_id}_event_badge_id/gen_send`
params = {};
params['qr_type'] = 'obj';
params['qr_send'] = false;
params['obj_type'] = 'event_badge';
params['obj_id'] = event_badge_id;
event_badge_id_qr_get_promise = await api.get_object({api_cfg:$cfg.app, endpoint: endpoint, params: params});
});
/* END: Lifecycle functions (onMount, beforeUpdate, afterUpdate,
onDestroy, tick) */
/* BEGIN: Handle requests (archive, create, hide, remove, select, update, POST, PATCH, GET, DELETE) */
async function handle_load_event_badge_obj() {
console.log('*** handle_load_event_badge_obj() ***');
let endpoint = '';
let params = {};
// let endpoint = `/event/badge/${event_badge_id}`;
// let params = { inc_event_badge_template: true };
// event_badge_obj_get_promise = await api.get_object({api_cfg: $cfg.api, endpoint: endpoint, params: params});
// event_badge_obj = event_badge_obj_get_promise;
if (event_badge_obj.full_name) {
console.log(`Using full_name: ${event_badge_obj.full_name}`);
full_name = event_badge_obj.full_name;
} else if (event_badge_obj.full_name_override) {
console.log('Using full_name_override');
full_name = event_badge_obj.full_name_override;
} else if (event_badge_obj.given_name && event_badge_obj.family_name) {
console.log('Using given_name family_name');
full_name = `${event_badge_obj.given_name} ${event_badge_obj.family_name}`;
} else if (event_badge_obj.given_name) {
console.log('Using given_name');
full_name = `${event_badge_obj.given_name}`;
} else {
console.log('Using no name');
full_name = 'no name'
}
email = event_badge_obj.email;
full_address = event_badge_obj.full_address;
endpoint = `/event/qr_image/${event_badge_id}/gen_send`
params = {};
params['qr_type'] = 'mecard';
params['qr_send'] = false;
params['n'] = full_name;
params['email'] = email;
params['adr'] = full_address;
event_badge_qr_get_promise = await api.get_object({api_cfg:$cfg.app, endpoint: endpoint, params: params});
endpoint = `/event/qr_image/${event_badge_id}_event_badge_id/gen_send`
params = {};
params['qr_type'] = 'obj';
params['qr_send'] = false;
params['obj_type'] = 'event_badge';
params['obj_id'] = event_badge_id;
event_badge_id_qr_get_promise = await api.get_object({api_cfg:$cfg.app, endpoint: endpoint, params: params});
}
/* END: Handle requests (archive, create, hide, remove, select, update, POST, PATCH, GET, DELETE) */
/* BEGIN: Handle children events (archived, canceled, closed, created, deleted, hidden, updated) */
/* END: Handle children events (archived, canceled, closed, created, deleted, hidden, updated) */
</script>
<!-- {#await event_badge_all_promise} -->
{#if event_badge_qr_get_promise && event_badge_id_qr_get_promise}
<section class="event_badge_details">
<div class="badge_person_name">
{full_name}
{email}
{full_address}
</div>
<div>
<div>{event_badge_obj.given_name}'s QR Code:</div>
<img class="person_information_qr" style="width: 1.00in;" src="/event/qr_image/{event_badge_obj.event_badge_id_random}" alt="missing person information QR code">
</div>
<div>
<div>Badge Lookup QR Code for {event_badge_obj.given_name}:</div>
<img class="person_information_qr" style="width: 1.00in;" src="/event/qr_image/{event_badge_obj.event_badge_id_random}_event_badge_id" alt="missing QR code">
</div>
</section>
{/if}
<!-- {/await} -->
<style>
</style>

View File

@@ -0,0 +1,543 @@
<script lang="ts">
// *** Import Svelte core
import { onMount } from 'svelte';
import { fade } from 'svelte/transition';
// *** Import Aether core variables and functions
import { ae, api, Element_modal_v3 } from 'aether_npm_lib';
// import { slct_event_id } from '../../event/stores_event.js';
import { create_event_badge_obj, create_event_person_obj } from '../../event/stores_event_api.js';
import { account_id, cfg, client, page, slct, slct_trigger, ae_events } from '../../stores_mod_events';
// export let event_id: string = $slct.event_id;
export let event_person_id: string = null;
export let event_badge_id: string = null;
// let event_badge_obj: object = null
// let event_badge_obj_get_promise = null;
let show_restricted_fields: boolean = false;
export let use_badge_template_obj_list: string|Array<{any;}> = [];
export let use_badge_type_code_list: string|Array<{code: string; name: string;}> = [];
export let use_badge_ticket_list: string|Array<{num: string; name: string;}> = [];
let badge_template_obj;
let use_badge_type_code_data;
let data_store_obj_get_promise = null;
// console.log(use_badge_type_code_list);
if (typeof use_badge_type_code_list == 'string') {
use_badge_type_code_list = JSON.parse(use_badge_type_code_list);
}
if (use_badge_type_code_list) {
} else {
use_badge_type_code_list = [];
use_badge_type_code_list.push({code: 'MBR', name: 'Member'});
use_badge_type_code_list.push({code: 'AHMB', name: 'Member'});
use_badge_type_code_list.push({code: 'SNMB', name: 'Student/Trainee Non-Member'});
use_badge_type_code_list.push({code: 'SMBR', name: 'Student/Trainee Member'});
use_badge_type_code_list.push({code: 'NMBR', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'ANHM', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'INMB', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'EXO', name: 'Exhibitor Booth Staff'});
use_badge_type_code_list.push({code: 'EXALL', name: 'Exhibitor All Access'});
use_badge_type_code_list.push({code: 'GUEST', name: 'Guest'});
use_badge_type_code_list.push({code: 'HEART', name: 'HFTX Core'});
use_badge_type_code_list.push({code: 'LUNG', name: 'LTX Core'});
use_badge_type_code_list.push({code: 'STAFF', name: 'Staff'});
use_badge_type_code_list.push({code: 'VIP', name: 'VIP'});
use_badge_type_code_list.push({code: 'VOL', name: 'Volunteer'});
}
// console.log(use_badge_ticket_list);
if (typeof use_badge_ticket_list == 'string') {
use_badge_ticket_list = JSON.parse(use_badge_ticket_list);
}
if (use_badge_ticket_list) {
} else {
use_badge_ticket_list = [];
use_badge_ticket_list.push({num: 1, name: 'Placeholder 1'});
use_badge_ticket_list.push({num: 2, name: 'Placeholder 2'});
use_badge_ticket_list.push({num: 3, name: 'Placeholder 3'});
}
let get_ds_event_launcher_main_info_promise = handle_get_data_store_obj_w_code('event_badge_add_help_staff');
onMount(() => {
console.log('** Component Mounted: ** Event Badge Form');
if (event_badge_id) {
handle_load_event_badge_obj();
}
});
$: if (badge_template_obj) {
console.log(badge_template_obj);
$slct.event_badge_template_obj = badge_template_obj;
$slct.event_badge_template_id = badge_template_obj.event_badge_template_id_random;
use_badge_type_code_list = badge_template_obj.badge_type_list;
use_badge_ticket_list = badge_template_obj.ticket_list
}
async function handle_get_data_store_obj_w_code(code) {
console.log('*** handle_get_data_store_obj_w_code() ***');
// let get_item_result = window.localStorage.getItem(code);
if ($ae_events.badges.ds[code]) {
// $ae_events.badges.ds[code] = get_item_result;
} else {
console.log('Get local storage item miss.');
}
data_store_obj_get_promise = api.get_data_store_obj_w_code({api_cfg: $cfg.api, data_store_code:code, log_lvl: 1})
.then(function (get_data_store_result) {
if (get_data_store_result) {
// console.log(get_data_store_result.text);
$ae_events.badges.ds[code] = get_data_store_result.text;
// window.localStorage.setItem(code, get_data_store_result.text);
// console.log(`Code: ${$ae_events.badges.ds[code]}`);
// console.log(`Code:`, $ae_events.badges.ds[code]);
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
}
async function handle_load_event_badge_obj() {
console.log('*** handle_load_event_badge_obj() ***');
// let endpoint = `/event/badge/${event_badge_id}`;
// let params = { inc_event_badge_template: true };
// event_badge_obj_get_promise = await api.get_object({api_cfg: $cfg.api, endpoint: endpoint, params: params});
// event_badge_obj = event_badge_obj_get_promise;
}
async function handle_submit_form(event) {
console.log('*** handle_submit_form() ***');
if (confirm('Add new badge?')) {
} else {
console.log(event.target);
return false;
}
let event_person_data = {};
event_person_data['event_id_random'] = $slct.event_id;
event_person_data['external_id'] = ae.util.value_try_null(event.target.external_id.value);
event_person_data['external_event_id'] = ae.util.value_try_null(event.target.external_event_id.value);
event_person_data['external_registration_id'] = ae.util.value_try_null(event.target.external_registration_id.value);
event_person_data['external_person_id'] = ae.util.value_try_null(event.target.external_person_id.value);
let event_badge_data = {};
event_badge_data['external_id'] = ae.util.value_try_null(event.target.external_id.value);
event_badge_data['external_event_id'] = ae.util.value_try_null(event.target.external_event_id.value);
event_badge_data['external_registration_id'] = ae.util.value_try_null(event.target.external_registration_id.value);
event_badge_data['external_person_id'] = ae.util.value_try_null(event.target.external_person_id.value);
event_badge_data['informal_name'] = ae.util.value_try_null(event.target.informal_name.value);
event_badge_data['given_name'] = ae.util.value_try_null(event.target.given_name.value);
event_badge_data['middle_name'] = ae.util.value_try_null(event.target.middle_name.value);
event_badge_data['family_name'] = ae.util.value_try_null(event.target.family_name.value);
event_badge_data['affiliations'] = ae.util.value_try_null(event.target.affiliations.value);
event_badge_data['email'] = ae.util.value_try_null(event.target.email.value);
event_badge_data['phone'] = ae.util.value_try_null(event.target.phone.value);
event_badge_data['address_line_1'] = ae.util.value_try_null(event.target.address_line_1.value);
event_badge_data['address_line_2'] = ae.util.value_try_null(event.target.address_line_2.value);
event_badge_data['address_line_3'] = ae.util.value_try_null(event.target.address_line_3.value);
event_badge_data['city'] = ae.util.value_try_null(event.target.city.value);
event_badge_data['state_province'] = ae.util.value_try_null(event.target.state_province.value);
event_badge_data['postal_code'] = ae.util.value_try_null(event.target.postal_code.value);
event_badge_data['country'] = ae.util.value_try_null(event.target.country.value);
// event_badge_data['badge_type_code'] = ae.util.value_try_null(event.target.badge_type_code.value);
event_badge_data['badge_type_code'] = use_badge_type_code_data.code;
event_badge_data['badge_type'] = use_badge_type_code_data.name;
if (event.target.ticket_1_code && event.target.ticket_1_code.checked) {
event_badge_data['ticket_1_code'] = event.target.ticket_1_code.value;
}
if (event?.target.ticket_2_code && event.target.ticket_2_code.checked) {
event_badge_data['ticket_2_code'] = event.target.ticket_2_code.value;
}
if (event?.target.ticket_3_code && event.target.ticket_3_code.checked) {
event_badge_data['ticket_3_code'] = event.target.ticket_3_code.value;
}
if (event.target.ticket_4_code) {
event_badge_data['ticket_4_code'] = ae.util.value_try_null(event.target.ticket_4_code.value);
}
// event_badge_data['ticket_5_code'] = ae.util.value_try_null(event.target.ticket_5_code.value);
// event_badge_data['ticket_6_code'] = ae.util.value_try_null(event.target.ticket_6_code.value);
// event_badge_data['ticket_7_code'] = ae.util.value_try_null(event.target.ticket_7_code.value);
// event_badge_data['ticket_8_code'] = ae.util.value_try_null(event.target.ticket_8_code.value);
event_badge_data['event_id_random_only'] = $slct.event_id;
event_badge_data['event_badge_template_id_random'] = $slct.event_badge_template_id // 'zulVBBpyCQw'; // 7;
// console.log(event_badge_data);
event_person_data['event_badge'] = event_badge_data;
let create_event_person_obj_promise = await create_event_person_obj({ event_id: $slct.event_id, data: event_person_data, inc_event_badge: false, return_obj: true, log_lvl: 1 });
console.log(create_event_person_obj_promise);
if (create_event_person_obj_promise) {
$slct.event_person_obj = create_event_person_obj_promise;
$slct.event_person_id = $slct.event_person_obj.event_person_id_random;
$slct.event_badge_id = $slct.event_person_obj.event_badge_id_random;
// $slct.event_badge_id = $slct.event_person_obj.event_badge.event_badge_id_random; // NOTE: This also works if inc_event_badge is true.
// alert('New Badge Created');
if (confirm('A new badge was created. View new badge?')) {
window.location.href = `/event/badge/view_badge?event_badge_id=${$slct.event_badge_id}`;
}
}
}
function handle_cancel_form() {}
// function handle_form_oninput() {
// console.log('*** handle_form_oninput() ***');
// let event_badge_data = {};
// if (external_id) {
// event_badge_data['external_id'] = external_id.trim();
// }
// if (given_name) {
// event_badge_data['given_name'] = given_name.trim();
// }
// if (family_name) {
// event_badge_data['family_name'] = family_name.trim();
// }
// if (email) {
// event_badge_data['email'] = email.trim();
// } else {
// }
// if (event_badge_id) {
// handle_create_event_badge_obj(event_badge_data);
// } else {
// handle_update_event_badge_obj(event_badge_data);
// }
// }
</script>
<section class="svelte event_badge_form-component">
{#if $ae_events.badges.show_add_badge_help}
<div
class="add_badge_help"
transition:fade="{{ duration: 500 }}"
>
<button
on:click={() => {
$ae_events.badges.show_add_badge_help = false;
}}
class="ae_btn btn_sm btn_info add_badge_help_hide_btn"
>
<span class="fas fa-window-close"></span> Hide Help
</button>
<h2 class="text_align_center">Help</h2>
{#if $ae_events.badges.ds.event_badge_add_help_staff}
{@html $ae_events.badges.ds.event_badge_add_help_staff}
{:else}
<h3>Add Badge</h3>
<ol>
<li>Be sure the correct template is selected. The default is usually what you want.</li>
<li>Only the given/first name and badge type are required.</li>
<li>Ignore the external ID fields unless asked to use them.</li>
<li>Press the "Create Badge" button when ready.</li>
</ol>
<h3>Viewing New Badge</h3>
<ul>
<li>You will be able to make changes after the badge has been created.</li>
<li>When you press the "Create Badge" button you will be asked to confirm before it is created.</li>
<li>When you press the "Create Badge" button and the badge has been created, you will be asked if you want to view the badge or stay on this badge creation form.</li>
</ul>
{/if}
</div>
<!-- {:else} -->
{/if}
<button
on:click={() => {
$ae_events.badges.show_add_badge_help = !$ae_events.badges.show_add_badge_help;
}}
class:d_none={$ae_events.badges.show_add_badge_help}
class="ae_btn btn_sm btn_info add_badge_help_btn float_right"
>
<span class="fas fa-question"></span> Help
</button>
<form on:submit|preventDefault={handle_submit_form} on:keydown={e => e.key === 'Escape' && handle_cancel_form} class="flex_row flex_gap_lg">
<fieldset class="form_content_group flex_row flex_gap_md width_100">
{#if use_badge_template_obj_list}
<select
name="event_badge_template_id"
class=""
required
style=""
bind:value={badge_template_obj}
>
{#each use_badge_template_obj_list as use_badge_template_obj }
<option value={use_badge_template_obj}>{use_badge_template_obj.name}</option>
<!-- <option value={use_badge_template_obj.event_badge_template_id_random}>{use_badge_template_obj.name}</option> -->
{/each}
</select>
{/if}
</fieldset>
<input type="hidden" name="event_id_random" value="{ $slct.event_id }">
<input type="hidden" name="event_person_id_random" value="{ event_person_id }">
<input type="hidden" name="event_badge_id_random" value="{ event_badge_id }">
<fieldset class="form_content_group flex_col flex_gap_md width_md fs_smaller">
<legend>IDs</legend>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="external_id" class="">External/Record ID:</label>
<input type="text" name="external_id" id="external_id" value="" placeholder="External/Record ID" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="external_event_id" class="">External Event ID:</label>
<input type="text" name="external_event_id" id="external_event_id" value="" placeholder="External Event ID" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="external_registration_id" class="">External Registration ID:</label>
<input type="text" name="external_registration_id" id="external_registration_id" value="" placeholder="External Registration ID" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="external_person_id" class="">External Person ID:</label>
<input type="text" name="external_person_id" id="external_person_id" value="" placeholder="External Person ID" class="">
</div>
</fieldset>
<fieldset class="form_content_group flex_col flex_gap_md width_lg">
<legend>Person's Name Parts</legend>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="informal_name" class="">Informal Name:</label>
<input type="text" name="informal_name" id="informal_name" value="" placeholder="Informal/Nick name" class="">
</div>
<!-- NOTE: LastPass affects the layout of this field for some reason. -->
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="given_name" class="">Given Name:</label>
<input type="text" name="given_name" id="given_name" value="" placeholder="Given/First name" class="" required>
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="middle_name" class="">Middle:</label>
<input type="text" name="middle_name" id="middle_name" value="" placeholder="Middle name" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="family_name" class="">Family Name:</label>
<input type="text" name="family_name" id="family_name" value="" placeholder="Family/Last name" class="">
</div>
<!-- <div class="form_data_group">
<label for="title_names" class="">Titles:</label>
<input type="text" name="title_names" id="title_names" value="" placeholder="Title names" class="">
</div>
</div>
</div> -->
<!-- <div class="form_data_group">
<label for="designations" class="">Designations/Credentials:</label>
<input type="text" name="designations" id="designations" value="" placeholder="Designations/Credentials" class="">
</div>
</div>
</div> -->
<!-- <div class="form_data_group">
<label for="pronouns" class="">Preferred Pronouns:</label>
<input type="text" name="pronouns" id="pronouns" value="" placeholder="Preferred pronouns" class="">
</div>
</div>
</div> -->
</fieldset>
<fieldset class="form_content_group flex_col flex_gap_md width_lg">
<legend>Affiliations and Contact</legend>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="affiliations" class="">Affiliations:</label>
<input type="text" name="affiliations" id="affiliations" value="" placeholder="affiliations" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="email" class="">Email:</label>
<input type="email" name="email" id="email" value="" placeholder="email" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="phone" class="">Phone:</label>
<input type="phone" name="phone" id="phone" value="" placeholder="phone" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="address_line_1" class="">Street Address:</label>
<input type="text" name="address_line_1" id="address_line_1" value="" placeholder="address line 1" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="address_line_2" class="">Address Line 2:</label>
<input type="text" name="address_line_2" id="address_line_2" value="" placeholder="address line 2" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="address_line_3" class="">Address Line 3:</label>
<input type="text" name="address_line_3" id="address_line_3" value="" placeholder="address line 3" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="city" class="">City:</label>
<input type="text" name="city" id="city" value="" placeholder="city" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="state_province" class="">State/Province:</label>
<input type="text" name="state_province" id="state_province" value="" placeholder="state/province" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="postal_code" class="">Postal Code:</label>
<input type="text" name="postal_code" id="postal_code" value="" placeholder="postal code" class="">
</div>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<label for="country" class="">Country:</label>
<input type="text" name="country" id="country" value="" placeholder="country" class="">
</div>
</fieldset>
<fieldset class="form_content_group flex_col flex_gap_md width_lg">
<legend>Badge Options</legend>
<div class="form_data_group flex_row flex_gap_md flex_justify_between">
<div>
<label for="select_footer" class="">Badge Type:</label>
{#if use_badge_type_code_list}
<select
name="badge_type_code"
class="width_match_input"
required
style=""
bind:value={use_badge_type_code_data}
>
{#each use_badge_type_code_list as use_badge_type_code }
<option value={use_badge_type_code}>{use_badge_type_code.name}</option>
{/each}
</select>
{/if}
</div>
<section class="event_badge_ticket_options">
<ul class="btn_list">
{#each use_badge_ticket_list as ticket_option }
<li>
<label>
<input type="checkbox" name={`ticket_${ticket_option.num}_code`} value={ticket_option.code}>
<span class="ticket_option_name">{ticket_option.name}</span>
</label>
</li>
{/each}
</ul>
</section>
</div>
<!-- <div class="form-group form-group-lg">
<div class="col-md-12">
<label for="select_footer" class="col-md-3 control-label">Member Type</label>
<div class="col-md-6">
<select name="member_type_code" class="form-control" required>
<option value="member">Member</option>
<option value="member_affiliate">Affiliate Member</option>
<option value="member_emeritus">Emeritus Member</option>
<option value="member_international">International Member</option>
<option value="member_student">Student Member</option>
<option value="non-member">Non-Member</option>
<option value="invited_speaker">Invited Speaker</option>
<option value="guest">Guest</option>
<option value="exhibitor">Exhibitor</option>
<option value="press">Press</option>
<option value="staff">Staff</option>
<option value="volunteer">Volunteer</option>
</select>
</div>
</div>
</div> -->
<!-- <div class="form-group form-group-lg">
<div class="col-md-12">
<label for="ticket_1_code" class="col-md-3 control-label">Banquet Ticket:</label>
<div class="col-md-6">
<input type="checkbox" name="ticket_1_code" id="ticket_1_code" value="banquet" class="form-control">
</div>
</div>
</div> -->
<!-- <div class="form-group form-group-lg">
<div class="col-md-12">
<label for="ticket_2_code" class="col-md-3 control-label">VIP Tickets:</label>
<div class="col-md-6">
<input type="checkbox" name="ticket_2_code" id="ticket_2_code" value="vip" class="form-control">
</div>
</div>
</div> -->
</fieldset>
<section class="form_content_group">
<button type="submit" class="ae_btn btn_primary"><span class="fas fa-plus"></span> Create Badge</button>
</section>
</form>
</section>
<style>
</style>

View File

@@ -0,0 +1,792 @@
<script lang="ts">
import { onMount } from 'svelte';
import { ae, api, Element_input, Element_modal_v3 } from 'aether_npm_lib';
// import Element_modal_v3 as Element_modal_v3 from 'aether_npm_lib';
import { account_id, cfg, client, page, slct, slct_trigger, ae_com } from '../../stores_mod_events';
// import {} from '../../event/stores_event.js';
import { load_event_badge_obj, update_event_badge_obj, create_event_badge_obj } from '../../event/stores_event_api.js';
export let set_event_badge_id: string = $page['page_for']['event_badge_id'];
export let event_badge_id: string = $page['page_for']['event_badge_id'];
let initial_loading_promise = null;
export let event_badge_obj = { event_badge_id_random: '', given_name: '', family_name: '', full_name: '', full_name_override: '', professional_title: '', affiliations: '', location: '', state_province: '', full_address: '', email: '', ticket_1_code: '', ticket_2_code: '', ticket_3_code: '', badge_type_code: '', allow_tracking: '', event_badge_template: { logo_path: '' } };
$slct.event_badge_id = $page['page_for']['event_badge_id'];
let event_badge_obj_load_promise = null;
let event_badge_obj_update_promise = null;
let event_badge_obj_create_promise = null;
let event_badge_qr_mecard_get_promise = null;
let event_badge_qr_id_get_promise = null;
let show_event_badge_tools_modal: boolean = false;
let show_restricted_fields: boolean = false;
let allow_tracking: boolean = null;
let show_allow_tracking: boolean = true;
let edit_full_name_override = false;
let edit_professional_title_override = false;
let edit_affiliations_override = false;
let edit_location_override = false;
let full_name_override = null; // Usually set by the person or similar
let longest_full_name_override_part = 0;
let full_name = null; // Usually auto generated
let professional_title_override = null;
let longest_professional_title_override_part = 0;
let affiliations_override = null;
let longest_affiliations_override_part = 0;
let location_override = null;
let longest_location_override_part = 0;
let event_badge_obj_id_qr_img_src_promise;
let event_badge_obj_id_qr_img_src = null;
onMount(() => {
console.log('** Component Mounted: ** Event Badge Review Badge');
if ($slct.event_badge_id) {
$slct_trigger = 'event_badge';
} else {
console.log('Missing event badge ID.');
return false;
}
});
$: if ($slct_trigger == 'event_badge' && $slct.event_badge_id) {
console.log(`Selected Event Badge: ${$slct.event_badge_id}`);
$slct_trigger = null;
handle_load_event_badge_obj({event_badge_id: $slct.event_badge_id});
}
// $: $slct.event_badge_id, handle_load_event_badge_obj($slct.event_badge_id);
// $: if ($slct.event_badge_id) {
// initial_loading_promise = handle_load_event_badge_obj($slct.event_badge_id);
// } else {
// console.log('No value');
// }
async function handle_load_event_badge_obj({event_badge_id=null, try_cache=true}) {
console.log('*** handle_load_event_badge_obj() ***');
console.log(`Event Badge ID: ${event_badge_id}`);
event_badge_obj_load_promise = await load_event_badge_obj({event_badge_id:event_badge_id, inc_event_badge_template:true, log_lvl: 2});
// event_badge_obj = event_badge_obj_load_promise;
$slct.event_badge_obj = event_badge_obj_load_promise;
console.log(`Allow Tracking: ${$slct.event_badge_obj.allow_tracking}`);
if ($slct.event_badge_obj.allow_tracking) {
console.log('Attendee tracking is allowed');
show_allow_tracking = false;
allow_tracking = true;
} else {
console.log('Attendee tracking is not allowed');
show_allow_tracking = true;
allow_tracking = false;
}
// let full_name_override_array = [];
console.log($slct.event_badge_obj);
if ($slct.event_badge_obj.full_name_override) {
console.log('Using full_name_override');
full_name_override = $slct.event_badge_obj.full_name_override.trim();
} else if (1==2 && $slct.event_badge_obj.full_name) {
// console.log('Using full_name');
// full_name_override = $slct.event_badge_obj.full_name.trim();
} else if (1==2 && $slct.event_badge_obj.title_names && $slct.event_badge_obj.given_name && $slct.event_badge_obj.family_name && $slct.event_badge_obj.designations) {
console.log('Using title_names given_name family_name designations');
full_name_override = `${$slct.event_badge_obj.title_names.trim()} ${$slct.event_badge_obj.given_name.trim()} ${$slct.event_badge_obj.family_name.trim()} ${$slct.event_badge_obj.designations.trim()}`;
} else if ($slct.event_badge_obj.given_name && $slct.event_badge_obj.family_name && $slct.event_badge_obj.designations) {
console.log('Using given_name family_name designations');
full_name_override = `${$slct.event_badge_obj.given_name.trim()} ${$slct.event_badge_obj.family_name.trim()} ${$slct.event_badge_obj.designations.trim()}`;
} else if ($slct.event_badge_obj.given_name && $slct.event_badge_obj.family_name) {
console.log('Using given_name family_name');
full_name_override = `${$slct.event_badge_obj.given_name.trim()} ${$slct.event_badge_obj.family_name.trim()}`;
} else if ($slct.event_badge_obj.given_name) {
console.log('Using given_name');
full_name_override = `${$slct.event_badge_obj.given_name.trim()}`;
} else {
console.log('Using no name');
// full_name_override = '-- no name --';
full_name_override = '';
}
console.log(`Using "${full_name_override}" as full name`);
// Find the longest part of the person's name to help with the font size.
// full_name_override_array = full_name_override.split(' ');
// for (let i = 0; i < full_name_override_array.length; i++) {
// console.log(full_name_override_array[i]);
// if (full_name_override_array[i].length > longest_full_name_override_part) {
// longest_full_name_override_part = full_name_override_array[i].length;
// }
// }
if ($slct.event_badge_obj.professional_title_override) {
console.log('Using professional_title_override');
professional_title_override = $slct.event_badge_obj.professional_title_override.trim();
} else if ($slct.event_badge_obj.professional_title) {
console.log('Using professional_title');
professional_title_override = $slct.event_badge_obj.professional_title.trim();
} else {
console.log('Using no professional title');
// full_name_override = '-- no professional title --';
professional_title_override = '';
}
if ($slct.event_badge_obj.affiliations_override) {
console.log('Using affiliations_override');
affiliations_override = $slct.event_badge_obj.affiliations_override.trim();
} else if ($slct.event_badge_obj.affiliations) {
console.log('Using affiliations');
affiliations_override = $slct.event_badge_obj.affiliations.trim();
} else {
console.log('Using no affiliations');
// affiliations_override = '-- no affiliations --';
affiliations_override = '';
}
if ($slct.event_badge_obj.location_override) {
console.log('Using location_override');
location_override = $slct.event_badge_obj.location_override.trim();
} else if ($slct.event_badge_obj.location) {
console.log('Using location');
location_override = `${$slct.event_badge_obj.location.trim()}`;
} else if ($slct.event_badge_obj.city) {
console.log('Using city');
location_override = `${$slct.event_badge_obj.city.trim()}`;
} else if ($slct.event_badge_obj.city && $slct.event_badge_obj.state_province) {
console.log('Using city and state_province');
location_override = `${$slct.event_badge_obj.city.trim()}, ${$slct.event_badge_obj.state_province.trim()}`;
} else if ($slct.event_badge_obj.state_province_abb && $slct.event_badge_obj.country) {
console.log('Using state_province_abb and country');
location_override = `${$slct.event_badge_obj.state_province_abb.trim()}, ${$slct.event_badge_obj.country.trim()}`;
} else {
console.log('Using no location');
// location_override = '-- no location --';
location_override = '';
}
event_badge_obj_id_qr_img_src_promise = generate_qr_code({ qr_type: 'obj', qr_id: event_badge_id, obj_type: 'event_badge', obj_id: event_badge_id }).then(function (result) {
console.log(result);
event_badge_obj_id_qr_img_src = result;
return result;
})
.catch(function (error) {
console.log('Something went wrong.');
console.log(error);
return false;
});
let endpoint = `/event/qr_image/event_badge_obj_${event_badge_id}/gen_send`;
console.log(endpoint);
let params = {};
params['qr_type'] = 'obj';
params['qr_send'] = false;
params['obj_type'] = 'event_badge';
params['obj_id'] = event_badge_id;
console.log(params);
event_badge_qr_id_get_promise = api.get_object({api_cfg:$cfg.app, endpoint: endpoint, params: params, log_lvl: 2})
.then(async function (tbl_event_exhibit_tracking_get_result) {
console.log('QR Badge ID done');
})
.catch(function (error) {
console.log('Something went wrong while creating the QR code.');
console.log(error);
});
let event_badge_reviewed_list = JSON.parse(localStorage.getItem('event_badge_reviewed_list'));
// console.log(event_badge_reviewed_list);
if (event_badge_reviewed_list && event_badge_reviewed_list.includes($slct.event_badge_obj.event_badge_id_random)) {
console.log('Already reviewed badge.');
} else if (event_badge_reviewed_list && !event_badge_reviewed_list.includes($slct.event_badge_obj.event_badge_id_random)) {
console.log('Adding badge to reviewed list.');
event_badge_reviewed_list.push($slct.event_badge_obj.event_badge_id_random);
localStorage.setItem('event_badge_reviewed_list', JSON.stringify(event_badge_reviewed_list));
} else {
console.log('Starting new badge reviewed list. Adding badge to reviewed list.');
event_badge_reviewed_list = [];
event_badge_reviewed_list.push($slct.event_badge_obj.event_badge_id_random);
localStorage.setItem('event_badge_reviewed_list', JSON.stringify(event_badge_reviewed_list));
}
}
async function handle_update_allow_tracking(event_badge_id, allow) {
console.log('*** handle_update_allow_tracking() ***');
console.log(`Allow Tracking: ${allow}`);
let data = {};
data['allow_tracking'] = allow;
event_badge_obj_update_promise = await update_event_badge_obj({event_badge_id:event_badge_id, data: data, log_lvl: 2});
// $slct.event_badge_obj = event_badge_obj_update_promise;
if (allow) {
console.log('Attendee tracking is allowed');
// show_allow_tracking = false;
allow_tracking = true;
} else {
console.log('Attendee tracking is not allowed');
// show_allow_tracking = true;
allow_tracking = false;
}
}
async function handle_update_badge_field(event_badge_id, field_name , value) {
console.log('*** handle_update_badge_field() ***');
console.log(`Field Name: ${field_name}; Value: ${value}`);
// ticket_x_code
let data = {};
if (field_name) {
data[field_name] = value;
} else {
return false;
}
event_badge_obj_update_promise = update_event_badge_obj({event_badge_id: event_badge_id, data: data, log_lvl: 2});
$slct.event_badge_obj[field_name] = value;
return event_badge_obj_update_promise;
}
async function generate_qr_code({qr_type, qr_id, obj_type=null, obj_id=null}) {
console.log('*** generate_qr_code() ***');
let filename = `qr_${$client.account_id}_${qr_id}.png`;
let return_blob = true;
let endpoint = `/qr/${$account_id}/${qr_id}`;
console.log('Endpoint', endpoint);
let params = {};
params['regen'] = true; // Regenerate the file even if nothing has changed.
params['return_file'] = return_blob;
if (qr_type == 'obj') {
params['qr_type'] = 'obj'; // mecard, obj, vcard
params['qr_send'] = return_blob;
params['obj_type'] = obj_type;
params['obj_id'] = obj_id;
console.log('Params', params);
filename = `qr_${$client.account_id}_${qr_id}_obj.png`;
}
let generate_qr_id_get_promise;
generate_qr_id_get_promise = await api.get_object({ api_cfg: $cfg.api, endpoint: endpoint, params: params, return_blob: return_blob, filename: filename, auto_download: false, log_lvl: 1 });
console.log('QR done?');
let file_blob = new Blob([generate_qr_id_get_promise.data]);
// console.log(file_blob);
let file_obj_url = URL.createObjectURL(file_blob); // The img src
return file_obj_url;
}
</script>
<svelte:head>
{#if event_badge_obj_load_promise}
<!-- <link rel="stylesheet" href="{$slct.event_badge_obj.event_badge_template.style_href}"> -->
{/if}
</svelte:head>
<section class="event_badge_review_badge" id="event_badge_{$slct.event_badge_obj.event_badge_id_random}">
{#await initial_loading_promise}
<header>
<h1>Loading badge data...</h1>
</header>
{:then}
<header>
<h1>Review
{#if $slct.event_badge_obj.given_name}
<span class="full_name_override">
{@html $slct.event_badge_obj.given_name.trim()}
{@html $slct.event_badge_obj.family_name.trim()}'s
</span>
{:else}
-- no name --
{/if}
Badge
</h1>
</header>
{/await}
{#if event_badge_obj_load_promise}
<!-- <header>
<h2>Details For Badge</h2>
</header> -->
<section class="badge_details badge_type__{$slct.event_badge_obj.badge_type_code.toLowerCase()}">
<div class="qr_badge_id">
<div class="qr_badge_id_label">
{$slct.event_badge_obj.given_name}'s QR Code
</div>
{#await event_badge_obj_id_qr_img_src_promise}
Generating...
{:then result}
{#if event_badge_obj_id_qr_img_src}
<img
class="qr_code qr_event_badge_id"
src={event_badge_obj_id_qr_img_src}
alt="missing QR code"
/>
{/if}
{/await}
</div>
<!-- <div class="event_badge_changes">
<h2>Badge Changes</h2>
<div class="">
If you need to change your display name, degrees/credentials, affiliations, or location please talk to a staff person.
</div>
</div> -->
<div class="badge_type">
<span class="label">Badge Type:</span>
<span class="value badge_type">
<!-- {#if $slct.event_badge_obj.title_names}<span class="title_names">{$slct.event_badge_obj.title_names}</span>{/if} -->
<span class="badge_type">
{#if $slct.event_badge_obj.badge_type}
{$slct.event_badge_obj.badge_type.trim()}
{:else}
<span class="value_none">-- not set --</span>
{/if}
</span>
<!-- {#if $slct.event_badge_obj.designations}<span class="designations">{$slct.event_badge_obj.designations}</span>{/if} -->
</span>
</div>
<div class="person_name">
<span class="label">Display Name:</span>
<span class="value full_name_override_all">
<!-- {#if $slct.event_badge_obj.title_names}<span class="title_names">{$slct.event_badge_obj.title_names}</span>{/if} -->
<span class="full_name_override" class:d-none={edit_full_name_override}>
{#if full_name_override}
{@html full_name_override.trim()}
{:else}
<span class="value_none">-- no name --</span>
{/if}
</span>
<!-- {#if $slct.event_badge_obj.designations}<span class="designations">{$slct.event_badge_obj.designations}</span>{/if} -->
</span>
<span class="edit_container">
{#if edit_full_name_override}
<Element_input
{...ae.input_template.event_badge.full_name_override}
label=""
bind:value={full_name_override}
use_name_prefix={true}
required
class_li={[]}
container_class_li={[]}
/>
<button
class="ae_btn btn_warning"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'full_name_override', full_name_override)
.then(function (result) {
// edit_title_names = false;
edit_full_name_override = false;
// edit_designations = false;
});
}}
>
{#await event_badge_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
<button
class="ae_btn btn_sm btn_default"
on:click={async () => {
edit_full_name_override = false;
}}
>
<span class="fas fa-window-close"></span> Cancel
</button>
{:else}
<button
class="ae_btn btn_secondary"
on:click={() => {
// edit_title_names = true;
edit_full_name_override = true;
// edit_designations = true;
}}
class:d-none={edit_full_name_override}
>
<span class="fas fa-edit"></span> Edit
</button>
{/if}
{#if $slct.event_badge_obj.full_name_override}
<button
class="ae_btn btn_sm btn_default"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'full_name_override', null)
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span> Reset
</button>
{/if}
</span>
</div>
<div class="professional_title">
<span class="label">Degrees/Credentials:</span>
<span class="value professional_title" class:d-none={edit_professional_title_override}>
{#if professional_title_override}
{@html professional_title_override}
{:else}
<span class="value_none">-- not set --</span>
{/if}
</span>
<span class="edit_container">
{#if edit_professional_title_override}
<Element_input
{...ae.input_template.event_badge.professional_title_override}
label=""
bind:value={professional_title_override}
use_name_prefix={true}
required
class_li={[]}
container_class_li={[]}
/>
<button
class="ae_btn btn_warning"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'professional_title_override', professional_title_override)
.then(function (result) {
edit_professional_title_override = false;
});
}}
>
{#await event_badge_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
<button
class="ae_btn btn_sm btn_default"
on:click={async () => {
edit_professional_title_override = false;
}}
>
<span class="fas fa-window-close"></span> Cancel
</button>
{:else}
<button
class="ae_btn btn_secondary"
on:click={() => {
edit_professional_title_override = true;
}}
>
<span class="fas fa-edit"></span> Edit
</button>
{/if}
{#if $slct.event_badge_obj.professional_title_override}
<button
class="ae_btn btn_sm btn_default"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'professional_title_override', null)
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span> Reset
</button>
{/if}
</span>
</div>
<div class="affiliations">
<span class="label">Affiliations:</span>
<span class="value affiliations" class:d-none={edit_affiliations_override}>
{#if affiliations_override}
{@html affiliations_override}
{:else}
<span class="value_none">-- not set --</span>
{/if}
</span>
<span class="edit_container">
{#if edit_affiliations_override}
<Element_input
{...ae.input_template.event_badge.affiliations_override}
label=""
bind:value={affiliations_override}
use_name_prefix={true}
required
container_class_li={[]}
/>
<button
class="ae_btn btn_warning"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'affiliations_override', affiliations_override)
.then(function (result) {
edit_affiliations_override = false;
});
}}
>
{#await event_badge_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
<button
class="ae_btn btn_sm btn_default"
on:click={async () => {
edit_affiliations_override = false;
}}
>
<span class="fas fa-window-close"></span> Cancel
</button>
{:else}
<button
class="ae_btn btn_secondary"
on:click={() => {
edit_affiliations_override = true;
}}
class:d-none={edit_affiliations_override}
>
<span class="fas fa-edit"></span> Edit
</button>
{/if}
{#if $slct.event_badge_obj.affiliations_override}
<button
class="ae_btn btn_sm btn_default"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'affiliations_override', null)
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span> Reset
</button>
{/if}
</span>
</div>
<div class="location">
<span class="label">Location:</span>
<span class="value location" class:d-none={edit_location_override}>
{#if location_override}
<span class="city state_province">{@html location_override}</span>
{:else}
<span class="value_none">-- not set --</span>
{/if}
</span>
<span class="edit_container">
{#if edit_location_override}
<Element_input
{...ae.input_template.event_badge.location_override}
label=""
bind:value={location_override}
use_name_prefix={true}
required
container_class_li={[]}
/>
<button
class="ae_btn btn_warning"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'location_override', location_override)
.then(function (result) {
edit_location_override = false;
});
}}
>
{#await event_badge_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
<button
class="ae_btn btn_sm btn_default"
on:click={async () => {
edit_location_override = false;
}}
>
<span class="fas fa-window-close"></span> Cancel
</button>
{:else}
<button
class="ae_btn btn_secondary"
on:click={() => {
edit_location_override = true;
}}
class:d-none={edit_location_override}
>
<span class="fas fa-edit"></span> Edit
</button>
{/if}
{#if $slct.event_badge_obj.location_override}
<button
class="ae_btn btn_sm btn_default"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'location_override', null)
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span> Reset
</button>
{/if}
</span>
</div>
<!-- Information for attendee only (banquets, receptions, and other) -->
{#if $slct.event_badge_obj.ticket_1_code || $slct.event_badge_obj.ticket_2_code || $slct.event_badge_obj.ticket_3_code}
<div class="attendee_information special">
<span class="label">Access Notes:</span>
<ul class="values">
{#if $slct.event_badge_obj.ticket_1_code}
<li class="value">{@html $slct.event_badge_obj.event_badge_template.ticket_1_text ?? '-- not set --'}</li>
{/if}
{#if $slct.event_badge_obj.ticket_2_code}
<li class="value">{@html $slct.event_badge_obj.event_badge_template.ticket_2_text ?? '-- not set --'}</li>
{/if}
{#if $slct.event_badge_obj.ticket_3_code}
<li class="value">{@html $slct.event_badge_obj.event_badge_template.ticket_3_tex ?? '-- not set --'}</li>
{/if}
</ul>
</div>
{/if}
</section>
<section class="badge_other">
<div class="event_badge_tracking" class:agree={allow_tracking} class:disagree={!allow_tracking}>
<h2>Lead Retrieval</h2>
<div class="allow_tracking_agreement">
<p class="fs_smaller">If you attend a session, program or exhibit booth hosted by an exhibitor and/or industry supporter, you understand and agree that when you present your badge for scanning or when you provide personal data, that information will go to a non-ISHLT entity and ISHLT takes no responsibility for how that company uses your personal information. Providing your information to them is optional and you should review their privacy policies to address your particular needs and concerns about how they will treat your personal information. Scanned badge information will include first and last names, company/institution, and email address.</p>
{#if allow_tracking}
<!-- <div> -->
<p>This is currently set to <strong>allowed</strong>. To opt-out press the "I Do Not Agree" button below.</p>
<p>By allowing this QR code to be scanned by an exhibitor and/or industry supporter, you understand and agree that they may use your personal information.</p>
<button on:click={() => {handle_update_allow_tracking($slct.event_badge_id, false); show_allow_tracking=false;}} class="ae_btn btn_lg btn_warning"><span class="fas fa-minus"></span> I Do <strong>Not</strong> Agree - Do not allow lead retrieval</button>
<!-- </div> -->
{:else}
<p>This is currently set to <strong>not</strong> allowed. To opt-in press the "I Agree" button below.</p>
<p>If this QR code is scanned by an exhibitor and/or industry supporter, they will <strong>not</strong> have access to your personal information.</p>
<button on:click={() => {handle_update_allow_tracking($slct.event_badge_id, true); show_allow_tracking=false;}} class="ae_btn btn_lg btn_success"><span class="fas fa-plus"></span> I Agree - Allow lead retrieval</button>
<button on:click={() => {alert('You have opted out of lead retrieval. You can opt back in at anytime.');}} class="ae_btn btn_lg btn_warning" disabled={false}><span class="fas fa-minus"></span> I Do <strong>Not</strong> Agree - <!--Already opted out - -->Do not allow lead retrieval</button>
{/if}
</div>
</div>
<div class="wifi_information">
{#if $slct.event_badge_obj.event_badge_template.wireless_ssid}
<div class="wifi_label"><span class="fas fa-wifi"></span> WiFi:</div>
<div>
<div >Signal Name:
<strong class="wifi_ssid">{$slct.event_badge_obj.event_badge_template.wireless_ssid}</strong>
</div>
<div >Access Code:
<strong class="wifi_code">{$slct.event_badge_obj.event_badge_template.wireless_password}</strong>
</div>
</div>
{/if}
</div>
</section>
{/if}
<section class="navigation">
<a href="/event/{$slct.event_badge_obj.event_id_random}/badge/review" class="ae_btn btn_lg btn_secondary"><span class="fas fa-arrow-left"></span> New Search</a>
</section>
</section>
<!-- {#if show_allow_tracking} -->
{#if show_allow_tracking}
<Element_modal_v3
show = { true }
modal_cover_body = { true }
on:close={ () => {show_allow_tracking = false;} }
>
<span slot="header_title">
Badge Scanning and Lead Retrieval
</span>
<span slot="body">
<div class="allow_tracking_agreement">
<p>If you attend a session, program or exhibit booth hosted by an exhibitor and/or industry supporter, you understand and agree that when you present your badge for scanning or when you provide personal data, that information will go to a non-ISHLT entity and ISHLT takes no responsibility for how that company uses your personal information. Providing your information to them is optional and you should review their privacy policies to address your particular needs and concerns about how they will treat your personal information. Scanned badge information will include first and last names, company/institution, and email address.</p>
{#if allow_tracking}
<p>This is currently set to <strong>allowed</strong>. To opt-out press the "I Do Not Agree" button below.</p>
<p>By allowing this QR code to be scanned by an exhibitor and/or industry supporter, you understand and agree that they may use your personal information.</p>
<button on:click={() => {handle_update_allow_tracking($slct.event_badge_id, false); show_allow_tracking=false;}} class="ae_btn btn_lg btn_warning"><span class="fas fa-minus"></span> I Do <strong>Not</strong> Agree - Do not allow lead retrieval</button>
{:else}
<p>This is currently set to <strong>not</strong> allowed. To opt-in press the "I Agree" button below.</p>
<!-- <p>If this QR code is scanned by an exhibitor and/or industry supporter, they will <strong>not</strong> have access to your personal information.</p> -->
<p>To opt-out, press the "I Do Not Agree" button below or the close button. If your badge is scanned, access to your personal information will <strong>not</strong> be provided.</p>
<button on:click={() => {handle_update_allow_tracking($slct.event_badge_id, true); show_allow_tracking=false;}} class="ae_btn btn_lg btn_success"><span class="fas fa-plus"></span> I Agree - Allow lead retrieval</button>
<button on:click={() => {handle_update_allow_tracking($slct.event_badge_id, false); show_allow_tracking = false;}} class="ae_btn btn_lg btn_warning"><span class="fas fa-minus"></span> I Do <strong>Not</strong> Agree - Do not allow lead retrieval</button>
{/if}
</div>
<!-- <button on:click={() => {handle_update_allow_tracking(true);}} class="ae_btn btn_lg btn_warning">I Agree - Allow lead retrieval</button> -->
<!-- <button on:click={() => {handle_update_allow_tracking(false);}} class="ae_btn btn_lg btn_warning">I Do <strong>Not</strong> Agree - Do not allow lead retrieval</button> -->
</span>
<!-- <span slot="footer_text">
</span> -->
</Element_modal_v3>
{/if}
<style>
</style>

View File

@@ -0,0 +1,652 @@
<script lang="ts">
import { onMount } from 'svelte';
import { ae, Element_input, Element_modal_v3, Element_qr_scanner } from 'aether_npm_lib';
import { client, page, slct, slct_trigger, ae_com, ae_events } from '../../stores_mod_events';
// import {} from '../stores_event.js';
import { get_event_badge_search, email_event_badge_review_url } from '../stores_event_api.js';
// ISHLT 2024 badge type codes
let badge_type_code_li = [{"code":"current_member","name":"Member"},{"code":"inactive_member","name":"Non-Member"},{"code":"current_member_trainee","name":"Trainee Member"},{"code":"inactive_member_trainee","name":"Trainee Non-Member"},{"code":"ex_all","name":"Exhibitor All Access"},{"code":"ex_booth","name":"Exhibitor Booth Staff"},{"code":"hftx","name":"HFTX Master Academy"},{"code":"mcs","name":"MCS Master Academy"},{"code":"pediatric","name":"Pediatric"},{"code":"guest","name":"Guest"},{"code":"staff","name":"Staff"},{"code":"volunteer","name":"Volunteer"},{"code":"test","name":"Test"}];
// ISHLT 2023 badge type codes
// let badge_type_code_li = {'current_member': 'Current Member', 'inactive_member': 'Inactive Member', 'inactive_member_trainee': 'Inactive Member Trainee', 'current_member_trainee': 'Current Member Trainee', 'ex_booth': 'Exhibitor Only', 'ex_all': 'Exhibitor All', 'pulmonary': 'Pulmonary', 'pediatric': 'Pediatric', 'lung_afternoon': 'Lung Afternoon', 'long_morning': 'Lung Morning', 'nurse_allied_nonphysician': 'Nurse Allied Non-physician', 'guest': 'Guest', 'nurse_allied_health': 'Nurse Allied Health', 'trainee': 'Trainee', 'physician': 'Physician', 'industry': 'Industry'}; // 'Trainee Non-Member', null
let search_badge_type_code: string = null;
let search_event_badge_id: string = null;
let search_query_str: string = null;
// let search_given_name: string = null;
// let search_family_name: string = null;
// let search_email: string = null;
// let event_obj: object = null
// let event_obj_get_promise = null;
let event_badge_search_data: object = {};
let event_badge_obj_li_get_promise;
let event_badge_obj_li: object = null;
// let show_event_badge_new_modal: boolean = false; // For form
// let show_event_badge_search_main: boolean = false;
// let show_event_badge_view_main: boolean = false;
// let show_search_qr_scanner: boolean = true;
let start_qr_scanner: boolean = true;
let show_event_badge_obj_details: boolean = false; // For ISHLT to see what the QR codes look like and do.
// let slct_event_badge_id: string = null;
// let slct_event_badge_obj: object = null;
let event_badge_obj_get_promise = null;
// let event_badge_obj_get_promise = Promise.resolve([]);
let event_badge_qr_get_promise = null;
let event_badge_id_qr_get_promise = null;
let event_badge_all_promise = null;
let auto_select: boolean = null;
// let auto_view_badge: boolean = true;
let auto_search: boolean = true;
onMount(() => {
console.log('** Component Mounted: ** Event Badge Search Main');
// if ($slct.event_id == 'RNEoBINgTBo') {
// badge_only = true;
// }
});
// NOTE: This technically works, but it is not very clean. Also review the <Element_qr_scanner /> below along with element_qr_scanner.svelte.
// $: if ($ae_com.trusted_access || $client.trusted_access) {
// // console.log('ADMIN or TRUSTED');
// $ae_events.badges.show_search_qr_scanner = false;
// $ae_events.badges.start_qr_scanner = false;
// } else {
// // console.log('UNTRUSTED');
// $ae_events.badges.show_search_qr_scanner = true;
// $ae_events.badges.start_qr_scanner = true;
// }
// if (!$client.trusted_access && !$ae_com.trusted_access) {
// show_search_qr_scanner = false;
// }
async function handle_get_event_badge_search() {
console.log(`*** handle_get_event_badge_search() *** search_event_badge_id: ${search_event_badge_id} search_query_str: ${search_query_str}`);
let params = {};
if ($client.administrator_access || $ae_com.administrator_access) {
params['enabled'] = 'all';
params['hidden'] = 'all';
} else {
params['enabled'] = 'enabled';
}
if (search_event_badge_id) {
event_badge_obj_li_get_promise = get_event_badge_search({event_id: $slct.event_id, event_badge_id: search_event_badge_id, type_code: search_badge_type_code, badge_only: $ae_events.badges.badge_id_only_search, params: params,
log_lvl: 2
});
// event_badge_obj_li = event_badge_obj_li_get_promise;
}
else if (search_query_str) {
event_badge_obj_li_get_promise = get_event_badge_search({event_id: $slct.event_id, type_code: search_badge_type_code, query_str: search_query_str, badge_only: $ae_events.badges.badge_id_only_search, params: params});
// event_badge_obj_li = event_badge_obj_li_get_promise;
}
event_badge_obj_li_get_promise.then(function (event_badge_obj_li_result) {
console.log('GET DONE get_event_badge_search');
console.log(event_badge_obj_li_result);
event_badge_obj_li = event_badge_obj_li_result;
return event_badge_obj_li_result;
})
.catch(function (error) {
console.log(error);
return false;
// return error;
});
}
function handle_cancel_form() {
console.log('*** handle_cancel_form() ***');
}
function handle_submit_form(event) {
console.log('*** handle_submit_form() ***');
// event_badge_search_data['event_badge_id'] = ae.util.value_try_null(event.target.event_badge_id.value.trim());
// event_badge_search_data['event_person_id'] = ae.util.value_try_null(event.target.event_person_id.value.trim());
event_badge_search_data['external_id'] = ae.util.value_try_null(event.target.external_id.value.trim());
event_badge_search_data['query_str'] = ae.util.value_try_null(event.target.query_str.value.trim());
event_badge_search_data['given_name'] = ae.util.value_try_null(event.target.given_name.value.trim());
event_badge_search_data['family_name'] = ae.util.value_try_null(event.target.family_name.value.trim());
event_badge_search_data['email'] = ae.util.value_try_null(event.target.email.value.trim());
let handle_get_event_badge_search_promise = handle_get_event_badge_search();
}
// function handle_form_oninput() {
// console.log('*** handle_form_oninput() ***');
// if (auto_search) {
// } else {
// return null;
// }
// event_badge_search_data = {};
// if (search_event_badge_id) {
// event_badge_search_data['event_badge_id'] = search_event_badge_id.trim();
// }
// if (search_event_person_id) {
// event_badge_search_data['event_person_id'] = search_event_person_id.trim();
// }
// if (search_external_id) {
// event_badge_search_data['external_id'] = search_external_id.trim();
// }
// if (search_query_str) {
// event_badge_search_data['query_str'] = search_query_str.trim();
// }
// if (search_given_name) {
// event_badge_search_data['given_name'] = search_given_name.trim();
// }
// if (search_family_name) {
// event_badge_search_data['family_name'] = search_family_name.trim();
// }
// if (search_email) {
// event_badge_search_data['email'] = search_email.trim();
// }
// handle_get_event_badge_search();
// }
function handle_oninput_search_type_code(event) {
console.log('*** handle_oninput_search_type_code() ***');
console.log(event);
// search_badge_type_code = event.detail.value;
handle_get_event_badge_search();
}
function handle_oninput_search_query_str(event) {
console.log('*** handle_oninput_search_query_str() ***');
console.log(event);
search_query_str = event.detail.value.trim();
handle_get_event_badge_search();
// if (search_query_str) {
// event_badge_search_data = {};
// event_badge_search_data['query_str'] = search_query_str;
// handle_get_event_badge_search();
// } else {
// return false;
// }
}
// function handle_select_event_badge_obj(event_badge_obj) {
// console.log('*** handle_select_event_badge_obj() ***');
// slct_event_badge_id.set(event_badge_obj.event_badge_id_random);
// slct_event_badge_obj.set(event_badge_obj);
// dispatch('event_badge_obj_selected', {
// event_badge_id: slct_event_badge_id,
// event_badge_obj: slct_event_badge_obj,
// });
// }
function handle_qr_scan_result(event) {
console.log('*** handle_qr_scan_result() ***');
let qr_scan_result = event.detail.result;
console.log(qr_scan_result);
let obj = ae.util.process_data_string(qr_scan_result);
if (obj.type && obj.id && obj.type == 'event_badge') {
console.log(`Found event_badge ID: ${obj.id}`);
if ($ae_events.badges.auto_view_badge) {
window.location.href = `/event/badge/view_badge?event_badge_id=${obj.id}`;
} else {
$slct.event_badge_id = obj.id;
$ae_events.badges.event_badge_id = obj.id;
event_badge_search_data = {};
event_badge_search_data['event_badge_id'] = obj.id;
handle_get_event_badge_search()
}
} else if (obj.type && obj.id && obj.type == 'event_person') {
console.log(`Found event_person ID: ${obj.id}`);
if ($ae_events.badges.auto_view_badge) {
window.location.href = `/event/badge/view_badge?event_person_id=${obj.id}`;
} else {
event_badge_search_data = {};
event_badge_search_data['event_person_id'] = obj.id;
handle_get_event_badge_search()
}
} else {
console.log('The object returned was unexpected or not valid');
}
}
let full_name = null;
let email = null;
let full_address = null;
async function handle_load_event_badge_obj(event_badge_id, event_badge_obj) {
console.log('*** handle_load_event_badge_obj() ***');
// $slct_event_badge_obj = event_badge_obj;
$slct.event_badge_obj = event_badge_obj;
// let endpoint = `/event/badge/${event_badge_id}`;
// let params = { inc_event_badge_template: true };
// event_badge_obj_get_promise = await api.get_object({api_cfg: $cfg.api, endpoint: endpoint, params: params});
// event_badge_obj = event_badge_obj_get_promise;
// // let full_name = null;
// full_name = null;
// if (event_badge_obj.full_name) {
// console.log(`Using full_name: ${event_badge_obj.full_name}`);
// full_name = event_badge_obj.full_name;
// } else if (event_badge_obj.full_name_override) {
// console.log('Using full_name_override');
// full_name = event_badge_obj.full_name_override;
// } else if (event_badge_obj.given_name && event_badge_obj.family_name) {
// console.log('Using given_name family_name');
// full_name = `${event_badge_obj.given_name} ${event_badge_obj.family_name}`;
// } else if (event_badge_obj.given_name) {
// console.log('Using given_name');
// full_name = `${event_badge_obj.given_name}`;
// } else {
// console.log('Using no name');
// full_name = 'no name'
// }
// // let email = event_badge_obj.email;
// email = event_badge_obj.email;
// // let full_address = event_badge_obj.full_address;
// full_address = event_badge_obj.full_address;
// // Generate the MeCard QR code
// endpoint = `/event/qr_image/event_badge_mecard_${event_badge_id}/gen_send`
// params = {};
// params['qr_type'] = 'mecard';
// params['qr_send'] = false;
// params['n'] = full_name;
// params['email'] = email;
// params['adr'] = full_address;
// console.log(params);
// event_badge_qr_get_promise = await api.get_object({api_cfg:$cfg.app, endpoint: endpoint, params: params, log_lvl: 2});
// // Generate the Aether object QR code
// endpoint = `/event/qr_image/event_badge_obj_${event_badge_id}/gen_send`
// params = {};
// params['qr_type'] = 'obj';
// params['qr_send'] = false;
// params['obj_type'] = 'event_badge';
// params['obj_id'] = event_badge_id;
// event_badge_id_qr_get_promise = await api.get_object({api_cfg:$cfg.app, endpoint: endpoint, params: params, log_lvl: 2});
show_event_badge_obj_details = true;
}
async function handle_email_event_badge_review_url(event_badge_id) {
console.log('*** handle_email_event_badge_review_url() ***');
// let params = event_badge_search_data;
let params = {};
let root_url = $page.current_url_root;
let event_badge_obj_email_promise = await email_event_badge_review_url({event_badge_id:event_badge_id, root_url:root_url});
return event_badge_obj_email_promise;
}
$: if ($client.administrator_access || $ae_com.administrator_access) {
$ae_events.badges.search_max_results = 150;
} else if ($client.trusted_access || $ae_com.trusted_access) {
$ae_events.badges.search_max_results = 75;
} else {
$ae_events.badges.search_max_results = 20;
}
</script>
<section class="event_badge_search_main search_and_results">
<section class="search_options">
<form on:submit|preventDefault={handle_submit_form} on:keydown={e => e.key === 'Escape' && handle_cancel_form} class="search_form">
<!-- <label>Auto Search? <input type="checkbox" bind:checked={auto_search} value="true"></label> -->
<fieldset>
<legend>Attendee Search</legend>
<div class="search_fields">
{#if $client.trusted_access || $ae_com.trusted_access && badge_type_code_li}
<div class="search_by_badge_type_code">
<select
bind:value={search_badge_type_code}
on:change={handle_oninput_search_type_code}
>
<option value="">-- Badge Type --</option>
{#each badge_type_code_li as badge_type_code}
<option value={badge_type_code.code}>{badge_type_code.name}</option>
{/each}
</select>
<!-- <Element_input {...ae.input_template.event_badge.badge_type_code} select_option_li={badge_type_code_li} value={search_badge_type_code} use_name_prefix={true} content_layout={'floating_input'} container_class_li={['mb-1', 'col-md-12', 'col-lg-12']} focus={false} on:oninput={handle_oninput_search_type_code} /> -->
</div>
{/if}
<div class="search_by_text">
<Element_input {...ae.input_template.event_badge.search_query_str} value={search_query_str} use_name_prefix={true} content_layout={'floating_input'} container_class_li={['mb-1', 'col-md-12', 'col-lg-12']} focus={true} on:oninput={handle_oninput_search_query_str} />
</div>
</div>
<div class="how_to_message">
<ol>
<li>Start typing.</li>
<!-- <li>Select a field and start typing.</li> -->
<li>Results will appear as you type.</li>
<!-- <li>Press the "Review and Print Badge" button in the row with your name to review your badge and print.</li> -->
<li>Click your name to review your badge and print.</li>
</ol>
<ul>
<li>You are only allowed to print your badge once. Please go to the Query desk for reprints or questions.</li>
</ul>
</div>
</fieldset>
</form>
{#if $ae_events.badges.show_search_qr_scanner}
<!-- NOTE: This technically works, but it is not very clean. Also review the if else statement above along with element_qr_scanner.svelte. -->
<div class="ae_cont qr_scanner_form">
<!-- <label>Auto View Badge on Scan? <input type="checkbox" bind:checked={$ae_events.badges.auto_view_badge} value="true"></label> -->
<Element_qr_scanner bind:start_qr_scanner on:qr_scan_result={handle_qr_scan_result} />
<div>
<button
class="ae_btn btn_xs btn_outline_default"
on:click={() => {
$ae_events.badges.show_search_qr_scanner = !$ae_events.badges.show_search_qr_scanner;
}}
>
<span class="fas fa-qrcode"></span> Close QR Scanner
</button>
<button
class="ae_btn btn_xs btn_outline_default"
on:click={() => {
$ae_events.badges.auto_view_badge = !$ae_events.badges.auto_view_badge;
}}
>
<span class="fas fa-eye"></span> Auto View [{$ae_events.badges.auto_view_badge}]
</button>
</div>
</div>
{:else}
{#if ($client.administrator_access || $ae_com.administrator_access)}
<div class="ae_cont">
<button
class="ae_btn btn_xs btn_outline_default"
on:click={() => {
$ae_events.badges.show_search_qr_scanner = !$ae_events.badges.show_search_qr_scanner;
}}
>
<span class="fas fa-qrcode"></span> Use QR Scanner
</button>
</div>
{/if}
{/if}
</section>
<section class="search_results">
{#if (Array.isArray(event_badge_obj_li) && event_badge_obj_li.length <= $ae_events.badges.search_max_results)}
<table class="ae_data table_borders table_alt_rows table_100w results_table">
<thead>
<tr>
{#if $client.trusted_access || $ae_com.trusted_access}
<th>Review</th>
{/if}
<th>View and Print Badge</th>
<th>Email</th>
<th>Affiliations or Location</th>
<th>Type</th>
</tr>
</thead>
<tbody>
{#each event_badge_obj_li.sort(ae.util.dynamic_sort_multiple('print_count ASC', 'given_name', 'family_name', 'created_on DESC', 'updated_on DESC')) as event_badge_obj, index}
<tr class:print_disabled={event_badge_obj.print_count >= 1 && !($client.administrator_access || $ae_com.administrator_access)} class:d_none={event_badge_obj.hide && !($client.administrator_access || $ae_com.administrator_access)}>
{#if $client.authenticated_access || $ae_com.authenticated_access}
<td>
<!-- <button on:click={() => {slct_event_badge_id = event_badge_obj.event_badge_id_random; slct_event_badge_obj = event_badge_obj; show_event_badge_obj_details = true;}} class="ae_btn btn_primary"><span class="fas fa-eye"></span> QRs</button> -->
<!-- <button on:click={handle_load_event_badge_obj(event_badge_obj.event_badge_id_random, event_badge_obj)} class="ae_btn btn_sm btn_outline_primary"><span class="fas fa-qrcode"></span> QR</button> -->
{#if $client.administrator_access || $ae_com.administrator_access}
<a href="/event/badge/{event_badge_obj.event_badge_id_random}/review_badge" class="ae_btn btn_md btn_secondary review_badge_btn"><span class="fas fa-qrcode"></span> Review</a>
{/if}
<button
class="ae_btn btn_md btn_secondary"
on:click={async () => {
if (confirm('Send email with URL to review this badge?')){
} else {
return false;
}
let emailing_promise = handle_email_event_badge_review_url(event_badge_obj.event_badge_id_random)
.then(function (result) {
alert('The email with the link to review this badge has been sent and should arrive within a few minutes.');
});
}}
>
<span class="fas fa-qrcode"></span> Email
</button>
</td>
{/if}
<td>
{#if event_badge_obj.print_count < 1 || $client.trusted_access || $ae_com.trusted_access}
<a href="/event/badge/view_badge?event_badge_id={event_badge_obj.event_badge_id_random}" class="ae_btn btn_lg btn_primary view_badge_btn" title="View and print badge">
<span>
<span class="fas fa-id-badge"></span>
<span class="fas fa-print"></span>
{#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.family_name}
{event_badge_obj.given_name} {event_badge_obj.family_name}
{:else if event_badge_obj.given_name}
{event_badge_obj.given_name}
{:else}
-- no name --
{/if}
</span>
{#if event_badge_obj.print_count >= 1}
<span class="print_count">{event_badge_obj.print_count}x</span>
{/if}
</a>
{:else}
<button class="ae_btn btn_lg btn_secondary view_badge_btn" title="Badge already printed" disabled={true}>
<span>
<span class="fas fa-id-badge"></span>
<span class="fas fa-print"></span>
{#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.family_name}
{event_badge_obj.given_name} {event_badge_obj.family_name}
{:else if event_badge_obj.given_name}
{event_badge_obj.given_name}
{:else}
-- no name --
{/if}
</span>
{#if event_badge_obj.print_count >= 1}
<span class="print_count">{event_badge_obj.print_count}x</span>
{/if}
</button>
{/if}
</td>
<td class="fs_smaller">
{#if event_badge_obj.print_count < 1}
<a href="/event/badge/view_badge?event_badge_id={event_badge_obj.event_badge_id_random}"
title="View and print badge"
>
{#if event_badge_obj.email && event_badge_obj.email.length}
{#if $client.trusted_access || $ae_com.trusted_access}
{event_badge_obj.email}
{:else}
{event_badge_obj.email.substring(0,1)}{'*'.repeat(event_badge_obj.email.indexOf('@')-2)}{event_badge_obj.email.substring(event_badge_obj.email.indexOf('@')-1, event_badge_obj.email.indexOf('@'))}{event_badge_obj.email.substring(event_badge_obj.email.indexOf('@'))}
{/if}
{:else}
-- no email address --
{/if}
</a>
{:else}
{#if event_badge_obj.email && event_badge_obj.email.length}
{#if $client.trusted_access || $ae_com.trusted_access}
{event_badge_obj.email}
{:else}
{event_badge_obj.email.substring(0,1)}{'*'.repeat(event_badge_obj.email.indexOf('@')-2)}{event_badge_obj.email.substring(event_badge_obj.email.indexOf('@')-1, event_badge_obj.email.indexOf('@'))}{event_badge_obj.email.substring(event_badge_obj.email.indexOf('@'))}
{/if}
{:else}
-- no email address --
{/if}
{/if}
</td>
<td class="fs_smaller">
{#if event_badge_obj.print_count < 1}
<a href="/event/badge/view_badge?event_badge_id={event_badge_obj.event_badge_id_random}&badge_only={$ae_events.badges.badge_id_only_search}" class="" title="View and print badge">
{#if event_badge_obj.affiliations && event_badge_obj.affiliations.length}
{event_badge_obj.affiliations}
{:else if event_badge_obj.location}
{event_badge_obj.location}
{:else if event_badge_obj.city && event_badge_obj.state_province}
{event_badge_obj.city}, {event_badge_obj.state_province}
{:else if event_badge_obj.city}
{event_badge_obj.city}
{:else if event_badge_obj.state_province}
{event_badge_obj.state_province}
{:else}
-- none --
{/if}
</a>
{:else}
{#if event_badge_obj.affiliations && event_badge_obj.affiliations.length}
{event_badge_obj.affiliations}
{:else if event_badge_obj.location}
{event_badge_obj.location}
{:else if event_badge_obj.city && event_badge_obj.state_province}
{event_badge_obj.city}, {event_badge_obj.state_province}
{:else if event_badge_obj.city}
{event_badge_obj.city}
{:else if event_badge_obj.state_province}
{event_badge_obj.state_province}
{:else}
-- none --
{/if}
{/if}
</td>
<td class="fs_smaller">
<span title={event_badge_obj.registration_type}>{event_badge_obj.badge_type}</span>
</td>
</tr>
{/each}
</tbody>
</table>
{:else if (Array.isArray(event_badge_obj_li) && event_badge_obj_li.length > $ae_events.badges.search_max_results)}
<div class="results_message warning"><span class="fas fa-search"></span> Too many results. Max {$ae_events.badges.search_max_results} attendees. Please narrow down your search.</div>
{:else}
{#if search_query_str && search_query_str.length > 0}
<div class="results_message warning"><span class="fas fa-search"></span> No results.</div>
{/if}
{/if}
{#await event_badge_obj_li_get_promise}
searching...
{:then}
{#if event_badge_obj_li_get_promise}
<!-- done! -->
{:else}
<!-- nothing yet -->
{/if}
{/await}
</section>
</section>
{#if show_event_badge_obj_details}
<Element_modal_v3
show = { true }
modal_cover_body = { true }
on:close={ () => {show_event_badge_obj_details = false;} }
>
<span slot="header_title">
Attendee Badge QR Code
</span>
<!-- <span slot="header_text">
</span> -->
<span slot="body">
<!-- <Event_badge_obj_details event_badge_id={slct_event_badge_id} event_badge_obj={slct_event_badge_obj} /> -->
<div class="badge_person_name">
{full_name}
{email}
<!-- {location} -->
</div>
<hr>
<div>
<div>Badge Lookup QR Code for {$slct.event_badge_obj.given_name}:</div>
<img class="person_information_qr qr_code" style="" src="/event/qr_image/event_badge_obj_{$slct.event_badge_obj.event_badge_id_random}?qr_filename=attendee_qr.png" alt="missing QR code">
</div>
<br>
<hr>
<br>
<div>
<div>{$slct.event_badge_obj.given_name}'s QR Code MeCard:</div>
<img class="person_information_qr qr_code" style="" src="/event/qr_image/event_badge_mecard_{$slct.event_badge_obj.event_badge_id_random}?qr_filename=attendee_qr.png" alt="missing person information QR code">
</div>
</span>
<span slot="footer_text">
<div class="load_datetime"><span class="label">Loaded:</span> <span class="datetime">{new Date()}</span></div>
</span>
</Element_modal_v3>
{/if}
<style>
</style>

View File

@@ -0,0 +1,213 @@
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';
import { ae, api, Element_input, Element_input_file } from 'aether_npm_lib';
import { account_id, cfg, client, page, slct, slct_trigger, time, ae_com } from '../../stores_mod_events';
// import { slct_event_id, slct_event_obj } from '../stores_event.js';
// import { email_event_badge_review_url } from '../stores_event_api.js'; /* FIX FIX FIX */
// export let max_results: number = 20;
export let allow_overwrite = false;
const dispatch = createEventDispatcher();
// let event_badge_search_data: object = {};
// let event_badge_obj_li_get_promise = null;
// let event_badge_obj_li: object = null;
// let show_event_badge_new_modal: boolean = false; // For form
// let show_event_badge_search_main: boolean = false;
// let show_event_badge_view_main: boolean = false;
// let show_qr_scanner: boolean = true;
// let start_qr_scanner: boolean = true;
// let show_event_badge_obj_details: boolean = false; // For ISHLT to see what the QR codes look like and do.
// let slct_event_badge_id: string = null;
// let slct_event_badge_obj: object = null;
let file_upload_post_promise = null;
let disable_submit_btn = false;
onMount(() => {
console.log('Event Badge Upload component has mounted');
});
function handle_cancel_form() {
console.log('*** handle_cancel_form() ***');
// dispatch(
// 'event_badge_search_form_canceled',
// {
// event_badge_id: event_badge_id,
// }
// );
}
function handle_submit_form(event) {
console.log('*** handle_submit_form() ***');
// console.log(event.target.file_list);
disable_submit_btn = true;
// Process the upload hosted file parts
const form_data = new FormData();
form_data.append('account_id', $account_id);
form_data.append('event_id', $slct.event_id);
// form_data.append('begin_at', '0');
// form_data.append('end_at', '20000');
for (let i = 0; i < event.target.file_list.files.length; i++) {
// if (event.target.event_file_upload_file_list.files[i].name.endsWith('.pptxwin')) {
// console.log('Need to fix filename');
// event.target.event_file_upload_file_list.files[i].name.replace('.pptxwin', '.pptx');
// }
form_data.append(`file`, event.target.event_badge_list_file.files[i]);
}
let params = null;
let endpoint = `/event/${$slct.event_id}/badge/import`;
console.log(form_data);
params = null;
// Uncomment and the file_upload_post_promise is not seen by the "await" below
// file_upload_post_promise = await api.post_object({api_cfg: $cfg.api, endpoint: endpoint, params: params, data:form_data});
// Uncomment so that the file_upload_post_promise is not seen by the "await" below
file_upload_post_promise = api.post_object({api_cfg: $cfg.api, endpoint: endpoint, params: params, form_data: form_data, log_lvl: 2})
.then(async function (result) {
for (let i = 0; i < result.length; i++) {
console.log(result[i]);
let test_result = result[i];
console.log('Test Result', test_result);
}
return true;
})
.then(function (result) {
// NOTE: Need to make sure the event file records are created first. The update won't see the changes if too fast.
dispatch(
'event_badge_file_uploaded',
{
event_id: $slct.event_id,
}
);
return true;
})
.catch(function (error) {
console.log('Something went wrong.');
console.log(error);
return false;
})
.finally(function (result) {
disable_submit_btn = false;
});
console.log(file_upload_post_promise);
return file_upload_post_promise;
}
function handle_file_upload_list_updated(event) {
console.log(event.detail.element_id);
console.log(event.detail.file_upload_list);
}
</script>
<section class="event_badge_list_file_upload_form">
<form on:submit|preventDefault={handle_submit_form} on:keydown={e => e.key === 'Escape' && handle_cancel_form} class="event_badge_list_file_upload">
<!-- <label>Auto Search? <input type="checkbox" bind:checked={auto_search} value="true"></label> -->
<!-- <fieldset> -->
<!-- <legend>Badge List File Upload</legend> -->
<!-- <div class="search_fields">
{#if $client.trusted_access || $ae_com.trusted_access}
<div class="search_by_badge_type_code">
<Element_input {...ae.input_template.event_badge.badge_type_code} value={search_badge_type_code} use_name_prefix={true} content_layout={'floating_input'} container_class_li={['mb-1', 'col-md-12', 'col-lg-12']} focus={false} on:oninput={handle_oninput_search_type_code} />
</div>
{/if}
<div class="search_by_text">
<Element_input {...ae.input_template.event_badge.search_query_str} value={search_query_str} use_name_prefix={true} content_layout={'floating_input'} container_class_li={['mb-1', 'col-md-12', 'col-lg-12']} focus={true} on:oninput={handle_oninput_search_query_str} />
</div>
</div> -->
<!-- <div class="how_to_message">
<ol>
<li>Start typing.</li>
<li>Results will appear as you type.</li>
<li>Click your name to review your badge and print.</li>
</ol>
<ul>
<li>You are only allowed to print your badge once. Please go to the Query desk for reprints or questions.</li>
</ul>
</div> -->
<fieldset class="select_files">
<legend>Browse or Drag and Drop File Here:</legend>
<div class="">
<Element_input_file multiple={false} required={true} element_id={'event_badge_list_file'} on:file_upload_list_updated={handle_file_upload_list_updated} container_class_li={['ae_prop_input']} />
<div class="ae_prop_description">
{#if $slct.event_obj.event_cfg.some_event_badge_option }
{@html $slct.event_obj.event_cfg.some_event_badge_option}
{:else}
Browse or drag and drop a CSV file to be uploaded.
{/if}
</div>
</div>
{#await file_upload_post_promise}
<div class="awaiting alert_msg_pulse">Uploading files...</div>
{:then}
{#if file_upload_post_promise}
<!-- <div class="awaiting_finished success_msg_pulse">Finished uploading files</div> -->
{:else}
<!-- <div class="awaiting" out:fade={{ duration: 2000 }}>Nothing here yet</div> -->
{/if}
{/await}
</fieldset>
<!-- </fieldset> -->
<button type="submit" class="ae_btn btn_primary" disabled={disable_submit_btn}><span class="fas fa-upload"></span> Ready to Upload File</button>
{#await file_upload_post_promise}
<div class="awaiting alert_msg_pulse">Uploading file...</div>
{:then}
{#if file_upload_post_promise}
<div class="awaiting_finished success_msg_pulse">Finished uploading files</div>
{:else}
<!-- <div class="awaiting" out:fade={{ duration: 2000 }}>Nothing here yet</div> -->
{/if}
{/await}
</form>
<section class="search_results"></section>
</section>
<style>
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
<script lang="ts">
// *** Import Svelte core
import { onMount } from 'svelte';
// *** Import Aether core variables and functio
import { ae, Element_modal_v3 } from 'aether_npm_lib';
import { cfg, client, page, slct, slct_trigger, ae_events } from '../../stores_mod_events';
// *** Import Aether core components
// *** Import Aether module variables and functions
import { slct_event_id, slct_event_badge_obj_li } from '../../event/stores_event.js';
import { get_event_badge_obj_li, load_event_badge_obj, update_event_badge_obj, create_event_badge_obj } from '../../event/stores_event_api.js';
// *** Import Aether module components
import Event_badge_view_badge_obj from './20_event_badge_view_badge.svelte';
// *** Export/Exposed variables and functions for component
export let event_id: string = $page['page_for']['event_id'];
// export let badge_only: boolean = false; // event_badge only record; no event_person record
// *** Set initial variables
let initial_loading_promise = null;
let event_obj_load_promise = null;
let event_badge_obj_li_get_promise = null;
// export let event_badge_obj = { event_badge_id_random: '', event_id_random: '', title_names: '', given_name: '', family_name: '', designations: '', full_name: '', full_Name_override: '', professional_title: '', professional_title_override: '', affiliations: '', affiliations_override: '', location: '', location_override: '', state_province: '', full_address: '', email: '', other_1: '', other_2: '', ticket_1_code: '', ticket_2_code: '', ticket_3_code: '', ticket_4_code: '', ticket_5_code: '', badge_type_code: '', badge_type_code_override: '', badge_type: '', badge_type_override: '', allow_tracking: '', event_badge_template: { logo_path: '' }, print_first_datetime: '' };
let event_badge_obj_li_load_promise = null;
let event_badge_obj_load_promise = null;
let event_badge_obj_update_promise = null;
let event_badge_obj_create_promise = null;
let event_badge_qr_mecard_get_promise = null;
let event_badge_qr_id_get_promise = null;
let show_event_badge_tools_modal: boolean = false;
let show_restricted_fields: boolean = false;
let allow_tracking: boolean = null;
let show_allow_tracking: boolean = true;
let edit_full_Name_override = false;
let edit_professional_title_override = false;
let edit_affiliations_override = false;
let edit_location_override = false;
let show_print_msg: boolean = null;
let use_badge_type = null;
let use_badge_type_code = null;
let use_badge_type_code_list = [];
use_badge_type_code_list.push({code: 'MBR', name: 'Member'});
use_badge_type_code_list.push({code: 'AHMB', name: 'Member'});
use_badge_type_code_list.push({code: 'SNMB', name: 'Student/Trainee Non-Member'});
use_badge_type_code_list.push({code: 'SMBR', name: 'Student/Trainee Member'});
use_badge_type_code_list.push({code: 'NMBR', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'ANHM', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'INMB', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'EXO', name: 'Exhibitor Booth Staff'});
use_badge_type_code_list.push({code: 'EXALL', name: 'Exhibitor All Access'});
use_badge_type_code_list.push({code: 'GUEST', name: 'Guest'});
use_badge_type_code_list.push({code: 'HEART', name: 'HFTX Core'});
use_badge_type_code_list.push({code: 'LUNG', name: 'LTX Core'});
use_badge_type_code_list.push({code: 'STAFF', name: 'Staff'});
use_badge_type_code_list.push({code: 'VIP', name: 'VIP'});
use_badge_type_code_list.push({code: 'VOL', name: 'Volunteer'});
let full_Name_override = null; // Usually set by the person or similar
let longest_full_Name_override_part = 0;
let full_name = null; // Usually auto generated
let professional_title_override = null;
let longest_professional_title_override_part = 0;
let affiliations_override = null;
let longest_affiliations_override_part = 0;
let location_override = null;
let longest_location_override_part = 0;
let slct_badge_type = '';
let url_params = ae.util.get_url_params();
console.log(url_params);
onMount(() => {
console.log('Event Badge View Badge List component has mounted');
if (event_id) {
// if (event_id == 'RNEoBINgTBo') {
// badge_only = true;
// }
initial_loading_promise = handle_load_event_badge_obj_li();
}
});
async function handle_load_event_badge_obj_li() {
console.log('*** handle_load_event_badge_obj_li() ***');
$slct_event_id = event_id;
$slct.event_id = event_id;
let badge_type_code = null;
let printed = null;
let params = { 'limit': 1000 };
if (url_params.badge_type_code) {
badge_type_code = url_params.badge_type_code;
}
if (url_params.printed) {
// 'not_printed', 'printed', 'all'
printed = url_params.printed;
}
params['badge_only'] = $ae_events.badges.badge_id_only_search;
event_badge_obj_li_load_promise = await get_event_badge_obj_li({ event_id: event_id, badge_type_code: badge_type_code, printed: printed, inc_event_badge_template: false, params: params, log_lvl: 1 });
$slct_event_badge_obj_li = event_badge_obj_li_load_promise;
$slct.event_badge_obj_li = event_badge_obj_li_load_promise;
console.log($slct.event_badge_obj_li);
return event_badge_obj_li_load_promise;
}
</script>
<svelte:head>
{#if event_badge_obj_li_load_promise}
<!-- <link rel="stylesheet" href="{event_badge_obj.event_badge_template.style_href}"> -->
{/if}
</svelte:head>
{#await initial_loading_promise}
Getting badge list...
{:then}
<!-- Done -->
{/await}
{#if event_badge_obj_li_load_promise}
<section class="event_badge_list_wrapper event_badge_list">
{#each $slct_event_badge_obj_li as event_badge_obj, index}
<Event_badge_view_badge_obj event_badge_id={event_badge_obj.event_badge_id_random} mass_print={true} slct_this_badge={false} />
{/each}
</section>
<!-- <Event_badge_menu_element event_badge_obj={$slct_event_badge_obj} on:event_badge_obj_updated={() => {console.log('From list mod... badge updated.');}} /> -->
{/if}
<!-- <Access_type_element /> -->
<style>
</style>

View File

@@ -0,0 +1,710 @@
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';
import { Element_modal_v3 } from 'aether_npm_lib';
import { cfg, client, page, slct, slct_trigger, ae_com } from '../../stores_mod_events';
// import { slct_event_badge_id, slct_event_badge_obj } from '../../event/stores_event.js';
import { update_event_badge_obj } from '../../event/stores_event_api.js';
export let event_badge_obj = { event_badge_id_random: '', event_id_random: '', title_names: '', given_name: '', family_name: '', designations: '', full_name: '', full_name_override: '', professional_title: '', professional_title_override: '', affiliations: '', affiliations_override: '', location: '', location_override: '', state_province: '', full_address: '', email: '', other_1: '', other_2: '', ticket_1_code: '', ticket_2_code: '', ticket_3_code: '', ticket_4_code: '', ticket_5_code: '', badge_type_code: '', badge_type_code_override: '', badge_type: '', badge_type_override: '', allow_tracking: '', event_badge_template: { logo_path: '' }, print_first_datetime: '' };
export let mass_print: boolean = false;
let event_badge_obj_load_promise = null;
let event_badge_obj_update_promise = null;
let use_badge_type = null;
let use_badge_type_code = null;
export let use_badge_type_code_list: string|Array<{code: string; name: string;}> = [];
export let use_badge_ticket_list: string|Array<{num: string; name: string;}> = [];
let show_event_badge_render_image = false;
let allow_tracking: boolean = false;
// This should not really be needed. The list should already be passed as a list.
if (typeof use_badge_type_code_list == 'string') {
use_badge_type_code_list = JSON.parse(use_badge_type_code_list);
}
if (use_badge_type_code_list) {
// console.log(`use_badge_type_code_list:`,use_badge_type_code_list);
} else {
use_badge_type_code_list = [];
use_badge_type_code_list.push({code: 'MBR', name: 'Member'});
use_badge_type_code_list.push({code: 'AHMB', name: 'Member'});
use_badge_type_code_list.push({code: 'SNMB', name: 'Student/Trainee Non-Member'});
use_badge_type_code_list.push({code: 'SMBR', name: 'Student/Trainee Member'});
use_badge_type_code_list.push({code: 'NMBR', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'ANHM', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'INMB', name: 'Non-Member'});
use_badge_type_code_list.push({code: 'EXO', name: 'Exhibitor Booth Staff'});
use_badge_type_code_list.push({code: 'EXALL', name: 'Exhibitor All Access'});
use_badge_type_code_list.push({code: 'GUEST', name: 'Guest'});
use_badge_type_code_list.push({code: 'HEART', name: 'HFTX Core'});
use_badge_type_code_list.push({code: 'LUNG', name: 'LTX Core'});
use_badge_type_code_list.push({code: 'STAFF', name: 'Staff'});
use_badge_type_code_list.push({code: 'VIP', name: 'VIP'});
use_badge_type_code_list.push({code: 'VOL', name: 'Volunteer'});
}
// console.log(use_badge_ticket_list);
if (typeof use_badge_ticket_list == 'string') {
use_badge_ticket_list = JSON.parse(use_badge_ticket_list);
}
if (use_badge_ticket_list) {
} else {
use_badge_ticket_list = [];
use_badge_ticket_list.push({num: 1, name: 'Placeholder 1'});
use_badge_ticket_list.push({num: 2, name: 'Placeholder 2'});
use_badge_ticket_list.push({num: 3, name: 'Placeholder 3'});
}
const dispatch = createEventDispatcher();
onMount(() => {
console.log('** Component Mounted: ** Event Badge Menu');
});
// function handle_print_badge() {
// // Should this be async?
// return false;
// }
function handle_print_badge(event_badge_id, print_count=0) {
console.log('*** handle_print_badge() ***');
console.log(`Event Badge ID: ${event_badge_id}; Print Count: print_count`);
print_count++;
// if (print_count) {
// } else {
// }
let data = {};
data['print_count'] = print_count;
let current_datetime = new Date();
if (!event_badge_obj.print_first_datetime) {
data['print_first_datetime'] = current_datetime;
}
data['print_last_datetime'] = current_datetime;
event_badge_obj_update_promise = update_event_badge_obj({event_badge_id:event_badge_id, data: data, log_lvl: 2});
// event_badge_obj = event_badge_obj_update_promise;
// $slct.event_badge_obj = event_badge_obj_update_promise;
// $slct_user_obj = event_badge_obj_update_promise.user;
console.log('Badge count updated');
window.print();
// console.log('Printed?');
let event_badge_printed_list = JSON.parse(window.localStorage.getItem(`event_badge_printed_list`));
// console.log(event_badge_printed_list);
if (event_badge_printed_list && event_badge_printed_list.includes(event_badge_obj.event_badge_id_random)) {
console.log('Already printed badge.');
} else if (event_badge_printed_list && !event_badge_printed_list.includes(event_badge_obj.event_badge_id_random)) {
console.log('Adding badge to printed list.');
event_badge_printed_list.push(event_badge_obj.event_badge_id_random);
localStorage.setItem('event_badge_printed_list', JSON.stringify(event_badge_printed_list));
} else {
console.log('Starting new badge printed list. Adding badge to printed list.');
event_badge_printed_list = [];
event_badge_printed_list.push(event_badge_obj.event_badge_id_random);
localStorage.setItem('event_badge_printed_list', JSON.stringify(event_badge_printed_list));
}
dispatch(
'event_badge_obj_printing',
{
event_badge_id: event_badge_id,
event_badge_obj: event_badge_obj,
}
);
}
async function handle_update_allow_tracking(event_badge_id, allow) {
console.log('*** handle_update_allow_tracking() ***');
console.log(`Allow Tracking: ${allow}`);
let data = {};
data['allow_tracking'] = allow;
event_badge_obj_update_promise = await update_event_badge_obj({event_badge_id: event_badge_id, data: data, log_lvl: 1});
// event_badge_obj = event_badge_obj_update_promise;
// $slct_event_badge_obj = event_badge_obj_update_promise;
// $slct_user_obj = event_badge_obj_update_promise.user;
if (allow) {
console.log('Attendee tracking is allowed');
// show_allow_tracking = false;
allow_tracking = true;
} else {
console.log('Attendee tracking is not allowed');
// show_allow_tracking = true;
allow_tracking = false;
}
dispatch(
'event_badge_obj_updated',
{
event_badge_id: event_badge_id,
event_badge_obj: event_badge_obj,
}
);
return event_badge_obj_update_promise;
}
async function handle_update_badge_field(event_badge_id, field_name , value) {
console.log('*** handle_update_badge_field() ***');
console.log(`Field Name: ${field_name}; Value: ${value}`);
// ticket_x_code
let data = {};
if (field_name) {
data[field_name] = value;
} else {
return false;
}
event_badge_obj_update_promise = await update_event_badge_obj({event_badge_id: event_badge_id, data: data, log_lvl: 1});
event_badge_obj[field_name] = value;
// slct_event_badge_obj.set(event_badge_obj);
// console.log($slct_event_badge_obj);
dispatch(
'event_badge_obj_updated',
{
event_badge_id: event_badge_id,
event_badge_obj: event_badge_obj,
}
);
return event_badge_obj_update_promise;
}
function font_size(obj_type, obj_id, obj_prop, delta) {
let selector = `#${obj_type}_${obj_id} .${obj_prop}`;
let element = document.querySelector(selector);
console.log(element);
let computed_styles = window.getComputedStyle(element);
// //Take out the px in the end
// let current_font_size = element.style.fontSize.slice(0, -2);
// console.log('current_font_size', current_font_size);
// //Make currenFontSize an Integer
// current_font_size = parseInt(current_font_size);
let font_size_string = computed_styles.getPropertyValue('font-size');
console.log('font_size_string', font_size_string);
let current_font_size = parseInt(font_size_string);
let new_font_size = current_font_size + delta;
console.log('new_font_size', new_font_size);
element.style.fontSize = new_font_size+'px';
// element.style.fontSize = new_font_size+'in';
// element.style.fontSize = '.4in';
}
function handle_render_badge_image(event_badge_id) {
console.log('*** handle_render_badge_image() ***');
show_event_badge_render_image = true;
let badge_front = document.querySelector(`#event_badge_${event_badge_id}.event_badge_wrapper .badge_front`);
badge_front.querySelector('img.qr_code').style.removeProperty('top');
badge_front.querySelector('img.qr_code').style.removeProperty('right');
badge_front.querySelector('img.qr_code').style.bottom = 0;
badge_front.querySelector('img.qr_code').style.left = 0;
badge_front.querySelector('.badge_body').appendChild(badge_front.querySelector('img.qr_code'));
badge_front.querySelector('.badge_body>.affiliations_location').style.maxWidth = '3in';
badge_front.querySelector('.badge_body>.affiliations_location').style.alignSelf = 'flex-end';
badge_front.querySelector('.badge_body>.affiliations_location').style.textAlign = 'right';
console.log(window.devicePixelRatio);
// https://html2canvas.hertzen.com
// Under aether_app/static/js/html2canvas.min.js
console.log('BEGIN: Render to canvas?');
html2canvas(document.querySelector(`#event_badge_${event_badge_id}.event_badge_wrapper .badge_body`), {'scale': 2}).then(function(canvas) {
// document.body.appendChild(canvas);
let render_to_element = document.getElementById('event_badge_render_image');
render_to_element.appendChild(canvas);
canvas.toBlob(function(blob) {
const new_image = document.createElement('img');
const url = URL.createObjectURL(blob);
console.log(new_image);
// let new_blob = new_image.blob();
// new_image.onload = function() {
// // no longer need to read the blob so it's revoked
// URL.revokeObjectURL(url);
// };
new_image.src = url;
// document.body.appendChild(new_image);
// navigator.clipboard.write([new ClipboardItem({ 'image/png': new_image })]);
navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })])
});
// let render_blob = render_to_element.blob();
// navigator.clipboard.write([new ClipboardItem({ 'image/png': new_image })])
/* Get the text field */
// let copy_content = document.getElementById('event_badge_render_image');
// console.log
/* Select the text field */
// render_to_element.select();
// copy_content.setSelectionRange(0, 99999); /*For mobile devices*/
/* Copy the text inside the text field */
// document.execCommand('copy');
alert('The content has been copied to your clipboard.');
});
console.log('END: Render to canvas?');
}
</script>
{#if event_badge_obj}
<section id="event_badge_render_menu" class="event_badge_render_menu pull-left hidden-print affix">
{#if mass_print}<strong>{event_badge_obj.given_name} {event_badge_obj.family_name}</strong>{/if}
<section class="event_badge_render_navigate">
<!-- <button onclick="window.history.back();" class="ae_btn btn_lg btn_secondary"><span class="fas fa-arrow-left"></span> Back</button> -->
{#if !mass_print}
<div>
<button class="ae_btn btn_lg btn_success btn_print margin_xs margin_h_xl" on:click={() => {handle_print_badge(event_badge_obj.event_badge_id_random, event_badge_obj.print_count);}}>
<span class="fas fa-print"></span> Print Your Badge
</button>
</div>
{/if}
<div>
<!-- <a href="/event/{event_badge_obj.event_id_random}/badge" class="ae_btn btn_lg btn_secondary margin_md margin_h_xl">
<span class="fas fa-arrow-left"></span> New Search
</a> -->
<button
class="ae_btn btn_lg btn_secondary margin_xs margin_h_xl"
on:click={() => {
let redirect_path = localStorage.getItem('ae_badge_printed_redirect_path');
if (redirect_path == '/events_badges/review') {
window.location.href = redirect_path;
} else {
// Use old default
window.location.href = `/event/${event_badge_obj.event_id_random}/badge`;
}
}}
>
<span class="fas fa-arrow-left"></span>
New Search
</button>
</div>
<!-- {#if $client.authenticated_access || $ae_com.authenticated_access}
Authenticated
{/if} -->
{#if $client.trusted_access || $ae_com.trusted_access}
<!-- <button class="ae_btn btn_md btn_warning btn_edit" onclick="return confirm('Are you sure you want to edit this badge?');"><span class="fas fa-edit"></span> Edit Badge</button> -->
{/if}
{#if $client.administrator_access || $ae_com.administrator_access}
<button class="ae_btn btn_lg btn_success btn_print" on:click={() => {handle_render_badge_image(event_badge_obj.event_badge_id_random);}}>
<span class="fas fa-magic"></span> Render Badge Image
</button>
{/if}
</section>
<!-- <hr /> -->
<section class="event_badge_tracking">
<button on:click={() => {handle_update_allow_tracking($slct.event_badge_id, true);}} class="ae_btn btn_sm btn_default">I Agree - Allow lead retrieval</button>
<button on:click={() => {handle_update_allow_tracking($slct.event_badge_id, false);}} class="ae_btn btn_sm btn_default">I Do <strong>Not</strong> Agree - Do not allow lead retrieval</button>
</section>
<!-- <hr /> -->
<section class="event_badge_render_modify">
<h1>Modify Badge</h1>
<!-- <div class="event_badge_render_font_size_text"> -->
<section>
<h2>
<span>Display Name:</span>
<span>
<button on:click={font_size('event_badge', event_badge_obj.event_badge_id_random, 'full_name_override_all', -1)} class="ae_btn btn_sm btn_default"><span class="fas fa-minus"></span> Smaller</button>
<button on:click={font_size('event_badge', event_badge_obj.event_badge_id_random, 'full_name_override_all', 1)} class="ae_btn btn_sm btn_default"><span class="fas fa-plus"></span> Larger</button>
</span>
</h2>
{#if $client.trusted_access || $ae_com.trusted_access}
<div class="menu_full_name_override edit_container">
<!-- {#if $client.authenticated_access}
<input type="text" bind:value="{event_badge_obj.given_name}" placeholder="Given/First Name" size="8" />
{:else}
<div class="input_disabled_message" class:d_none={admin_mode}>First names can only be changed by staff.</div>
<input type="text" bind:value="{event_badge_obj.given_name}" placeholder="Given/First Name" size="8" disabled={!admin_mode} />
{/if}
<input type="text" bind:value="{event_badge_obj.family_name}" placeholder="Family/Last Name" size="8" />
{#if $client.authenticated_access || event_badge_obj.designations}
<input type="text" bind:value="{event_badge_obj.designations}" placeholder="Designations/Suffix" size="5" />
{/if} -->
<input type="text" bind:value="{event_badge_obj.full_name_override}" placeholder="Display Name" size="8" />
<span class="btn_group">
<button
class="ae_btn btn_sm btn_warning"
on:click={async () => {
let saving_promise = handle_update_badge_field(event_badge_obj.event_badge_id_random, 'full_name_override', event_badge_obj.full_name_override)
.then(function (result) {
// edit_title_names = false;
// edit_full_name_override = false;
// edit_designations = false;
});
}}
>
{#await event_badge_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
{#if event_badge_obj.full_name_override}
<button
class="ae_btn btn_sm btn_secondary"
on:click={async () => {
let saving_promise = handle_update_badge_field(event_badge_obj.event_badge_id_random, 'full_name_override', null)
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span><!-- Reset-->
</button>
{/if}
<!-- <input type="text" bind:value="{event_badge_obj.designations}" placeholder="Designations/Suffix" size="5" /> -->
</span>
</div>
{/if}
</section>
<section>
<h2>
<!-- <span>Professional Title:</span> -->
<span><!-- Professional -->Title/Degrees/Credentials:</span>
<span>
<button on:click={font_size('event_badge', event_badge_obj.event_badge_id_random, 'professional_title', -1)} class="ae_btn btn_sm btn_default"><span class="fas fa-minus"></span> Smaller</button>
<button on:click={font_size('event_badge', event_badge_obj.event_badge_id_random, 'professional_title', 1)} class="ae_btn btn_sm btn_default"><span class="fas fa-plus"></span> Larger</button>
</span>
</h2>
<div class="menu_professional_title edit_container">
<input type="text" bind:value="{event_badge_obj.professional_title_override}" placeholder="Professional Title" size="15" />
<span class="btn_group">
<button
class="ae_btn btn_sm btn_warning"
on:click={async () => {
let saving_promise = handle_update_badge_field(event_badge_obj.event_badge_id_random, 'professional_title_override', event_badge_obj.professional_title_override)
.then(function (result) {
// edit_professional_title_override = false;
});
}}
>
{#await event_badge_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
{#if event_badge_obj.professional_title_override}
<button
class="ae_btn btn_sm btn_secondary"
on:click={async () => {
let saving_promise = handle_update_badge_field(event_badge_obj.event_badge_id_random, 'professional_title_override', null)
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span><!-- Reset-->
</button>
{/if}
</span>
</div>
</section>
<section>
<h2>
<span>Affiliations:</span>
<span>
<button on:click={font_size('event_badge', event_badge_obj.event_badge_id_random, 'affiliations', -1)} class="ae_btn btn_sm btn_default"><span class="fas fa-minus"></span> Smaller</button>
<button on:click={font_size('event_badge', event_badge_obj.event_badge_id_random, 'affiliations', 1)} class="ae_btn btn_sm btn_default"><span class="fas fa-plus"></span> Larger</button>
</span>
</h2>
<div class="menu_affiliations edit_container">
<input type="text" bind:value="{event_badge_obj.affiliations_override}" placeholder="Affiliations" size="15" />
<span class="btn_group">
<button
class="ae_btn btn_sm btn_warning"
on:click={async () => {
let saving_promise = handle_update_badge_field(event_badge_obj.event_badge_id_random, 'affiliations_override', event_badge_obj.affiliations_override)
.then(function (result) {
// edit_affiliations_override = false;
});
}}
>
{#await event_badge_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
{#if event_badge_obj.affiliations_override}
<button
class="ae_btn btn_sm btn_secondary"
on:click={async () => {
let saving_promise = handle_update_badge_field(event_badge_obj.event_badge_id_random, 'affiliations_override', null)
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span><!-- Reset-->
</button>
{/if}
</span>
</div>
</section>
<section>
<h2>
<span>Location:</span>
<span>
<button on:click={font_size('event_badge', event_badge_obj.event_badge_id_random, 'location', -1)} class="ae_btn btn_sm btn_default"><span class="fas fa-minus"></span> Smaller</button>
<button on:click={font_size('event_badge', event_badge_obj.event_badge_id_random, 'location', 1)} class="ae_btn btn_sm btn_default"><span class="fas fa-plus"></span> Larger</button>
</span>
</h2>
<div class="menu_location edit_container">
<input type="text" bind:value="{event_badge_obj.location_override}" placeholder="Location" size="15" />
<span class="btn_group">
<button
class="ae_btn btn_sm btn_warning"
on:click={async () => {
let saving_promise = handle_update_badge_field(event_badge_obj.event_badge_id_random, 'location_override', event_badge_obj.location_override)
.then(function (result) {
// edit_location_override = false;
});
}}
>
{#await event_badge_obj_update_promise}
Saving...
{:then}
<span class="fas fa-save"></span> Save
{/await}
</button>
{#if event_badge_obj.location_override}
<button
class="ae_btn btn_sm btn_secondary"
on:click={async () => {
let saving_promise = handle_update_badge_field(event_badge_obj.event_badge_id_random, 'location_override', null)
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span><!-- Reset-->
</button>
{/if}
</span>
</div>
</section>
{#if $client.trusted_access || $ae_com.trusted_access}
<section class="event_badge_render_footer">
<h2>Badge Type</h2>
<div class="menu_badge_type edit_container">
{#if use_badge_type_code_list}
<select
bind:value={use_badge_type_code}
on:change={() => {
for (var i = 0; i < use_badge_type_code_list.length; i++) {
if (use_badge_type_code_list[i].code == use_badge_type_code) {
// Version 0:
// Works but never saves.
use_badge_type = use_badge_type_code_list[i].name;
// Version 1:
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'badge_type_code_override', use_badge_type_code)
.then(async function (result) {
let saving_promise = await handle_update_badge_field(event_badge_obj.event_badge_id_random, 'badge_type_override', use_badge_type)
})
.then(function (result) {
// location.reload();
});
// Version 2:
// handle_update_badge_field($slct.event_badge_id, 'badge_type_code_override', use_badge_type_code);
// handle_update_badge_field($slct.event_badge_id, 'badge_type_override', use_badge_type_code_list[i].name);
}
}
}}
>
{#each use_badge_type_code_list as use_badge_type_code }
<option value="{use_badge_type_code.code}">{use_badge_type_code.name}</option>
{/each}
<!-- <option value="MBR">Member</option> -->
<!-- <option value="AHMB">Member (Allied Health)</option> -->
<!-- <option value="SNMB">Student/Trainee Non-Member</option> -->
<!-- <option value="SMBR">Student/Trainee Member</option> -->
<!-- <option value="NMBR">Non-Member</option> -->
<!-- <option value="ANHM">Non-Member (Allied Health)</option> -->
<!-- <option value="INMB">Non-Member (International)</option> -->
<!-- <option value="EXO">Exhibitor Booth Staff</option> -->
<!-- <option value="EXALL">Exhibitor All Access</option> -->
<!-- <option value="EX">Exhibit Staff</option> -->
<!-- <option value="HEART">HFTX Core</option> -->
<!-- <option value="LUNG">LTX Core</option> -->
<!-- <option value="GUEST">Guest Registration</option> -->
<!-- <option value="STAFF">Staff</option> -->
<!-- <option value="VIP">VIP</option> -->
<!-- <option value="VOL">Volunteer</option> -->
</select>
{/if}
<span class="btn_group">
{#if event_badge_obj.badge_type_code_override}
<button
class="ae_btn btn_sm btn_secondary"
on:click={async () => {
let saving_promise = handle_update_badge_field($slct.event_badge_id, 'badge_type_code_override', null)
.then(async function (result) {
let saving_promise = await handle_update_badge_field($slct.event_badge_id, 'badge_type_override', null)
})
.then(function (result) {
location.reload();
});
}}
title="Reset"
>
<span class="fas fa-undo"></span><!-- Reset-->
</button>
{/if}
</span>
</div>
</section>
{/if}
<!-- </div> -->
<!-- {#if $ae_com.access_type == 'trusted'} -->
{#if $client.trusted_access || $ae_com.trusted_access}
<!-- <section class="event_badge_special_options">
<div>
<button on:click={() => {handle_update_badge_field($slct.event_badge_id, 'ticket_1_code', 'leadership_lounge');}} class="ae_btn btn_sm btn_default"><span class="fas fa-plus"></span> Lounge Pass</button>
<button on:click={() => {handle_update_badge_field($slct.event_badge_id, 'ticket_1_code', null);}} class="ae_btn btn_sm btn_default"><span class="fas fa-minus"></span> Lounge Pass</button>
</div>
<div>
<button on:click={() => {handle_update_badge_field($slct.event_badge_id, 'ticket_2_code', 'volunteer_reception');}} class="ae_btn btn_sm btn_default"><span class="fas fa-plus"></span> Volunteer Reception</button>
<button on:click={() => {handle_update_badge_field($slct.event_badge_id, 'ticket_2_code', null);}} class="ae_btn btn_sm btn_default"><span class="fas fa-minus"></span> Volunteer Reception</button>
</div>
<div>
<button on:click={() => {handle_update_badge_field($slct.event_badge_id, 'ticket_3_code', 'first_timers_breakfast');}} class="ae_btn btn_sm btn_default"><span class="fas fa-plus"></span> First Time Breakfast</button>
<button on:click={() => {handle_update_badge_field($slct.event_badge_id, 'ticket_3_code', null);}} class="ae_btn btn_sm btn_default"><span class="fas fa-minus"></span> First Time Breakfast</button>
</div>
</section> -->
<section class="event_badge_ticket_options">
<ul class="btn_list">
{#each use_badge_ticket_list as ticket_option }
<li>
<button on:click={() => {handle_update_badge_field($slct.event_badge_id, `ticket_${ticket_option.num}_code`, ticket_option.code);}} class="ae_btn btn_sm btn_default margin_0"><span class="fas fa-plus"></span></button>
<button on:click={() => {handle_update_badge_field($slct.event_badge_id, `ticket_${ticket_option.num}_code`, null);}} class="ae_btn btn_sm btn_default margin_0"><span class="fas fa-minus"></span></button>
<span class="ticket_option_name">{ticket_option.name}</span>
</li>
{/each}
</ul>
</section>
{/if}
</section>
</section>
{/if}
{#if show_event_badge_render_image}
<Element_modal_v3
show = { true }
modal_cover_body = { true }
on:close={ () => {show_event_badge_render_image = false;} }
>
<span slot="header_title">
Rendered Badge Body
</span>
<span slot="body">
<div id="event_badge_render_image">
</div>
</span>
</Element_modal_v3>
{/if}
<style>
</style>