It has been a long two or three weeks...

This commit is contained in:
Scott Idem
2024-03-15 17:48:14 -04:00
parent 68b0efb6c9
commit 0400aa429b
13 changed files with 725 additions and 222 deletions

View File

@@ -13,7 +13,7 @@ onMount(() => {
// console.log('ae_ slct:', $slct);
console.log(window.location.href);
// console.log(window.location.href);
let href_url = window.location.href;
// $ae_loc.href_url = href_url;
// console.log(`$ae_loc.href_url = `, $ae_loc.href_url);

View File

@@ -4,13 +4,14 @@ console.log(`ae_events_leads +page data:`, data);
// console.log(`ae_events_leads Data Params:`, data.url.searchParams.get('event_id'));
import { onMount } from 'svelte';
import { goto, invalidate, pushState, replaceState } from '$app/navigation';
import { ae_util } from '$lib/ae_utils';
import { api } from '$lib/api';
import { liveQuery } from "dexie";
import { db_events } from "$lib/db_events";
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/ae_stores';
import { events_loc, events_slct, events_trigger } from '$lib/ae_events_stores';
import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_events_stores';
import Element_data_store from '$lib/element_data_store.svelte';
@@ -18,26 +19,30 @@ import Element_data_store from '$lib/element_data_store.svelte';
let event_exhibit_obj_li = liveQuery(
// () => db_events.exhibits.toArray()
() => db_events.exhibits
// .where('passcode')
.where('license_max')
// .aboveOrEqual(0)
// .equals('99999')
.orderBy('name')
.above(0)
.sortBy('name') // Use sortBy() instead of orderBy(). toArray() is also not needed???
// .orderBy('name')
// .offset(10).limit(5)
.toArray()
// .toArray()
);
// if (data.url.searchParams.get('event_id')) {
// $events_slct.event_id = data.url.searchParams.get('event_id');
// } else if (data.ae_loc.site_cfg_json.slct__event_id) {
// $events_slct.event_id = data.ae_loc.site_cfg_json.slct__event_id;
// } else if ($events_loc.default__event_id) {
// $events_slct.event_id = $events_loc.default__event_id;
// } else if ($events_slct.event_id) {
// console.log(`Event ID already set:`, $events_slct.event_id);
// } else {
// console.log(`No Event ID set.`);
// }
// This should probably be moved
if (data.url.searchParams.get('event_id')) {
$events_slct.event_id = data.url.searchParams.get('event_id');
} else if (data.ae_loc.site_cfg_json.slct__event_id) {
$events_slct.event_id = data.ae_loc.site_cfg_json.slct__event_id;
} else if ($events_loc.default__event_id) {
$events_slct.event_id = $events_loc.default__event_id;
} else if ($events_slct.event_id) {
console.log(`Event ID already set:`, $events_slct.event_id);
} else {
console.log(`No Event ID set.`);
}
export let event_exhibit_staff_passcode: string = '';
// export let event_exhibit_staff_passcode: string = '';
let disable_open_lead_retrieval_btn: boolean = true;
let disable_reset_passcode_btn: boolean = true;
let reset_passcode: string = '';
@@ -61,7 +66,7 @@ onMount(() => {
});
$: if (event_exhibit_staff_passcode.length >= 5) {
$: if ($events_sess.leads.entered_passcode && $events_sess.leads.entered_passcode >= 5) {
// disable_open_lead_retrieval_btn = false;
handle_check_event_exhibit_staff_passcode();
} else {
@@ -70,12 +75,27 @@ $: if (event_exhibit_staff_passcode.length >= 5) {
}
function handle_check_event_exhibit_staff_passcode() {
// console.log(`*** handle_check_event_exhibit_staff_passcode() *** $slct_event_exhibit_obj=`, $events_slct.exhibit_obj);
console.log(`*** handle_check_event_exhibit_staff_passcode() *** $events_slct.exhibit_obj=`, $events_slct.exhibit_obj);
if ($events_slct.exhibit_obj && event_exhibit_staff_passcode && event_exhibit_staff_passcode.length >= 4) {
if ($events_slct.exhibit_obj.staff_passcode == event_exhibit_staff_passcode) {
$events_sess.leads.open_href = '';
if ($events_slct.exhibit_obj && $events_sess.leads.entered_passcode && $events_sess.leads.entered_passcode.length >= 4) {
if ($events_slct.exhibit_obj.staff_passcode == $events_sess.leads.entered_passcode) {
console.log('Passcode matched');
disable_open_lead_retrieval_btn = false;
$events_sess.leads.entered_passcode = null;
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] = {
key: null,
updated_on: new Date().toISOString()
};
// console.log($events_slct);
$events_sess.leads.open_href = `/events_leads/exhibit/${$events_slct.exhibit_obj.id_random}?event_id=${$events_slct.event_id}`;
if ($events_loc.leads.auto_view) {
goto($events_sess.leads.open_href, {invalidateAll: true});
}
} else {
// console.log('Passcode does not match');
disable_open_lead_retrieval_btn = true;
@@ -88,7 +108,7 @@ function handle_check_event_exhibit_staff_passcode() {
}
if ($events_loc.leads.auto_view) {
open_exhibit_tracking($events_slct.exhibit_obj.event_exhibit_id_random, event_exhibit_staff_passcode)
// open_exhibit_tracking($events_slct.exhibit_obj.id_random)
} else {
// console.log(document.getElementById('open_lead_retrieval_btn'));
// document.getElementById('open_lead_retrieval_btn').focus();
@@ -96,22 +116,23 @@ function handle_check_event_exhibit_staff_passcode() {
}
function open_exhibit_tracking(event_exhibit_id_random, event_exhibit_staff_passcode) {
console.log(`open_exhibit_tracking() event_exhibit_id_random=${event_exhibit_id_random} event_exhibit_staff_passcode=${event_exhibit_staff_passcode}`);
// function open_exhibit_tracking(event_exhibit_id_random) {
// console.log(`open_exhibit_tracking() event_exhibit_id_random=${event_exhibit_id_random}`);
// let url = `/events_leads/exhibit/${event_exhibit_id_random}`;
// window.open(url, '_blank');
// window.focus();
// if (!event_exhibit_id_random) {
// console.log('No event exhibit ID provided.');
// return null;
// }
let url = `/events_leads/exhibit/${event_exhibit_id_random}`;
window.open(url);
// window.open(url, '_blank');
window.focus();
}
// if ($events_loc.leads.auto_view) {
// goto($events_sess.leads.open_href, {invalidateAll: true});
// } else {
// }
// }
</script>
<section class="ae_events_leads md:container h-full mx-auto">
<section class="ae_events_leads h-full w-full flex flex-col wrap align-begin justify-start space-y-4">
<h1 class="h2">Events - Leads</h1>
@@ -121,14 +142,14 @@ function open_exhibit_tracking(event_exhibit_id_random, event_exhibit_staff_pass
for_type="event"
for_id={$events_slct.event_id}
display="block"
class_li="variant-ghost-surface p-2"
class_li="variant-ghost-secondary p-2"
/>
<a href="/{$events_slct.event_id}">Event ID {$events_slct.event_id}</a>
<!-- <a href="/{$events_slct.event_id}">Event ID {$events_slct.event_id}</a> -->
{#if $event_exhibit_obj_li}
<h2>Exhibits</h2>
<h2 class="h3">Exhibits</h2>
<!-- <ul>
{#each $event_exhibit_obj_li as exhibit_obj}
<li>
@@ -139,51 +160,64 @@ function open_exhibit_tracking(event_exhibit_id_random, event_exhibit_staff_pass
<div class="event_exhibit_tracking_select_exhibit space-y-6">
<form on:submit|preventDefault={() => open_exhibit_tracking($events_slct.exhibit_obj, event_exhibit_staff_passcode)} class="form-floating">
<form
on:submit|preventDefault={() => {
$events_sess.leads.open_href = `/events_leads/exhibit/${$events_slct.exhibit_obj.id_random}?event_id=${$events_slct.event_id}`;
goto($events_sess.leads.open_href, {invalidateAll: true});
}}
class="form-floating">
<h2>Exhibitor Lead Retrieval</h2>
<div>Select your exhibit booth from the list and enter passcode you were given.</div>
<div class="form-floating mb-1 col-md-12 col-lg-12">
<label for="exhibit_list" class="label">
Exhibit List:<br>
<select bind:value={$events_slct.exhibit_obj} id="exhibit_list" class="select max-w-md">
<option value="">-- Nothing Selected --</option>
<option value="" selected>-- Nothing Selected --</option>
{#each $event_exhibit_obj_li as event_exhibit_obj, index}
<!-- <option value="{event_exhibit_obj.event_exhibit_id_random}">{event_exhibit_obj.name} (Booth # {event_exhibit_obj.code})</option> -->
<option value="{event_exhibit_obj}">{event_exhibit_obj.name} (Booth #{event_exhibit_obj.code})</option>
{/each}
<option value={event_exhibit_obj}>{event_exhibit_obj.name} (Booth #{event_exhibit_obj.code})</option>
{/each}
</select>
<label for="exhibit_list" class="label">
Exhibit List:
</label>
</div>
<div class="container_group">
<!-- <input bind:value={event_exhibit_staff_passcode} type="text" id="exhibit_passcode" placeholder="Exhibit passcode" /> -->
<!-- <input bind:value={$events_sess.leads.entered_passcode} type="text" id="exhibit_passcode" placeholder="Exhibit passcode" /> -->
<input
bind:value={event_exhibit_staff_passcode}
bind:value={$events_sess.leads.entered_passcode}
class="input max-w-40"
placeholder="Exhibit passcode"
/>
<!-- <button on:click={() => open_exhibit_tracking(exhibit_obj.event_exhibit_id_random, event_exhibit_staff_passcode)} id="open_lead_retrieval_btn" disabled={disable_open_lead_retrieval_btn} autofocus>Open Exhibitor Lead Retrieval</button> -->
<!-- <button on:click={() => open_exhibit_tracking(exhibit_obj.event_exhibit_id_random, $events_sess.leads.entered_passcode)} id="open_lead_retrieval_btn" disabled={disable_open_lead_retrieval_btn} autofocus>Open Exhibitor Lead Retrieval</button> -->
<button
type="submit"
disabled={disable_open_lead_retrieval_btn}
class="btn variant-filled-primary open_lead_retrieval_btn"
>
<span class="fas fa-arrow-right"></span> Open Exhibitor Lead Retrieval
<span class="fas fa-arrow-right mx-1"></span> Open Exhibitor Lead Retrieval
</button>
<!-- <a
on:click|preventDefault={() => goto($events_sess.leads.open_href, {invalidateAll: true})}
href={$events_sess.leads.open_href}
>
Open Exhibitor Lead Retrieval
</a> -->
</div>
</form>
{#if ($ae_loc.trusted_access)}
{#if ($ae_loc.administrator_access && !$events_loc.show_details)}
<div class="">
<!-- <input bind:value={reset_passcode} type="text" id="reset_exhibit_passcode" placeholder="Reset exhibit passcode" /> -->
<input bind:value={reset_passcode} placeholder="Reset passcode" title="Reset exhibit passcode" class="input max-w-40" />
<!-- <button on:click={() => open_exhibit_tracking(exhibit_obj.event_exhibit_id_random, event_exhibit_staff_passcode)} id="open_lead_retrieval_btn" disabled={disable_open_lead_retrieval_btn} autofocus>Open Exhibitor Lead Retrieval</button> -->
<!-- <button on:click={() => open_exhibit_tracking(exhibit_obj.event_exhibit_id_random, $events_sess.leads.entered_passcode)} id="open_lead_retrieval_btn" disabled={disable_open_lead_retrieval_btn} autofocus>Open Exhibitor Lead Retrieval</button> -->
<!-- <button type="button" id="reset_passcode_btn" disabled={disable_reset_passcode_btn} autofocus on:click={() => show_exhibit_tracking_add_modal=true}>Reset Passcode</button> -->
<button
@@ -194,7 +228,7 @@ function open_exhibit_tracking(event_exhibit_id_random, event_exhibit_staff_pass
}}
class="btn variant-filled-secondary reset_passcode_btn"
>
<span class="fas fa-undo"></span> Reset Passcode
<span class="fas fa-undo mx-1"></span> Reset Passcode
</button>
</div>
{/if}
@@ -203,7 +237,17 @@ function open_exhibit_tracking(event_exhibit_id_random, event_exhibit_staff_pass
</div>
<!-- <button
type="button"
on:click={() => {
console.log(`Goto Button Clicked`);
// goto($events_sess.leads.open_href, {invalidateAll: true});
goto('?key=value');
}}
class="btn variant-filled-secondary"
>
Test Goto Button
</button> -->
{/if}

View File

@@ -29,10 +29,10 @@ export async function load({ params, parent, url }) { // route
// Do not wait on these:
let event_id = url.searchParams.get('event_id');
let load_event_obj = events_func.handle_load_ae_obj_id__event({api_cfg: data.ae_api, event_id: event_id, try_cache: false});
console.log(`load_event_obj = `, load_event_obj);
// console.log(`load_event_obj = `, load_event_obj);
let load_event_exhibit_obj_li = events_func.handle_load_ae_obj_li__exhibit({api_cfg: data.ae_api, event_id: event_id, try_cache: false});
console.log(`load_event_exhibit_obj_li = `, load_event_exhibit_obj_li);
// console.log(`load_event_exhibit_obj_li = `, load_event_exhibit_obj_li);
// let exhibit_id = data.params.slug;
// let load_event_exhibit_obj = events_func.handle_load_ae_obj_id__exhibit({api_cfg: data.ae_api, exhibit_id: exhibit_id, try_cache: false});

View File

@@ -14,18 +14,13 @@ import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_ev
import { events_func } from '$lib/ae_events_functions';
// This works and uses local storage:
// store_current_tab must be prefixed with $ to be reactive.
import { clipboard, FileDropzone, getModalStore, localStorageStore, ProgressRadial, RadioGroup, RadioItem, TabGroup, Tab, TabAnchor } from '@skeletonlabs/skeleton';
import type { Writable } from 'svelte/store';
// import type { Writable } from 'svelte/store';
import Element_data_store from '$lib/element_data_store.svelte';
import Element_qr_scanner from '$lib/element_qr_scanner.svelte';
const store_current_tab: Writable<string> = localStorageStore('ae_events_leads_current_tab', 'start');
console.log(`ae_events_leads exhibit +page.svelte [slug] store_current_tab:`, $store_current_tab);
let param_slug_event_exhibit_id = data.params.slug;
let event_exhibit_obj = liveQuery(
@@ -48,13 +43,30 @@ $events_trigger = 'load__event_exhibit_obj';
let license_submit_results: Promise<any>|key_val;
if ($events_loc.leads.auth_exhibit_li && $events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id]) {
console.log('Already logged in.');
} else {
console.log('Not logged in.');
$store_current_tab = 'start';
if (!$events_loc.leads.tab) {
$events_loc.leads.tab = {};
$events_loc.leads.tab[$events_slct.exhibit_id] = 'start';
}
if (!$events_loc.leads.auth_exhibit_kv) {
$events_loc.leads.auth_exhibit_kv = {};
}
if ($events_loc.leads.auth_exhibit_kv && $events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id]) {
console.log('Logged in using shared exhibit staff passcode.');
if ($events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key) {
console.log(`Using the license key: ${$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}`);
} else {
console.log('License key (email) not used.');
$events_loc.leads.tab[$events_slct.exhibit_id] = 'start';
}
} else {
console.log('Not logged in using shared exhibit staff passcode.');
$events_loc.leads.tab[$events_slct.exhibit_id] = 'start';
}
onMount(() => {
console.log('Events Leads Exhibit [slug]: +page.svelte');
@@ -69,7 +81,7 @@ onMount(() => {
});
// console.log(`$ae_loc = `, $ae_loc);
$: if ($slct.event_exhibit_obj && $events_sess.leads.entered_passcode) {
$: if ($events_slct.exhibit_obj && $events_sess.leads.entered_passcode) {
console.log('Check the passcode?');
if ($events_sess.leads.entered_passcode.length > 4) {
console.log('Check the passcode');
@@ -83,16 +95,24 @@ $: if ($slct.event_exhibit_obj && $events_sess.leads.entered_passcode) {
function handle_check_event_exhibit_staff_passcode() {
// console.log(`*** handle_check_event_exhibit_staff_passcode() *** $slct_event_exhibit_obj=`, $events_slct.exhibit_obj);
if (!$events_loc.leads.auth_exhibit_li) {
$events_loc.leads.auth_exhibit_li = {};
// if (!$events_loc.leads.auth_exhibit_li) {
// $events_loc.leads.auth_exhibit_li = {};
// }
if (!$events_loc.leads.auth_exhibit_kv) {
$events_loc.leads.auth_exhibit_kv = {};
}
if ($slct.event_exhibit_obj && $events_sess.leads.entered_passcode && $events_sess.leads.entered_passcode.length >= 4) {
if ($events_slct.exhibit_obj && $events_sess.leads.entered_passcode && $events_sess.leads.entered_passcode.length >= 4) {
if ($events_slct.exhibit_obj.staff_passcode == $events_sess.leads.entered_passcode) {
console.log('Passcode matched');
// disable_open_lead_retrieval_btn = false;
$events_sess.leads.entered_passcode = null;
$events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id] = new Date().toISOString();
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] = {
key: null,
updated_on: new Date().toISOString()
};
} else {
// console.log('Passcode does not match');
// disable_open_lead_retrieval_btn = true;
@@ -402,6 +422,107 @@ function send_init_confirm_email({to_email}) {
});
}
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}`;
// 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???');
// }
} 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_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) {
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';
}
}
// Updated 2022-04-22
export let get_event_exhibit_tracking_export = async function get_event_exhibit_tracking_export({event_exhibit_id, file_type='CSV', return_file=true, filename=null, auto_download=false, params={}, log_lvl=0}) {
console.log('*** stores_event_api.js: get_event_exhibit_tracking_export() ***');
const endpoint = `/event/exhibit/${event_exhibit_id}/tracking/export`;
if (file_type == 'CSV' || file_type == 'Excel') {
params['file_type'] = file_type;
}
params['return_file'] = true;
let event_exhibit_tracking_export_file_get_promise = await api.get_object({api_cfg: ae_api, endpoint: endpoint, params: params, return_blob: true, filename: filename, auto_download: auto_download, log_lvl: log_lvl});
// console.log(event_exhibit_tracking_export_file_get_promise);
return event_exhibit_tracking_export_file_get_promise;
}
</script>
@@ -421,7 +542,7 @@ function send_init_confirm_email({to_email}) {
<!-- <div
class="events__leads__exhibit_obj_main_about"
class:hidden={$store_current_tab !== 'start'}
class:hidden={$events_loc.leads.tab[$events_slct.exhibit_id] !== 'start'}
>
<Element_data_store
ds_code="events__leads__exhibit_obj_main_about"
@@ -434,16 +555,12 @@ function send_init_confirm_email({to_email}) {
</div> -->
{#if $events_slct.exhibit_id && $event_exhibit_obj}
<section class="ae_h_scrollfix"></section>
<!-- <section class="ae_h_scrollfix"> -->
<!-- <hr>
<p class="variant-soft-warning">Make logging in with shared exhibit passcode work first!</p>
<p>Mark as logged in by using: events_loc.leads.auth_exhibit_li. This is a key (exhibit ID) and value (started datetime) pair. They can be logged into more than one exhibit at a time. Warn about log out when using the "Use License" button. Avoid "accidental" clicks.</p>
<p>Check that the started datetime is still within X period and check against the tracked session timestamps. The table or object field is event_exhibit.license_sess_li.</p>
<p>Config option to show additional settings or information? Hide the Email and Copy buttons by default. Hide license input fields by default.</p>
<p class="variant-soft-warning">Tabs: Main (list of licenses to use, show started timestamps?, summary of counts per license), Manage (export, settings), Add/Scan, Leads</p>
<p>The tabs and everything is not visible until they enter the shared exhibit passcode. Or maybe just gray out tabs and hide any details under the active one.</p>
<p>Header, footer, etc can be shown/hidden</p>
<p>The header image can use md:hidden to hide when too small?</p>
<p class="variant-soft-warning">Only show exhibitors in the list that have licenses available.</p>
@@ -460,7 +577,7 @@ function send_init_confirm_email({to_email}) {
class="bg-surface-100-800-token w-full"
>
<Tab
bind:group={$store_current_tab}
bind:group={$events_loc.leads.tab[$events_slct.exhibit_id]}
name="tab_start"
value={'start'}>
<svelte:fragment slot="lead">
@@ -472,11 +589,11 @@ function send_init_confirm_email({to_email}) {
<!-- Manage - For changing the settings, exporting, and other. -->
<Tab
bind:group={$store_current_tab}
bind:group={$events_loc.leads.tab[$events_slct.exhibit_id]}
name="tab_manage"
value={'manage'}
disabled={!$events_slct.exhibit_obj || !$events_loc?.leads.auth_exhibit_li || !$events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id]}
regionTab={!$events_slct.exhibit_obj || !$events_loc?.leads.auth_exhibit_li || !$events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id] ? 'text-slate-400' : ''}
disabled={!$events_slct.exhibit_obj || !$events_loc?.leads.auth_exhibit_kv || !$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id]}
regionTab={!$events_slct.exhibit_obj || !$events_loc?.leads.auth_exhibit_kv || !$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] ? 'text-slate-400' : ''}
>
<svelte:fragment slot="lead">
<span class="fas fa-cogs"></span>
@@ -485,11 +602,11 @@ function send_init_confirm_email({to_email}) {
</Tab>
<Tab
bind:group={$store_current_tab}
bind:group={$events_loc.leads.tab[$events_slct.exhibit_id]}
name="tab_add_scan"
value={'add_scan'}
disabled={!$events_slct.exhibit_obj || !$events_loc?.leads.auth_exhibit_li || !$events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id]}
regionTab={!$events_slct.exhibit_obj || !$events_loc?.leads.auth_exhibit_li || !$events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id] ? 'text-slate-400' : ''}
disabled={!$events_slct.exhibit_obj || !$events_loc?.leads.auth_exhibit_kv || !$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id]}
regionTab={!$events_slct.exhibit_obj || !$events_loc?.leads.auth_exhibit_kv || !$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] ? 'text-slate-400' : ''}
>
<svelte:fragment slot="lead">
<span class="fas fa-qrcode"></span>
@@ -499,29 +616,44 @@ function send_init_confirm_email({to_email}) {
</TabGroup>
{#if $store_current_tab === 'start'}
<!-- BEGIN Tab: Main (start) -->
{#if $events_loc.leads.tab[$events_slct.exhibit_id] === 'start'}
<div class="text-center m-4">
<p>
<section class="tab__start flex flex-col wrap justify-center items-center space-y-4 ae_h_scrollfix">
<div class="flex flex-col wrap justify-center items-center">
<h2 class="h3">
<!-- {$events_slct.exhibit_obj.name} -->
<strong>{$event_exhibit_obj?.name ?? 'Welcome to Leads for Exhibits!'}</strong>
<strong>{$event_exhibit_obj?.code ?? ''}</strong>
</p>
</h2>
<h3 class="h4">
{#if $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
<span class="fas fa-check text-green-500"></span>
{$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
<button
type="button"
class="btn btn-sm variant-soft-warning"
on:click={() => {
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key = null;
}}
>
<span class="fas fa-times mx-1"></span>
Clear License
</button>
{:else}
<span class="fas fa-times text-red-500"></span>
No license key selected.
{/if}
</h3>
</div>
{#if $events_loc?.leads.auth_exhibit_li && $events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id]}
<!-- <button
type="button"
on:click={() => {
console.log('Log Out');
$events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id] = null;
}}
title="Log out"
class="btn variant-soft-primary w-40"
>
<span class="fas fa-sign-out-alt mx-1"></span>
Log Out
</button> -->
{#if $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
<p>
You are logged in using the shared exhibit staff passcode and are using the license key for {$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}. Any leads you collect will be associated with this license key (email address).
</p>
{:else if $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id]}
<p>To use the lead retrieval service, please select a license from the list below.</p>
{:else}
<p>To access this exhibit you must enter the shared staff passcode that you were given. You will then be able to select a license and use the lead retrieval service from your device.</p>
@@ -538,13 +670,13 @@ function send_init_confirm_email({to_email}) {
{/if}
{#if $events_loc?.leads.auth_exhibit_li && $events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id]}
{#if $events_loc?.leads.auth_exhibit_kv && $events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id]}
<!-- Loop through the key value pairs. Each license key has a passcode, updated_on, etc -->
{#if $event_exhibit_obj?.license_max }
<h2 class="h3">License List (max {$event_exhibit_obj?.license_max})</h2>
<section class="ae_license_list">
{#if $event_exhibit_obj?.license_li_json && $event_exhibit_obj?.license_li_json.length < $event_exhibit_obj?.license_max}
<button
@@ -587,23 +719,26 @@ function send_init_confirm_email({to_email}) {
</button> -->
{/if} <!-- $event_exhibit_obj?.license_li_json.length < $event_exhibit_obj?.license_max -->
<div>Use one of the options below to log in using one of the licenses.</div>
<div>Use the "Sign In" or "Email" option buttons below to log in using one of the available licenses. If you select a license that is already in use on another device, it will be logged out. The "Sign In" option will use the license selected with your browser. The "Email" option will send an email with a link to log in.</div>
<section class="ae_license_list ae_h_scrollfix">
<form
on:submit|preventDefault={() => {
console.log('Save License List');
handle_submit_form(event);
}}
id="form__license_table"
class="flex flex-row items-center space-x-2 border border-ae-3 p-0 m-0"
class="p-0 m-0"
>
<input type="hidden" name="license_max" value={$event_exhibit_obj?.license_max} />
<!-- <div class="ae_h_scrollfix"> -->
<table class="table table-compact table-hover">
<thead>
<tr>
<th>Use License</th>
<th>License</th>
<th>Info</th>
<!-- <th>Email</th> -->
<!-- <th>Full Name</th> -->
@@ -648,7 +783,7 @@ function send_init_confirm_email({to_email}) {
<button
type="button"
on:click={() => {
console.log('Use License');
console.log(`Use license: ${license.email}`);
// Use the license key to sign in
// $events_slct.exhibit_obj.url = `${data.url.origin}/events_leads/exhibit/${$events_slct.exhibit_id}?license_key=${index}&event_id=${$events_slct.event_id}`;
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] = {
@@ -669,7 +804,9 @@ function send_init_confirm_email({to_email}) {
// Send an email with the login link
send_init_confirm_email({ to_email: license.email });
}}
disabled={!$ae_loc.trusted_access}
class="btn btn-sm text-sm variant-soft-secondary"
title={`TEMPORARILY DISABLED: Send an email with the license login link to ${license.email}`}
>
<span class="fas fa-envelope mx-1"></span>
Email
@@ -694,57 +831,25 @@ function send_init_confirm_email({to_email}) {
</td>
<td>
<div class="flex flex-row wrap gap-1 justify-between items-center">
<!-- All elements should be centered horizontally and vertically using flex. -->
<div class="
flex flex-row wrap gap-1
items-center justify-center
content-center
"
>
<!-- <td> -->
<div class="full_name_email">
{#if $events_loc.leads.edit_license_li}
<input
type="text"
name={`license_${index}_full_name`}
value={license.full_name ?? ''}
placeholder="Full Name"
required
class="input text-sm max-w-40 font-mono"
minlength="2"
/>
{:else}
<div class="flex flex-col gap-1 wrap full_name_email grow">
<span class="text-sm">{license.full_name}</span>
{/if}
<!-- </td> -->
<!-- <input type="email" value={key ?? ''} name="license_key" placeholder="Valid email" required class="input text-sm max-w-xs" /> -->
{#if $events_loc.leads.edit_license_li}
<input
type="text"
name={`license_${index}_email`}
required
value={license.email ?? ''}
placeholder="Valid email"
minlength="5"
class="input text-sm max-w-xs font-mono"
/>
{:else}
<span class="text-sm">{license.email}</span>
{/if}
<!-- </td> -->
</div>
<!-- <td> -->
{#if $events_loc.leads.edit_license_li}
<input
type="text"
name={`license_${index}_passcode`}
value={license.passcode ?? '987654'}
placeholder="Passcode"
disabled={index >= $event_exhibit_obj?.license_max}
required
class="input text-sm max-w-20 font-mono"
minlength="5"
/>
{:else}
<span class="font-bold text-sm">{license.passcode}</span>
{/if}
<span
class="font-bold text-sm"
class:hidden={!$events_loc.show_details}
>
{license.passcode}
</span>
</div>
</td>
@@ -781,6 +886,18 @@ function send_init_confirm_email({to_email}) {
type="button"
on:click={() => {
console.log('Remove License');
if (confirm('Are you sure you want to remove this license?')) {
// This still needs to be saved to the database.
// Signal that this license should be removed from the list.
// $events_sess.leads.tmp_license.index = -1;
$events_sess.leads.tmp_license.index = index;
$events_sess.leads.tmp_license.email = null;
$events_sess.leads.tmp_license.full_name = null;
handle_submit_form_license_update(event);
}
// let tmp_obj = $event_exhibit_obj;
// tmp_obj?.license_li_json.splice(index, 1);
// console.log('Remove License:', tmp_obj);
@@ -789,10 +906,10 @@ function send_init_confirm_email({to_email}) {
// This still needs to be saved to the database.
// $events_sess.leads.tmp_license.index = -1;
// Signal that this license should be removed from the list.
$events_sess.leads.tmp_license.index = index;
$events_sess.leads.tmp_license.email = null;
$events_sess.leads.tmp_license.full_name = null;
handle_submit_form_license_update(event);
// $events_sess.leads.tmp_license.index = index;
// $events_sess.leads.tmp_license.email = null;
// $events_sess.leads.tmp_license.full_name = null;
// handle_submit_form_license_update(event);
}}
class="btn btn-sm variant-soft-error">
<span class="fas fa-trash mx-1"></span>
@@ -826,16 +943,137 @@ function send_init_confirm_email({to_email}) {
</tbody>
</table>
<!-- </div> --> <!-- .ae_h_scrollfix -->
</form>
</section> <!-- .ae_license_list -->
{/if} <!-- $event_exhibit_obj?.license_max -->
{/if}
</section> <!-- .tab__start -->
{:else if $store_current_tab == 'manage'}
{#if $events_loc?.leads.auth_exhibit_li && $events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id]}
<div>Manage: Logged in. Nothing here yet</div>
<!-- BEGIN Tab: Manage -->
{:else if $events_loc.leads.tab[$events_slct.exhibit_id] == 'manage'}
<section class="tab__manage flex flex-col wrap justify-center items-center space-y-4 ae_h_scrollfix">
<h2 class="h3">
<!-- <span class="fas fa-download"></span> -->
Login and License
</h2>
{#if $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
<div>
<strong>Logged in and using license for:</strong>
{#if $event_exhibit_obj?.license_li_json}
<!-- <div class="flex flex-row wrap gap-1"> -->
{#each $event_exhibit_obj?.license_li_json as license, index}
{#if license.email === $events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
<div class="flex flex-row items-center space-x-2">
<span class="ae_label">Name:</span>
<span class="ae_value">{license.full_name}</span>
</div>
{/if}
{/each}
<!-- </div> -->
{/if}
<div class="flex flex-row items-center space-x-2">
<span class="ae_label">Email:</span>
<span class="ae_value">{$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
</div>
<div class="flex flex-row items-center space-x-2">
<span class="ae_label">Started:</span>
<span class="ae_value">{ae_util.iso_datetime_formatter($events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].updated_on, 'datetime_long')}</span>
</div>
<!-- Show the full_name of the person associated with that license key email address. The license information is stored in an array. The license key is not the index number value in the array. Ideally I was planning to make the key the email address, not an array index number. -->
<button
type="button"
class="btn btn-sm variant-soft-warning w-48"
on:click={() => {
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key = null;
}}
>
<span class="fas fa-times mx-1"></span>
Clear License
</button>
<button
type="button"
on:click={() => {
console.log('Log Out');
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] = null;
}}
title="Log out"
class="btn btn-sm variant-soft-warning w-48"
>
<span class="fas fa-sign-out-alt mx-1"></span>
Log Out
</button>
</div>
{:else if $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id]}
<div class="variant-soft-warning">You are logged in using the shared passcode for the exhibit. You will want to select a license to fully use this lead retrieval service. Please go to the Main tab and select a license to use.</div>
<button
type="button"
on:click={() => {
console.log('Log Out');
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] = null;
}}
title="Log out"
class="btn btn-sm variant-soft-warning w-48"
>
<span class="fas fa-sign-out-alt mx-1"></span>
Log Out
</button>
{:else}
<div class="variant-soft-warning">Please go to the Main tab to login using the shared staff passcode for this exhibit. Then select a license to use.</div>
{/if}
{#if $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
<hr class="border w-full">
<h2 class="h3">
<!-- <span class="fas fa-download"></span> -->
Export Data
</h2>
<p>Use this to export the leads data for this exhibit to an Excel file format. The data can be downloaded at anytime using the export button below.</p>
<button
type="button"
on:click={() => {
if (!confirm('Download exported data Excel file?')) {
return false;
}
get_event_exhibit_tracking_export({ 'event_exhibit_id': $events_slct.exhibit_id, file_type: 'Excel', 'return_file': true, filename: `lead_retrieval_export_${$events_slct.exhibit_obj.name.replaceAll(' ', '_')}.xlsx`, auto_download: true, log_lvl: 2 });
// .replace(' ', '_')
}}
disabled={true}
class="btn btn-sm variant-soft-primary w-48 mb-1 export_data_btn"
title={`TEMPORARILY DISABLED: Download leads data for ${$events_slct.exhibit_obj.name}`}
>
<span class="fas fa-download mx-1"></span> Export Data
</button>
{/if} <!-- $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id].key -->
<hr class="border w-full">
<h2 class="h3">
<!-- <span class="fas fa-cogs"></span> -->
Additional Settings
</h2>
{#if $events_loc?.leads.auth_exhibit_kv[$events_slct.exhibit_id]}
<button
type="button"
@@ -843,18 +1081,18 @@ function send_init_confirm_email({to_email}) {
console.log('Show/Hide Details');
$events_loc.show_details = !$events_loc.show_details;
}}
class="btn variant-soft-primary w-48"
class="btn btn-sm variant-soft w-48"
>
<span class="fas fa-eye mx-1"></span>
Show/Hide Details
</button>
{#if $events_loc?.leads.auth_exhibit_li && $events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id]}
<!-- {#if $events_loc?.leads.auth_exhibit_kv && $events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id]}
<button
type="button"
on:click={() => {
console.log('Log Out');
$events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id] = null;
$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] = null;
}}
title="Log out"
class="btn variant-soft-primary w-48"
@@ -863,39 +1101,49 @@ function send_init_confirm_email({to_email}) {
Log Out
</button>
<p>To use the lead retrieval service, please select a license from the list on the Main tab.</p>
{/if} -->
{:else}
<div>You must be logged in to view this tab.</div>
{/if} <!-- $events_loc?.leads.auth_exhibit_kv && $events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id] -->
</section>
<!-- BEGIN Tab: Add/Scan -->
{:else if $events_loc.leads.tab[$events_slct.exhibit_id] == 'add_scan'}
<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>Scanning for:
{$events_loc.leads.auth_exhibit_kv[$events_slct.exhibit_id].key}
</div>
{:else}
<div class="variant-soft-warning">Please go to the Main tab and select a license to use.</div>
{/if}
{:else}
<div>Manage: Not logged in? Nothing here yet.</div>
{/if} <!-- $events_loc?.leads.auth_exhibit_li && $events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id] -->
<!-- <div class=""> -->
<Element_qr_scanner 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} />
<!-- </div> -->
{:else if $store_current_tab == 'add_scan'}
<div class="qr_quick_results variant-soft-secondary font-bold p-4">
{@html $events_sess.leads.qr_scan_result ?? 'No results yet'}
</div>
{#if $events_loc?.leads.auth_exhibit_li && $events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id]}
<div>Add/Scan: Logged in. Nothing here yet</div>
{:else}
<div class="variant-soft-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] -->
<Element_qr_scanner show_qr_manual_badge_id_entry_option={true} />
</section>
{/if} <!-- $events_loc.leads.tab[$events_slct.exhibit_id] -->
{:else}
<div>Add/Scan: Not logged in? Nothing here yet.</div>
{/if} <!-- $events_loc?.leads.auth_exhibit_li && $events_loc.leads.auth_exhibit_li[$events_slct.exhibit_id] -->
{/if} <!-- $store_current_tab -->
<!-- {:else} -->
<!-- {/if} -->
<!-- </section> -->
{/if} <!-- $events_slct.exhibit_id && $event_exhibit_obj -->
</section>