Resolved a critical parsing error in leads_view_lead.svelte due to incorrect Svelte class directive syntax.
Addressed multiple svelte/no-at-html-tags linting errors across the following files to mitigate potential XSS vulnerabilities and improve code safety:
- src/routes/events_leads/exhibit/[slug]/leads_add_scan.svelte
- src/routes/events_leads/exhibit/[slug]/leads_manage.svelte
- src/routes/events_leads/exhibit/[slug]/leads_view_lead.svelte
Replaced {@html} blocks with safer Svelte conditional rendering ({#if}) and direct interpolation ({value}) for static and dynamic content where appropriate. Removed commented-out {@html} tags that were still triggering linting errors.
1056 lines
37 KiB
Svelte
1056 lines
37 KiB
Svelte
<script lang="ts">
|
|
console.log(`ae_events_leads exhibit [slug] leads_add_scan.svelte`, $events_slct);
|
|
|
|
import type { key_val } from '$lib/stores/ae_stores';
|
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
|
import { liveQuery } from 'dexie';
|
|
import { db_events } from '$lib/ae_events/db_events';
|
|
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
|
|
// import { core_func } from '$lib/ae_core_functions';
|
|
import {
|
|
events_loc,
|
|
events_sess,
|
|
events_slct,
|
|
events_trigger
|
|
} from '$lib/stores/ae_events_stores';
|
|
import { events_func } from '$lib/ae_events_functions';
|
|
|
|
import Element_qr_scanner from '$lib/element_qr_scanner_v2.svelte';
|
|
|
|
// TEMPORARY: For testing and development???
|
|
if ($events_loc.leads.default_to_scan ?? false) {
|
|
// $events_sess.leads.show_form__search = true;
|
|
$events_sess.leads.show_form__scan = true;
|
|
$events_sess.leads.qr_scan_start = true;
|
|
}
|
|
// TEMPORARY: For testing and development???
|
|
|
|
$: event_exhibit_obj = liveQuery(() => db_events.exhibit.get($events_slct.exhibit_id));
|
|
|
|
$: event_exhibit_tracking_obj = liveQuery(() =>
|
|
db_events.exhibit_tracking.get($events_slct.exhibit_tracking_id)
|
|
);
|
|
|
|
$events_sess.leads.entered_search_str = '';
|
|
// $events_sess.leads.entered_search_str = 'Albert Einstein';
|
|
|
|
let tmp_search_terms = $events_sess.leads.entered_search_str.split(' ');
|
|
|
|
$: event_badge_obj = liveQuery(() => db_events.badge.get($events_slct.badge_id));
|
|
|
|
// Version 2: This does not work yet
|
|
let event_badge_obj_li = liveQuery(
|
|
// () => db_events.exhibit.toArray()
|
|
() =>
|
|
db_events.badge
|
|
// .where({event_exhibit_id_random: $events_slct.exhibit_id, enable: true, hide: false})
|
|
// .where({event_id_random: $events_loc.event_id})
|
|
.where('event_id_random')
|
|
.equals($events_loc.event_id)
|
|
// .where('event_id_random').equals($events_slct.event_id)
|
|
// .or('full_name').equalsIgnoreCase($events_sess.leads.entered_search_str)
|
|
// .and('full_name').anyOfIgnoreCase([$events_sess.leads.entered_search_str, 'Sasa Vukelic'])
|
|
// .where('full_name').anyOfIgnoreCase(tmp_search_terms)
|
|
// .and('enable').equals(true)
|
|
.sortBy('full_name') // Use sortBy() instead of orderBy(). toArray() is also not needed???
|
|
// .toArray()
|
|
|
|
// , full_name: 'Susan'
|
|
// Scott Idem
|
|
// Albert Einstein
|
|
);
|
|
|
|
// We are using Dexie.js for the database. This liveQuery should only show records that match the event_id and contain the search string.
|
|
// Version 3: This does not work yet
|
|
let event_badge_obj_li_v3 = liveQuery(
|
|
// () => db_events.exhibit.toArray()
|
|
() =>
|
|
db_events.badge.where({
|
|
event_exhibit_id_random: $events_slct.exhibit_id,
|
|
full_name: $events_sess.leads.entered_search_str
|
|
})
|
|
);
|
|
|
|
let search_submit_results: Promise<any> | key_val;
|
|
let scan_submit_results: Promise<any> | key_val;
|
|
|
|
let mecard;
|
|
let show_mecard = false;
|
|
|
|
async function handle_submit_form_search(event) {
|
|
console.log('*** handle_submit_form_search() ***', event);
|
|
|
|
$events_sess.leads.submit_status__search = 'submitting';
|
|
|
|
let search_str = $events_sess.leads.entered_search_str.trim();
|
|
console.log(search_str);
|
|
|
|
search_submit_results = await events_func.search__event_badge({
|
|
api_cfg: $ae_api,
|
|
event_id: $event_exhibit_obj?.event_id_random,
|
|
fulltext_search_qry_str: search_str,
|
|
external_event_id: $events_loc.leads.default__external_registration_id
|
|
});
|
|
console.log(search_submit_results);
|
|
|
|
$events_slct.badge_obj_li = search_submit_results;
|
|
}
|
|
|
|
let load_event_badge_results = null;
|
|
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 qr_scan_obj = ae_util.process_data_string(qr_scan_result);
|
|
|
|
if (qr_scan_obj.qr_type == 'OBJ') {
|
|
console.log(`Got a QR type of OBJ. Type ${qr_scan_obj.type}; ID ${qr_scan_obj.id}`);
|
|
|
|
if (qr_scan_obj.type && qr_scan_obj.id && qr_scan_obj.type == 'event_badge') {
|
|
console.log(`Found an Event Badge object type and ID.`);
|
|
let event_badge_id = qr_scan_obj.id;
|
|
|
|
$events_sess.leads.qr_scan_result = `Found a badge type with ID: ${event_badge_id}`;
|
|
|
|
load_event_badge_results = events_func
|
|
.handle_load_ae_obj_id__badge({ api_cfg: $ae_api, badge_id: event_badge_id })
|
|
.then((result) => {
|
|
$events_slct.badge_id = event_badge_id;
|
|
$events_slct.badge_obj = result;
|
|
console.log(result);
|
|
});
|
|
|
|
// event_exhibit_tracking_obj_create_promise = await handle_create_event_exhibit_tracking_obj($slct.event_exhibit_id, event_badge_id);
|
|
// console.log(event_exhibit_tracking_obj_create_promise);
|
|
// if (event_exhibit_tracking_obj_create_promise) {
|
|
// console.log('Created new log entry for this badge.');
|
|
// console.log(event_exhibit_tracking_obj_create_promise);
|
|
|
|
// handle_load_event_exhibit_obj({event_exhibit_id: $slct.event_exhibit_id, try_cache: false});
|
|
|
|
// $slct.event_exhibit_tracking_obj = event_exhibit_tracking_obj_create_promise;
|
|
// $slct.event_exhibit_tracking_id = $slct.event_exhibit_tracking_obj.event_exhibit_tracking_id_random;
|
|
// // $slct.event_badge_obj = $slct.event_exhibit_tracking_obj.event_badge;
|
|
// // $slct.event_badge_id = $slct.event_badge_obj.event_badge_id_random;
|
|
// show_add_qr = false;
|
|
// qr_scan_result = '';
|
|
// qr_scan_obj = {};
|
|
// show_tracking_entry = true;
|
|
// } else if (event_exhibit_tracking_obj_create_promise === null) {
|
|
// console.log('A matching log entry probably exists for this person!');
|
|
// } else {
|
|
// console.log('Something unexpected happened???');
|
|
// }
|
|
|
|
$events_sess.leads.show_confirm__add_lead[event_badge_id] = true;
|
|
} else if (qr_scan_obj.type && qr_scan_obj.id && qr_scan_obj.type == 'event_exhibit') {
|
|
console.log(`Ignoring.`);
|
|
} else if (qr_scan_obj.type && qr_scan_obj.id && qr_scan_obj.type == 'event_person') {
|
|
console.log(`Ignoring.`);
|
|
} else if (qr_scan_obj.type && qr_scan_obj.id && qr_scan_obj.type == 'event_session') {
|
|
console.log(`Ignoring.`);
|
|
} else {
|
|
console.log(`Ignoring. The object returned was unexpected or not valid.`);
|
|
console.log(qr_scan_obj);
|
|
}
|
|
} else if (qr_scan_obj && qr_scan_obj.qr_type == 'MECARD') {
|
|
console.log(
|
|
`Got a QR type of MECARD. This was not expected, but we will at least display it???`
|
|
);
|
|
|
|
// https://github.com/ertant/vCard
|
|
// vcard = vCardParser.parse(qr_scan_obj.str); // vCard
|
|
// console.log(vcard);
|
|
|
|
mecard = qr_scan_obj.str.split(';'); // vCard
|
|
// NOTE: Next we need to loop through the values and split each again on ":".
|
|
// NOTE: Then probably do a second check based on the known key values (N, EMAIL, ADR).
|
|
console.log(mecard);
|
|
|
|
show_mecard = true;
|
|
} else {
|
|
console.log(
|
|
`Got a QR type of ${qr_scan_obj.qr_type}. Display warning to user, but otherwise ignoring.`
|
|
);
|
|
console.log(qr_scan_obj);
|
|
}
|
|
}
|
|
|
|
function handle_qr_camera(event: CustomEvent<any>) {
|
|
console.log('*** handle_qr_camera() ***', event.detail);
|
|
|
|
if (!$ae_loc.hub.qr) {
|
|
$ae_loc.hub.qr = {};
|
|
}
|
|
|
|
if (event.detail.status == 'allowed') {
|
|
// console.log('Camera access allowed');
|
|
$ae_loc.hub.qr.camera_status = 'allowed';
|
|
} else if (event.detail.status == 'denied') {
|
|
console.log('Camera access denied!?');
|
|
$ae_loc.hub.qr.camera_status = 'denied';
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<section
|
|
class="tab__add_section min-w-full flex flex-col wrap justify-center items-center space-y-4 ae_h_scrollfix"
|
|
>
|
|
{#if $events_loc?.leads.auth_exhibit_kv && $events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id]}
|
|
{#if $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
|
|
<div>
|
|
Leads for:
|
|
<strong>{$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}</strong>
|
|
</div>
|
|
{:else}
|
|
<div class="border border-slate-500/10 p-2 preset-tonal-warning">
|
|
Please go to the Main tab and select a license to use.
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- <div class="border border-slate-500/10 p-2 variant-soft-warning">This section is not fully enabled for ISHLT 2024 at this time. The ability to add a lead by scanning the attendee's QR code or by searching for their name, will be enabled before the ISHLT 2024 Annual Meeting in Prague.</div> -->
|
|
|
|
<p>
|
|
<!-- This page is used to test QR scanning with your device. -->
|
|
{#if $ae_loc.hub.qr.camera_status == 'unknown'}
|
|
<strong>You will need to allow access to your device's camera when asked.</strong>
|
|
{:else if $ae_loc.hub.qr.camera_status == 'denied'}
|
|
<strong
|
|
>You need to allow access to your device's camera. Currently this seems to be blocked or
|
|
denied for this site.</strong
|
|
>
|
|
Please check your browser's permissions.
|
|
{/if}
|
|
</p>
|
|
<!--
|
|
<Element_qr_scanner
|
|
start_qr_scanner={false}
|
|
show_qr_scan_result={true}
|
|
show_qr_manual_badge_id_entry_option={true}
|
|
on:qr_scan_result={handle_qr_scan_result}
|
|
on:qr_camera={handle_qr_camera}
|
|
/> -->
|
|
|
|
<span class="flex flex-col md:flex-row wrap gap-1 justify-center items-center">
|
|
<button
|
|
class="btn btn-lg preset-tonal-primary border border-primary-500 m-1 w-64 add_person_qr_btn"
|
|
on:click={() => {
|
|
// $slct.event_exhibit_tracking_id = null;
|
|
// $slct.event_exhibit_tracking_obj = null;
|
|
// show_add_qr = true;
|
|
// qr_scan_obj = null;
|
|
// event_exhibit_tracking_obj_create_promise = null;
|
|
$events_sess.leads.show_form__scan = true;
|
|
$events_sess.leads.qr_scan_start = true;
|
|
}}
|
|
title="Scan a QR code to add a person to the leads list."
|
|
>
|
|
<span class="fas fa-qrcode mx-2"></span>
|
|
Scan to Add Person
|
|
</button>
|
|
|
|
<button
|
|
class="btn btn-lg preset-tonal-primary border border-primary-500 m-1 w-64 add_person_search_btn"
|
|
on:click={() => {
|
|
// $slct.event_exhibit_tracking_id = null;
|
|
// $slct.event_exhibit_tracking_obj = null;
|
|
// show_add_search = true;
|
|
// qr_scan_obj = null;
|
|
// event_exhibit_tracking_obj_create_promise = null;
|
|
$events_sess.leads.show_form__search = true;
|
|
}}
|
|
title="Search for a person to add to the leads list."
|
|
>
|
|
<span class="fas fa-search mx-2"></span>
|
|
Search to Add Person
|
|
</button>
|
|
</span>
|
|
|
|
<span class="flex flex-row flex-wrap gap-1 justify-center items-center">
|
|
{#if $events_loc.leads.show_content__scan_alert}
|
|
<button
|
|
class="btn btn-sm preset-tonal-warning"
|
|
on:click={() => ($events_loc.leads.show_content__scan_alert = false)}
|
|
><span class="fas fa-exclamation-triangle mx-1"></span> Hide Alert?</button
|
|
>
|
|
{:else if !$events_loc.leads.show_content__scan_alert}
|
|
<button
|
|
class="btn btn-sm preset-tonal-warning"
|
|
on:click={() => ($events_loc.leads.show_content__scan_alert = true)}
|
|
><span class="fas fa-exclamation-triangle mx-1"></span> Alert</button
|
|
>
|
|
{/if}
|
|
|
|
<button
|
|
class="btn btn-sm preset-tonal-warning"
|
|
on:click={() => {
|
|
if (!$events_loc.leads.default_to_scan) {
|
|
if (!confirm('Are you sure you want to enable the default scan option?')) {
|
|
return false;
|
|
}
|
|
}
|
|
$events_loc.leads.default_to_scan = !$events_loc.leads.default_to_scan;
|
|
}}
|
|
>
|
|
{#if $events_loc.leads.default_to_scan}
|
|
<span class="fas fa-toggle-on m-1"></span> Disable Default Scan?
|
|
{:else}
|
|
<span class="fas fa-toggle-off m-1"></span> Enable Default Scan?
|
|
{/if}
|
|
</button>
|
|
|
|
<button
|
|
class="btn btn-sm preset-tonal-warning"
|
|
on:click={() => {
|
|
if (!$events_loc.leads.auto_view) {
|
|
if (!confirm('Are you sure you want to enable the auto view new leads option?')) {
|
|
return false;
|
|
}
|
|
}
|
|
$events_loc.leads.auto_view = !$events_loc.leads.auto_view;
|
|
}}
|
|
>
|
|
{#if $events_loc.leads.auto_view}
|
|
<span class="fas fa-toggle-on m-1"></span> Disable Auto View?
|
|
{:else}
|
|
<span class="fas fa-toggle-off m-1"></span> Enable Auto View?
|
|
{/if}
|
|
</button>
|
|
|
|
{#if $events_loc.leads.show_content__scan_requirements}
|
|
<button
|
|
class="btn btn-sm preset-tonal-secondary"
|
|
on:click={() => ($events_loc.leads.show_content__scan_requirements = false)}
|
|
><span class="fas fa-info mx-1"></span> Hide Requirements?</button
|
|
>
|
|
{:else if !$events_loc.leads.show_content__scan_requirements}
|
|
<button
|
|
class="btn btn-sm preset-tonal-secondary"
|
|
on:click={() => ($events_loc.leads.show_content__scan_requirements = true)}
|
|
><span class="fas fa-info mx-1"></span> Requirements</button
|
|
>
|
|
{/if}
|
|
</span>
|
|
|
|
{#if $events_loc.leads.show_content__scan_alert}
|
|
<div class="border-slate-500/10 p-2 preset-tonal-warning">
|
|
<span class="fas fa-exclamation-triangle mx-1"></span>
|
|
<span>
|
|
<strong>Alert</strong>
|
|
<span>Use Scanner Version:</span>
|
|
<select bind:value={$ae_loc.qr_scanner_version} class="select w-52">
|
|
<option value={'one'}>v1</option>
|
|
<option value={'two'}>v2</option>
|
|
</select>
|
|
|
|
<p>
|
|
A bug was found late Monday that affects some mobile devices (cell phones and tablets).
|
|
Incremental fixes have been added, but this issue has been difficult to address across
|
|
all devices. We recommend most users stick with v1 (default). If you are not having any
|
|
trouble and have no idea what this message is about, then this is what you want.
|
|
</p>
|
|
<p>
|
|
We recommend you try v2 if you are having trouble with the camera not starting or
|
|
turning on. This version allows you to manually attempt to Allow Camera Access and to
|
|
Start Scanning if it does not start on its own. This fix is not perfect. A permanent
|
|
solution is actively being worked on in the development version.
|
|
</p>
|
|
<p>A fix is in progress to address all devices. -2024-04-10 2:25 AM (Prague time)</p>
|
|
</span>
|
|
</div>
|
|
{/if}
|
|
{#if $events_loc.leads.show_content__scan_requirements}
|
|
<div class="border border-slate-500/10 p-2 preset-tonal-secondary">
|
|
<p>
|
|
You will need a device with a camera to scan the QR codes. You will also of course need
|
|
one or more valid QR codes to scan.
|
|
<!-- <button class="ae_btn btn_sm" on:click={() => show='qr_codes'}><span class="fas fa-qrcode"></span> Example QR Codes</button> -->
|
|
</p>
|
|
<ul class="list-disc list-inside">
|
|
<li>
|
|
Most laptops, workstations, Android phones/tablets, iPhones, and iPads are compatible
|
|
</li>
|
|
<li>
|
|
The device must have a current (within the last 4 years) web browser such as Google
|
|
Chrome, Mozilla Firefox, Apple's Safari, or Microsoft Edge. Opera is not yet fully
|
|
supported.
|
|
</li>
|
|
<li>There is no Android or Apple app that needs to be installed!</li>
|
|
<li>
|
|
The device must have a camera for scanning or you will need to manually enter attendee
|
|
badge IDs.
|
|
</li>
|
|
<li>
|
|
The only permission you need to allow is access to your device's camera when asked.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
{:else}
|
|
<!-- <button class="ae_btn btn_sm btn_info" on:click={() => show_requirements=true}><span class="fas fa-eye"></span> Requirements</button> -->
|
|
{/if}
|
|
{:else}
|
|
<!-- $events_loc?.leads.auth_exhibit_kv && $events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] -->
|
|
<div class="preset-tonal-error">Not logged in. Please log in and select a user license.</div>
|
|
{/if}
|
|
<!-- $events_loc?.leads.auth_exhibit_kv && $events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] -->
|
|
</section>
|
|
|
|
{#if $events_sess.leads.show_form__search}
|
|
<div class="ae_quick_modal_container">
|
|
<section
|
|
class="
|
|
ae_quick_popover
|
|
events__leads__search
|
|
z-50
|
|
flex
|
|
flex-col
|
|
gap-4
|
|
justify-stretch
|
|
max-h-full
|
|
min-w-full
|
|
"
|
|
>
|
|
<header class="popover__header flex gap-1 justify-between items-center p-1 border-b">
|
|
<h2 class="h3">Search</h2>
|
|
|
|
<div class="">
|
|
<form
|
|
id="form__search_text"
|
|
class="form flex flex-col sm:flex-row md:flex-row lg:flex-row wrap gap-2 justify-center items-center w-full"
|
|
on:submit|preventDefault={handle_submit_form_search}
|
|
>
|
|
<!-- This is the plain text search field for looking up attendees based on their name, email, etc. The focus needs to be set automatically! -->
|
|
<input
|
|
type="text"
|
|
name="entered_search_string"
|
|
placeholder="Search for attendee"
|
|
bind:value={$events_sess.leads.entered_search_str}
|
|
required
|
|
class="input text-lg w-56"
|
|
autofocus
|
|
/>
|
|
|
|
<button type="submit" class="btn preset-tonal-primary border border-primary-500">
|
|
<span class="fas fa-search mx-1"></span>
|
|
Search
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="popover__actions">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
$events_sess.leads.show_form__search = false;
|
|
}}
|
|
>
|
|
<span class="fas fa-times mx-1"></span>
|
|
Close
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<section class="popover__content grow flex flex-col gap-4 items-center ae_modal_scrollfix">
|
|
<div class="ae_events__badge_li w-full">
|
|
{#if $event_badge_obj_li}
|
|
<!-- {#if $ae_loc.trusted_access} -->
|
|
|
|
<div class="border border-slate-500/10 p-2 preset-tonal-success min-h-96">
|
|
<p>{$events_slct.badge_obj_li.length} results found</p>
|
|
|
|
{#each $events_slct.badge_obj_li as event_badge_obj_v2, index}
|
|
<div
|
|
class="ae_events__badge_li__item flex flex-row justify-between items-center mx-0 my-2 border border-slate-500/10 p-2 hover:bg-slate-500/10"
|
|
>
|
|
<button
|
|
type="button"
|
|
on:click={() => {
|
|
// if (confirm(`Add ${event_badge_obj_v2.full_name} <${event_badge_obj_v2.email}> to the leads list?`)) {
|
|
// } else {
|
|
// return false;
|
|
// }
|
|
// console.log(`Add ${event_badge_obj_v2.full_name} ${event_badge_obj_v2.email} to the leads list`);
|
|
|
|
$events_sess.leads.show_confirm__add_lead[index] = true;
|
|
}}
|
|
title="Add {event_badge_obj_v2.full_name} to the leads list?"
|
|
class="btn btn-md preset-tonal-primary mx-1"
|
|
>
|
|
<span class="fas fa-plus mx-1"></span>
|
|
Add
|
|
</button>
|
|
|
|
<!-- This block needs to be moved or something. It takes up too much space! -->
|
|
<!-- This uses the event_badge_obj_v2 from the for each loop. -->
|
|
{#if $events_sess.leads.show_confirm__add_lead[index]}
|
|
<div class="ae_quick_modal_container">
|
|
<section
|
|
class="
|
|
ae_quick_popover_small
|
|
events__leads__scan
|
|
z-50
|
|
flex
|
|
flex-col
|
|
gap-4
|
|
justify-stretch
|
|
|
|
"
|
|
>
|
|
<header
|
|
class="popover__header flex gap-1 justify-between items-center p-1 border-b"
|
|
>
|
|
<h2 class="h3">Add Selected?</h2>
|
|
|
|
<div class="popover__actions">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
$events_sess.leads.show_confirm__add_lead[index] = false;
|
|
}}
|
|
>
|
|
<span class="fas fa-times mx-1"></span>
|
|
Close
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<section
|
|
class="popover__content grow flex flex-col gap-4 items-center ae_modal_scrollfix"
|
|
>
|
|
<p>
|
|
Are you sure you want to add <strong
|
|
>{event_badge_obj_v2.full_name}</strong
|
|
> to the leads list?
|
|
</p>
|
|
<p>
|
|
Badge ID: <strong>{event_badge_obj_v2.event_badge_id_random}</strong>
|
|
</p>
|
|
<div class="flex flex-row gap-16 justify-center items-center">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
console.log(
|
|
`Do not add ${event_badge_obj_v2.full_name} ${event_badge_obj_v2.email} to the leads list`
|
|
);
|
|
|
|
$events_sess.leads.show_confirm__add_lead[index] = false;
|
|
}}
|
|
>
|
|
<span class="fas fa-times mx-1"></span>
|
|
No
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
console.log(
|
|
`Add ${event_badge_obj_v2.full_name} ${event_badge_obj_v2.email} to the leads list`
|
|
);
|
|
|
|
// TEMPORARY: For testing and development
|
|
// if (!$ae_loc.trusted_access) {
|
|
// console.log('You do not have permission to add this person to the leads list.');
|
|
// return false;
|
|
// }
|
|
// TEMPORARY: For testing and development
|
|
|
|
events_func
|
|
.handle_create_ae_obj__exhibit_tracking({
|
|
api_cfg: $ae_api,
|
|
exhibit_id: $events_slct.exhibit_id,
|
|
event_badge_id: event_badge_obj_v2.event_badge_id_random,
|
|
external_person_id:
|
|
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key
|
|
})
|
|
.then((result) => {
|
|
console.log(result);
|
|
let exhibit_tracking_id = null;
|
|
let exhibit_tracking_obj = {};
|
|
if (result) {
|
|
exhibit_tracking_id = result.event_exhibit_tracking_id_random;
|
|
exhibit_tracking_obj = result;
|
|
|
|
$events_slct.exhibit_tracking_id = exhibit_tracking_id;
|
|
$events_slct.exhibit_tracking_obj = exhibit_tracking_obj;
|
|
|
|
$events_sess.leads.show_confirm__add_lead[index] = false;
|
|
} else {
|
|
console.log(
|
|
'This badge ID has probably already been added to the lead list for this exhibit.'
|
|
);
|
|
|
|
// Need to look the old record up and set it to not hidden.
|
|
// events_func.handle_update_ae_obj_id_crud({api_cfg: $ae_api, object_type: 'event_exhibit_tracking', object_id: $events_slct.exhibit_tracking_id, field_name: 'hide', new_field_value: false})
|
|
|
|
$events_sess.leads.show_confirm__add_lead[index] = false;
|
|
}
|
|
|
|
if ($events_loc.leads.auto_view) {
|
|
$events_sess.leads.show_form__search = false;
|
|
$events_sess.leads.show_form__scan = false;
|
|
|
|
// $events_slct.exhibit_tracking_id = exhibit_tracking_id;
|
|
// $events_slct.exhibit_tracking_obj = exhibit_tracking_id;
|
|
|
|
$events_loc.leads.tab[$events_slct.exhibit_id] = 'leads';
|
|
|
|
$events_sess.leads.show_form__view_lead =
|
|
$events_slct.exhibit_tracking_id;
|
|
} else {
|
|
// $events_sess.leads.show_form__search = true;
|
|
$events_sess.leads.show_form__scan = true;
|
|
$events_sess.leads.qr_scan_start = true;
|
|
}
|
|
});
|
|
|
|
// $events_sess.leads.show_confirm__add_lead[index] = false;
|
|
}}
|
|
>
|
|
<span class="fas fa-check mx-1"></span>
|
|
Yes
|
|
</button>
|
|
</div>
|
|
</section>
|
|
<!-- .popover__content -->
|
|
</section>
|
|
<!-- .ae_quick_popover -->
|
|
</div>
|
|
{/if}
|
|
|
|
<div class="grow flex flex-row wrap justify-between items-center mx-1">
|
|
<!-- <span class="ae_events__badge_li__item__id">
|
|
{event_badge_obj_v2.event_badge_id_random}
|
|
</span> -->
|
|
<span class="ae_events__badge_li__item__name">
|
|
<span class="fas fa-user mx-0.5"></span>
|
|
{#if $event_exhibit_obj?.priority || $ae_loc.trusted_access}
|
|
{event_badge_obj_v2.full_name}
|
|
{:else}
|
|
<span class="ae_events__badge_li__item__name__hidden">
|
|
{event_badge_obj_v2.full_name
|
|
? event_badge_obj_v2.full_name.substring(0, 1) + '...'
|
|
: 'Hidden'}
|
|
</span>
|
|
{/if}
|
|
</span>
|
|
<span class="text-sm text-right">
|
|
<span class="ae_events__badge_li__item__affiliations">
|
|
{#if $event_exhibit_obj?.priority || $ae_loc.trusted_access}
|
|
{event_badge_obj_v2.affiliations}
|
|
{:else}
|
|
<span class="ae_events__badge_li__item__affiliations__hidden">
|
|
{event_badge_obj_v2.affiliations
|
|
? event_badge_obj_v2.affiliations.substring(0, 3) + '...'
|
|
: 'Hidden'}
|
|
</span>
|
|
{/if}
|
|
</span>
|
|
<span class="ae_events__badge_li__item__email">
|
|
{#if $event_exhibit_obj?.priority || $ae_loc.trusted_access}
|
|
<a
|
|
href="mailto:{event_badge_obj_v2.email}"
|
|
class="font-medium text-blue-600 dark:text-blue-500 hover:underline"
|
|
>
|
|
<span class="fas fa-envelope mx-0.5"></span>
|
|
{event_badge_obj_v2.email}</a
|
|
>
|
|
{:else}
|
|
<span class="ae_events__badge_li__item__email__hidden">
|
|
<span class="fas fa-envelope mx-0.5"></span>
|
|
{event_badge_obj_v2.email
|
|
? event_badge_obj_v2.email.substring(0, 1) + '...@example.com'
|
|
: 'Hidden'}
|
|
</span>
|
|
{/if}
|
|
</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
|
|
<!-- <div class="border border-slate-500/10 p-2 variant-soft-warning">
|
|
<p>{$event_badge_obj_li.length} results found cached</p>
|
|
{#each $event_badge_obj_li as event_badge_obj, index}
|
|
<div class="ae_events__badge_li__item">
|
|
<span class="ae_events__badge_li__item__id">
|
|
{event_badge_obj.event_badge_id_random}
|
|
</span>
|
|
--
|
|
<span class="ae_events__badge_li__item__name">
|
|
{event_badge_obj.full_name}
|
|
</span>
|
|
</div>
|
|
{/each}
|
|
</div> -->
|
|
|
|
<!-- {:else}
|
|
<div class="variant-soft-warning">The search results are not enabled at this time.</div>
|
|
{/if} -->
|
|
{:else}
|
|
<div class="preset-tonal-warning">No results yet</div>
|
|
{/if}
|
|
</div>
|
|
</section>
|
|
<!-- .popover__content -->
|
|
|
|
<footer class="popover__footer flex gap-1 justify-between items-center p-1 border-t">
|
|
<div class="popover__content__actions">
|
|
<button
|
|
type="submit"
|
|
form="form__search_text"
|
|
class="btn preset-tonal-primary border border-primary-500"
|
|
disabled={search_submit_results instanceof Promise && !search_submit_results}
|
|
on:click={() => {
|
|
// trigger = 'save__ds__code';
|
|
// $slct_trigger = 'save__ds__code';
|
|
}}
|
|
>
|
|
<span class="fas fa-search mx-1"></span>
|
|
Search
|
|
</button>
|
|
</div>
|
|
|
|
<div class="popover__status">
|
|
<!-- Something text -->
|
|
{#await search_submit_results}
|
|
<div class="modal-loading">
|
|
<span class="fas fa-spinner fa-spin"></span>
|
|
<span class="loading-text"> Searching... </span>
|
|
</div>
|
|
{:then search_submit_results}
|
|
{#if search_submit_results}
|
|
<div>
|
|
<span class="fas fa-check text-green-500"></span>
|
|
<span class="saved-text"> Complete </span>
|
|
|
|
<span class="results_cache text-sm">
|
|
(
|
|
<span class="search_results text-sm"
|
|
>{$events_slct.badge_obj_li.length} results</span
|
|
>
|
|
{#if $ae_loc.trusted_access}
|
|
&
|
|
<span class="idb_cache text-sm">{$event_badge_obj_li.length} cached</span>
|
|
{/if}
|
|
)
|
|
</span>
|
|
</div>
|
|
{/if}
|
|
{/await}
|
|
|
|
<div class="ae_debug" class:hidden={!$ae_loc?.debug}>
|
|
submit: {$events_sess?.leads.submit_status__search}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="popover__actions">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
$events_sess.leads.show_form__search = false;
|
|
}}
|
|
>
|
|
<span class="fas fa-times mx-1"></span>
|
|
Close
|
|
</button>
|
|
</div>
|
|
</footer>
|
|
<!-- .popover__footer -->
|
|
</section>
|
|
<!-- .ae_quick_popover -->
|
|
</div>
|
|
<!-- .ae_quick_modal_container -->
|
|
{/if}
|
|
|
|
<!-- **END** Search Form -->
|
|
|
|
<!-- **BEGIN** Scan Form -->
|
|
|
|
{#if $events_sess.leads.show_form__scan}
|
|
<div class="ae_quick_modal_container">
|
|
<section
|
|
class="
|
|
ae_quick_popover
|
|
events__leads__scan
|
|
z-50
|
|
flex
|
|
flex-col
|
|
gap-4
|
|
justify-stretch
|
|
max-h-full
|
|
min-w-full
|
|
"
|
|
>
|
|
<header class="popover__header flex gap-1 justify-between items-center p-1 border-b">
|
|
<h2 class="h3">Scan</h2>
|
|
|
|
<div class="popover__actions">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
$events_sess.leads.show_form__scan = false;
|
|
$events_sess.leads.qr_scan_start = false;
|
|
|
|
$events_sess.leads.qr_scan_result = null;
|
|
}}
|
|
>
|
|
<span class="fas fa-times mx-1"></span>
|
|
Close
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<section class="popover__content grow flex flex-col gap-4 items-center ae_modal_scrollfix">
|
|
{#if !$ae_loc.qr_scanner_version || $ae_loc.qr_scanner_version == 'one'}
|
|
<Element_qr_scanner
|
|
start_qr_scanner={$events_sess.leads.qr_scan_start}
|
|
show_qr_scan_result={true}
|
|
show_qr_manual_badge_id_entry_option={true}
|
|
on:qr_scan_result={handle_qr_scan_result}
|
|
on:qr_camera={handle_qr_camera}
|
|
/>
|
|
{:else if $ae_loc.qr_scanner_version == 'two'}
|
|
<!-- v2 dev -->
|
|
<!-- <Element_qr_scanner_v2
|
|
start_qr_scanner={$events_sess.leads.qr_scan_start}
|
|
show_qr_scan_result={true}
|
|
show_qr_manual_badge_id_entry_option={true}
|
|
on:qr_scan_result={handle_qr_scan_result}
|
|
on:qr_camera={handle_qr_camera}
|
|
/> -->
|
|
{:else}
|
|
<p>Please close this and select a QR Scanner version</p>
|
|
{/if}
|
|
|
|
<div class="qr_quick_results preset-tonal-secondary font-bold p-4">
|
|
{$events_sess.leads.qr_scan_result ?? 'No results yet'}
|
|
</div>
|
|
|
|
<!-- This block needs to be moved or something. It takes up too much space! -->
|
|
<!-- This uses the events_slct with badge_id and badge_obj. -->
|
|
{#if $events_sess.leads.show_confirm__add_lead[$events_slct.badge_id] && $event_badge_obj}
|
|
<div class="ae_quick_modal_container">
|
|
<section
|
|
class="
|
|
ae_quick_popover_small
|
|
events__leads__scan
|
|
z-50
|
|
flex
|
|
flex-col
|
|
gap-4
|
|
justify-stretch
|
|
|
|
"
|
|
>
|
|
<header class="popover__header flex gap-1 justify-between items-center p-1 border-b">
|
|
<h2 class="h3">Add Scanned?</h2>
|
|
|
|
<div class="popover__actions">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
$events_sess.leads.show_confirm__add_lead[$events_slct.badge_id] = false;
|
|
|
|
$events_slct.badge_id = null;
|
|
$events_slct.badge_obj = null;
|
|
|
|
$events_sess.leads.qr_scan_result = null;
|
|
}}
|
|
>
|
|
<span class="fas fa-times mx-1"></span>
|
|
Close
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<section
|
|
class="popover__content grow flex flex-col gap-4 items-center ae_modal_scrollfix"
|
|
>
|
|
<p>
|
|
Are you sure you want to add <strong>{$event_badge_obj.full_name}</strong> to the leads
|
|
list?
|
|
</p>
|
|
<p>Badge ID: <strong>{$event_badge_obj.event_badge_id_random}</strong></p>
|
|
<div class="flex flex-row gap-16 justify-center items-center">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
console.log(
|
|
`Do not add ${$event_badge_obj.full_name} ${$event_badge_obj.email} to the leads list`
|
|
);
|
|
|
|
$events_sess.leads.show_confirm__add_lead[$events_slct.badge_id] = false;
|
|
|
|
$events_slct.badge_id = null;
|
|
$events_slct.badge_obj = null;
|
|
|
|
// $events_slct = $events_slct;
|
|
// $events_sess = $events_sess;
|
|
|
|
$events_sess.leads.qr_scan_result = null;
|
|
}}
|
|
>
|
|
<span class="fas fa-times mx-1"></span>
|
|
No
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
disabled={!$ae_loc.trusted_access}
|
|
on:click={() => {
|
|
console.log(
|
|
`Add ${event_badge_obj.full_name} ${event_badge_obj.email} to the leads list`
|
|
);
|
|
|
|
// TEMPORARY: For testing and development
|
|
// if (!$ae_loc.trusted_access) {
|
|
// console.log('You do not have permission to add this person to the leads list.');
|
|
// return false;
|
|
// }
|
|
// TEMPORARY: For testing and development
|
|
|
|
events_func
|
|
.handle_create_ae_obj__exhibit_tracking({
|
|
api_cfg: $ae_api,
|
|
exhibit_id: $events_slct.exhibit_id,
|
|
event_badge_id: $events_slct.badge_id,
|
|
external_person_id:
|
|
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key
|
|
})
|
|
.then((result) => {
|
|
console.log(result);
|
|
let exhibit_tracking_id = null;
|
|
let exhibit_tracking_obj = {};
|
|
if (result) {
|
|
exhibit_tracking_id = result.event_exhibit_tracking_id_random;
|
|
exhibit_tracking_obj = result;
|
|
|
|
$events_slct.exhibit_tracking_id = exhibit_tracking_id;
|
|
$events_slct.exhibit_tracking_obj = exhibit_tracking_obj;
|
|
} else {
|
|
console.log(
|
|
'This badge ID has probably already been added to the lead list for this exhibit.'
|
|
);
|
|
|
|
// Need to look the old record up and set it to not hidden.
|
|
}
|
|
$events_sess.leads.show_confirm__add_lead[$events_slct.badge_id] = false;
|
|
|
|
// $events_sess.leads.show_confirm__add_lead[$events_slct.badge_id] = false;
|
|
$events_slct.badge_id = null;
|
|
$events_slct.badge_obj = null;
|
|
|
|
if ($events_loc.leads.auto_view) {
|
|
$events_sess.leads.show_form__search = false;
|
|
$events_sess.leads.show_form__scan = false;
|
|
|
|
$events_loc.leads.tab[$events_slct.exhibit_id] = 'leads';
|
|
|
|
$events_sess.leads.show_form__view_lead =
|
|
$events_slct.exhibit_tracking_id;
|
|
} else {
|
|
// $events_sess.leads.show_form__search = true;
|
|
$events_sess.leads.show_form__scan = true;
|
|
$events_sess.leads.qr_scan_start = true;
|
|
|
|
$events_sess.leads.qr_scan_result = null;
|
|
}
|
|
});
|
|
|
|
// $events_sess.leads.show_confirm__add_lead[$events_slct.badge_id] = false;
|
|
}}
|
|
>
|
|
<span class="fas fa-check mx-1"></span>
|
|
Yes
|
|
</button>
|
|
</div>
|
|
</section>
|
|
<!-- .popover__content -->
|
|
</section>
|
|
<!-- .ae_quick_popover -->
|
|
</div>
|
|
{/if}
|
|
</section>
|
|
<!-- .popover__content -->
|
|
|
|
<footer class="popover__footer flex gap-1 justify-between items-center p-1 border-t">
|
|
<!-- <div class="popover__content__actions">
|
|
<button
|
|
type="button"
|
|
class="btn variant-soft-primary"
|
|
on:click={() => {
|
|
$events_sess.leads.qr_scan_start = !$events_sess.leads.qr_scan_start;
|
|
}}
|
|
>
|
|
<span class="fas fa-search mx-1"></span>
|
|
{#if $events_sess.leads.qr_scan_start}
|
|
Stop Scanning
|
|
{:else}
|
|
Scanning
|
|
{/if}
|
|
</button>
|
|
</div> -->
|
|
|
|
<div class="popover__status">
|
|
<!-- Something text -->
|
|
<!-- {#await scan_submit_results}
|
|
<div class="modal-loading">
|
|
<span class="fas fa-spinner fa-spin"></span>
|
|
<span class="loading-text">
|
|
Scanning...
|
|
</span>
|
|
</div>
|
|
{:then scan_submit_results}
|
|
{#if scan_submit_results}
|
|
<div>
|
|
<span class="fas fa-check text-green-500"></span>
|
|
<span class="saved-text
|
|
">
|
|
Complete
|
|
</span>
|
|
</div>
|
|
{/if}
|
|
{/await} -->
|
|
|
|
<div class="ae_debug" class:hidden={!$ae_loc?.debug}>
|
|
submit: {$events_sess?.leads.submit_status__scan}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="popover__actions">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-primary"
|
|
on:click={() => {
|
|
$events_sess.leads.show_form__scan = false;
|
|
$events_sess.leads.qr_scan_start = false;
|
|
|
|
$events_sess.leads.qr_scan_result = null;
|
|
}}
|
|
>
|
|
<span class="fas fa-times mx-1"></span>
|
|
Close
|
|
</button>
|
|
</div>
|
|
</footer>
|
|
<!-- .popover__footer -->
|
|
</section>
|
|
<!-- .ae_quick_popover -->
|
|
</div>
|
|
<!-- .ae_quick_modal_container -->
|
|
{/if}
|
|
|
|
<style lang="postcss">
|
|
</style>
|