Prettier for Event ID

This commit is contained in:
Scott Idem
2026-03-24 12:16:11 -04:00
parent 693486bac9
commit 6e67534454
10 changed files with 948 additions and 895 deletions

View File

@@ -1,61 +1,70 @@
<script lang="ts"> <script lang="ts">
import { untrack } from 'svelte'; import { untrack } from 'svelte';
interface Props { interface Props {
/** @type {import('./$types').LayoutData} */ /** @type {import('./$types').LayoutData} */
data: any; data: any;
children?: import('svelte').Snippet; children?: import('svelte').Snippet;
}
let { data, children }: Props = $props();
let log_lvl: number = 0;
import {
ae_snip,
ae_loc,
ae_sess,
ae_api,
ae_trig,
slct,
slct_trigger
} from '$lib/stores/ae_stores';
import {
events_loc,
events_sess,
events_slct,
events_trigger
} from '$lib/stores/ae_events_stores';
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
// $slct.account_id = data.account_id;
// NOTE: Derived from data.account_id (prop) instead of $slct.account_id (store)
// to prevent circular dependency loops during hydration.
let ae_acct = $derived(data[data.account_id]);
$effect(() => {
if (log_lvl) {
console.log(`ae_acct = `, ae_acct);
} }
let { data, children }: Props = $props(); if (log_lvl > 1) {
console.log(`[event_id] +layout A: ${data.params.event_id}`);
if (ae_acct)
console.log(`[event_id] +layout B: ${ae_acct.slct.event_id}`);
console.log(`[event_id] +layout C: ${$events_slct.event_id}`);
}
});
let log_lvl: number = 0; $effect(() => {
if (ae_acct) {
import { untrack(() => {
ae_snip, if (
ae_loc, JSON.stringify($events_slct.event_session_obj_li) !==
ae_sess, JSON.stringify(ae_acct.slct.event_session_obj_li)
ae_api, ) {
ae_trig, $events_slct.event_session_obj_li =
slct, ae_acct.slct.event_session_obj_li;
slct_trigger }
} from '$lib/stores/ae_stores'; if (
import { JSON.stringify($events_slct.event_location_obj_li) !==
events_loc, JSON.stringify(ae_acct.slct.event_location_obj_li)
events_sess, ) {
events_slct, $events_slct.event_location_obj_li =
events_trigger ae_acct.slct.event_location_obj_li;
} from '$lib/stores/ae_events_stores'; }
});
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other. }
// $slct.account_id = data.account_id; });
// NOTE: Derived from data.account_id (prop) instead of $slct.account_id (store)
// to prevent circular dependency loops during hydration.
let ae_acct = $derived(data[data.account_id]);
$effect(() => {
if (log_lvl) {
console.log(`ae_acct = `, ae_acct);
}
if (log_lvl > 1) {
console.log(`[event_id] +layout A: ${data.params.event_id}`);
if (ae_acct) console.log(`[event_id] +layout B: ${ae_acct.slct.event_id}`);
console.log(`[event_id] +layout C: ${$events_slct.event_id}`);
}
});
$effect(() => {
if (ae_acct) {
untrack(() => {
if (JSON.stringify($events_slct.event_session_obj_li) !== JSON.stringify(ae_acct.slct.event_session_obj_li)) {
$events_slct.event_session_obj_li = ae_acct.slct.event_session_obj_li;
}
if (JSON.stringify($events_slct.event_location_obj_li) !== JSON.stringify(ae_acct.slct.event_location_obj_li)) {
$events_slct.event_location_obj_li = ae_acct.slct.event_location_obj_li;
}
});
}
});
</script> </script>
{@render children?.()} {@render children?.()}

View File

@@ -17,7 +17,9 @@ export async function load({ params, parent }) {
let ae_acct = data[account_id]; let ae_acct = data[account_id];
if (!ae_acct) { if (!ae_acct) {
console.warn(`ae Events - [event_id] +layout.ts: Account ${account_id} not found in data. Initializing ghost acct.`); console.warn(
`ae Events - [event_id] +layout.ts: Account ${account_id} not found in data. Initializing ghost acct.`
);
ae_acct = { ae_acct = {
api: data.ae_api || {}, api: data.ae_api || {},
slct: { slct: {
@@ -39,7 +41,8 @@ export async function load({ params, parent }) {
ae_acct.slct.event_id = event_id; ae_acct.slct.event_id = event_id;
if (browser) { if (browser) {
if (log_lvl) console.log(`ae_events [event_id] +layout.ts (Non-Blocking)`); if (log_lvl)
console.log(`ae_events [event_id] +layout.ts (Non-Blocking)`);
// OPTIMIZATION: Fire the event load in the background without 'await'. // OPTIMIZATION: Fire the event load in the background without 'await'.
// The event module uses SWR, so this will: // The event module uses SWR, so this will:

View File

@@ -1,65 +1,67 @@
<script lang="ts"> <script lang="ts">
import { liveQuery } from 'dexie'; import { liveQuery } from 'dexie';
import { Wrench, Presentation, Plane, IdCard, Contact } from '@lucide/svelte'; import { Wrench, Presentation, Plane, IdCard, Contact } from '@lucide/svelte';
import { db_events } from '$lib/ae_events/db_events'; import { db_events } from '$lib/ae_events/db_events';
import { ae_util } from '$lib/ae_utils/ae_utils'; import { ae_util } from '$lib/ae_utils/ae_utils';
import { events_slct } from '$lib/stores/ae_events_stores'; import { events_slct } from '$lib/stores/ae_events_stores';
import { ae_loc } from '$lib/stores/ae_stores'; import { ae_loc } from '$lib/stores/ae_stores';
interface Props { interface Props {
data: any; data: any;
}
let { data }: Props = $props();
let lq__event_obj = $derived(
liveQuery(async () => {
return await db_events.event.get($events_slct?.event_id ?? '');
})
);
const modules = [
{
name: 'Presentation Management',
path: 'pres_mgmt',
icon: Presentation,
description: 'Manage sessions, presentations, and presenters.',
color: 'preset-filled-primary-200-800',
access: 'authenticated_access'
},
{
name: 'Launcher',
path: 'launcher',
icon: Plane,
description: 'Launch presentations and manage live session display.',
color: 'preset-filled-secondary-200-800',
access: 'authenticated_access'
},
{
name: 'Badges',
path: 'badges',
icon: IdCard,
description: 'Manage and print event badges.',
color: 'preset-filled-tertiary-200-800',
access: 'authenticated_access'
},
{
name: 'Leads',
path: 'leads',
icon: Contact,
description: 'Exhibitor lead retrieval and management.',
color: 'preset-filled-success-200-800',
access: 'authenticated_access'
} }
let { data }: Props = $props(); ];
let lq__event_obj = $derived( let filtered_modules = $derived(
liveQuery(async () => { modules.filter((mod) => {
return await db_events.event.get($events_slct?.event_id ?? ''); if (mod.access === 'authenticated_access')
}) return $ae_loc.authenticated_access;
); if (mod.access === 'trusted_access') return $ae_loc.trusted_access;
if (mod.access === 'administrator_access')
const modules = [ return $ae_loc.administrator_access;
{ return true;
name: 'Presentation Management', })
path: 'pres_mgmt', );
icon: Presentation,
description: 'Manage sessions, presentations, and presenters.',
color: 'preset-filled-primary-200-800',
access: 'authenticated_access'
},
{
name: 'Launcher',
path: 'launcher',
icon: Plane,
description: 'Launch presentations and manage live session display.',
color: 'preset-filled-secondary-200-800',
access: 'authenticated_access'
},
{
name: 'Badges',
path: 'badges',
icon: IdCard,
description: 'Manage and print event badges.',
color: 'preset-filled-tertiary-200-800',
access: 'authenticated_access'
},
{
name: 'Leads',
path: 'leads',
icon: Contact,
description: 'Exhibitor lead retrieval and management.',
color: 'preset-filled-success-200-800',
access: 'authenticated_access'
}
];
let filtered_modules = $derived(
modules.filter(mod => {
if (mod.access === 'authenticated_access') return $ae_loc.authenticated_access;
if (mod.access === 'trusted_access') return $ae_loc.trusted_access;
if (mod.access === 'administrator_access') return $ae_loc.administrator_access;
return true;
})
);
</script> </script>
<svelte:head> <svelte:head>
@@ -68,23 +70,23 @@
</title> </title>
</svelte:head> </svelte:head>
<div class="container mx-auto p-4 space-y-8"> <div class="container mx-auto space-y-8 p-4">
<header class="text-center space-y-2"> <header class="space-y-2 text-center">
<h1 class="text-4xl font-bold"> <h1 class="text-4xl font-bold">
{$lq__event_obj?.name ?? 'Event Hub'} {$lq__event_obj?.name ?? 'Event Hub'}
</h1> </h1>
<p class="text-xl opacity-70"> <p class="text-xl opacity-70">
Welcome to the event management dashboard. Please select a module to begin. Welcome to the event management dashboard. Please select a module to
begin.
</p> </p>
</header> </header>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"> <div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-4">
{#each filtered_modules as mod (mod.path)} {#each filtered_modules as mod (mod.path)}
<a <a
href="/events/{$events_slct.event_id}/{mod.path}" href="/events/{$events_slct.event_id}/{mod.path}"
class="card card-hover p-6 flex flex-col items-center text-center space-y-4 transition-transform hover:scale-105 bg-surface-100 dark:bg-surface-800 border border-surface-200 dark:border-surface-700 shadow-lg" class="card card-hover bg-surface-100 dark:bg-surface-800 border-surface-200 dark:border-surface-700 flex flex-col items-center space-y-4 border p-6 text-center shadow-lg transition-transform hover:scale-105">
> <div class="rounded-full p-6 {mod.color} text-4xl text-white">
<div class="p-6 rounded-full {mod.color} text-white text-4xl">
<mod.icon size="2rem" /> <mod.icon size="2rem" />
</div> </div>
<h3 class="text-2xl font-bold">{mod.name}</h3> <h3 class="text-2xl font-bold">{mod.name}</h3>
@@ -94,14 +96,20 @@
</div> </div>
{#if $ae_loc.administrator_access && $ae_loc.edit_mode} {#if $ae_loc.administrator_access && $ae_loc.edit_mode}
<section class="card p-6 preset-tonal-warning border-l-4 border-warning-500 mt-12 shadow-lg"> <section
class="card preset-tonal-warning border-warning-500 mt-12 border-l-4 p-6 shadow-lg">
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<Wrench size="2rem" class="shrink-0" aria-hidden="true" /> <Wrench size="2rem" class="shrink-0" aria-hidden="true" />
<div> <div>
<h3 class="text-xl font-bold">Event Admin Settings</h3> <h3 class="text-xl font-bold">Event Admin Settings</h3>
<p>You have elevated privileges. Use the menu above to access advanced settings and reports.</p> <p>
You have elevated privileges. Use the menu above to
access advanced settings and reports.
</p>
</div> </div>
<a href="/events/{$events_slct.event_id}/settings" class="btn ae_btn_warning ml-auto"> <a
href="/events/{$events_slct.event_id}/settings"
class="btn ae_btn_warning ml-auto">
Event Settings Event Settings
</a> </a>
</div> </div>

View File

@@ -1,448 +1,456 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/state'; import { page } from '$app/state';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { Lock, Printer, Plus, Upload, FileText, BarChart2 } from '@lucide/svelte'; import {
import { liveQuery } from 'dexie'; Lock,
import { db_events, type Event } from '$lib/ae_events/db_events'; Printer,
import { onMount } from 'svelte'; Plus,
import { events_func } from '$lib/ae_events/ae_events_functions'; Upload,
import { ae_loc, ae_api } from '$lib/stores/ae_stores'; FileText,
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte'; BarChart2
import Ae_comp_event_settings_form from './ae_comp__event_settings_form.svelte'; } from '@lucide/svelte';
import Ae_comp_event_settings_pres_mgmt_form from './ae_comp__event_settings_pres_mgmt_form.svelte'; import { liveQuery } from 'dexie';
import Ae_comp_event_settings_basic_form from './ae_comp__event_settings_basic_form.svelte'; import { db_events, type Event } from '$lib/ae_events/db_events';
import Ae_comp_event_settings_badges_form from './ae_comp__event_settings_badges_form.svelte'; import { onMount } from 'svelte';
import Ae_comp_event_settings_abstracts_form from './ae_comp__event_settings_abstracts_form.svelte'; import { events_func } from '$lib/ae_events/ae_events_functions';
import { Modal } from 'flowbite-svelte'; import { ae_loc, ae_api } from '$lib/stores/ae_stores';
import Comp_badge_create_form from '../(badges)/badges/ae_comp__badge_create_form.svelte'; import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
import Comp_badge_upload_form from '../(badges)/badges/ae_comp__badge_upload_form.svelte'; import Ae_comp_event_settings_form from './ae_comp__event_settings_form.svelte';
import Ae_comp_event_settings_pres_mgmt_form from './ae_comp__event_settings_pres_mgmt_form.svelte';
import Ae_comp_event_settings_basic_form from './ae_comp__event_settings_basic_form.svelte';
import Ae_comp_event_settings_badges_form from './ae_comp__event_settings_badges_form.svelte';
import Ae_comp_event_settings_abstracts_form from './ae_comp__event_settings_abstracts_form.svelte';
import { Modal } from 'flowbite-svelte';
import Comp_badge_create_form from '../(badges)/badges/ae_comp__badge_create_form.svelte';
import Comp_badge_upload_form from '../(badges)/badges/ae_comp__badge_upload_form.svelte';
let event_id = page.params.event_id as string; let event_id = page.params.event_id as string;
let event_obj: Event | undefined | null = $state(null); let event_obj: Event | undefined | null = $state(null);
let cfg_json_view = $state('form'); let cfg_json_view = $state('form');
let pres_mgmt_json_view = $state('form'); let pres_mgmt_json_view = $state('form');
let badges_json_view = $state('form'); let badges_json_view = $state('form');
let abstracts_json_view = $state('form'); let abstracts_json_view = $state('form');
// Temp string values for CodeMirror binding // Temp string values for CodeMirror binding
// WARNING: These string buffers are used to decouple the object-based model from the string-based editor. // WARNING: These string buffers are used to decouple the object-based model from the string-based editor.
// Always ensure valid JSON parsing before calling handle_save to prevent data corruption. // Always ensure valid JSON parsing before calling handle_save to prevent data corruption.
let tmp_cfg_json_str = $state(''); let tmp_cfg_json_str = $state('');
let tmp_pres_mgmt_json_str = $state(''); let tmp_pres_mgmt_json_str = $state('');
let tmp_badges_json_str = $state(''); let tmp_badges_json_str = $state('');
let tmp_abstracts_json_str = $state(''); let tmp_abstracts_json_str = $state('');
let tmp_exhibits_json_str = $state(''); let tmp_exhibits_json_str = $state('');
let tmp_meetings_json_str = $state(''); let tmp_meetings_json_str = $state('');
let show_create_badge_modal: boolean = $state(false); let show_create_badge_modal: boolean = $state(false);
let show_upload_badge_modal: boolean = $state(false); let show_upload_badge_modal: boolean = $state(false);
onMount(() => { onMount(() => {
// Guard: administrator access required. 500ms grace delay matches the /core // Guard: administrator access required. 500ms grace delay matches the /core
// layout pattern — allows the persisted store to hydrate before redirecting. // layout pattern — allows the persisted store to hydrate before redirecting.
setTimeout(() => { setTimeout(() => {
if (!$ae_loc.administrator_access) { if (!$ae_loc.administrator_access) {
goto(`/events/${event_id}`); goto(`/events/${event_id}`);
} }
}, 500); }, 500);
const observable = liveQuery(() => db_events.event.get(event_id)); const observable = liveQuery(() => db_events.event.get(event_id));
const subscription = observable.subscribe((value) => { const subscription = observable.subscribe((value) => {
event_obj = value; event_obj = value;
if (event_obj) { if (event_obj) {
tmp_cfg_json_str = JSON.stringify(event_obj.cfg_json, null, 4); tmp_cfg_json_str = JSON.stringify(event_obj.cfg_json, null, 4);
tmp_pres_mgmt_json_str = JSON.stringify(event_obj.mod_pres_mgmt_json, null, 4); tmp_pres_mgmt_json_str = JSON.stringify(
tmp_badges_json_str = JSON.stringify(event_obj.mod_badges_json, null, 4); event_obj.mod_pres_mgmt_json,
tmp_abstracts_json_str = JSON.stringify(event_obj.mod_abstracts_json, null, 4); null,
tmp_exhibits_json_str = JSON.stringify(event_obj.mod_exhibits_json, null, 4); 4
tmp_meetings_json_str = JSON.stringify(event_obj.mod_meetings_json, null, 4); );
} tmp_badges_json_str = JSON.stringify(
}); event_obj.mod_badges_json,
null,
return () => { 4
subscription.unsubscribe(); );
}; tmp_abstracts_json_str = JSON.stringify(
}); event_obj.mod_abstracts_json,
null,
async function handle_save(field_name: string, data: any) { 4
if (!data) return; );
try { tmp_exhibits_json_str = JSON.stringify(
let data_kv = {}; event_obj.mod_exhibits_json,
if (field_name === 'basic_fields') { null,
data_kv = data; 4
} else { );
const data_to_save = tmp_meetings_json_str = JSON.stringify(
typeof data === 'string' ? JSON.parse(data) : data; event_obj.mod_meetings_json,
data_kv = { [field_name]: data_to_save }; null,
} 4
await events_func.update_ae_obj__event({
api_cfg: $ae_api,
event_id: event_id,
data_kv: data_kv
});
alert('Settings saved successfully!');
} catch (error) {
console.error('Error saving settings:', error);
alert(
'Failed to save settings. Please check if the JSON is valid.'
); );
} }
});
return () => {
subscription.unsubscribe();
};
});
async function handle_save(field_name: string, data: any) {
if (!data) return;
try {
let data_kv = {};
if (field_name === 'basic_fields') {
data_kv = data;
} else {
const data_to_save =
typeof data === 'string' ? JSON.parse(data) : data;
data_kv = { [field_name]: data_to_save };
}
await events_func.update_ae_obj__event({
api_cfg: $ae_api,
event_id: event_id,
data_kv: data_kv
});
alert('Settings saved successfully!');
} catch (error) {
console.error('Error saving settings:', error);
alert('Failed to save settings. Please check if the JSON is valid.');
} }
}
</script> </script>
{#if $ae_loc.administrator_access} {#if $ae_loc.administrator_access}
<h1 class="h1">Event Settings</h1>
<h1 class="h1">Event Settings</h1> {#if event_obj}
<div class="space-y-4">
{#if event_obj} <details class="details" open>
<div class="space-y-4"> <summary class="summary text-error-500 font-bold"
<details class="details" open> >Admin Tools</summary>
<summary class="summary font-bold text-error-500" <div class="space-y-4 p-4">
>Admin Tools</summary <div class="card rounded-md border p-4 text-center">
> <h4 class="h4">Badge Operations</h4>
<div class="p-4 space-y-4"> <div class="mt-2 flex flex-wrap justify-center gap-2">
<div class="card p-4 border rounded-md text-center"> <button
<h4 class="h4">Badge Operations</h4> type="button"
<div class="flex flex-wrap justify-center gap-2 mt-2"> class="btn btn-primary"
<button onclick={() =>
type="button" (show_create_badge_modal = true)}>
class="btn btn-primary" <Plus size="1em" aria-hidden="true" /> Add New Badge
onclick={() => (show_create_badge_modal = true)} </button>
> <button
<Plus size="1em" aria-hidden="true" /> Add New Badge type="button"
</button> class="btn btn-primary ml-2"
<button onclick={() =>
type="button" (show_upload_badge_modal = true)}>
class="btn btn-primary ml-2" <Upload size="1em" aria-hidden="true" /> Upload Badge
onclick={() => (show_upload_badge_modal = true)} List
> </button>
<Upload size="1em" aria-hidden="true" /> Upload Badge </div>
List
</button>
</div> </div>
</div>
<div class="card p-4 border rounded-md text-center"> <div class="card rounded-md border p-4 text-center">
<h4 class="h4">Mass Print Options</h4> <h4 class="h4">Mass Print Options</h4>
<div class="flex flex-wrap justify-center gap-2 mt-2"> <div class="mt-2 flex flex-wrap justify-center gap-2">
<a
href={`/events/${event_id}/badges/print_list?printed_status=not_printed`}
class="btn preset-filled-secondary">
<Printer size="1em" aria-hidden="true" /> Print All
Unprinted
</a>
<a
href={`/events/${event_id}/badges/print_list?badge_type_code=guest&printed_status=not_printed`}
class="btn preset-filled-secondary">
<Printer size="1em" aria-hidden="true" /> Print Unprinted
Guests
</a>
<a
href={`/events/${event_id}/badges/print_list`}
class="btn preset-filled-secondary">
<Printer size="1em" aria-hidden="true" /> Print All
</a>
</div>
</div>
<div class="mt-4 flex flex-wrap justify-center gap-4">
<a <a
href={`/events/${event_id}/badges/print_list?printed_status=not_printed`} href={`/events/${event_id}/templates`}
class="btn preset-filled-secondary" class="btn btn-tertiary">
> <FileText size="1em" aria-hidden="true" /> Manage Badge
<Printer size="1em" aria-hidden="true" /> Print All Unprinted Templates
</a> </a>
<a <a
href={`/events/${event_id}/badges/print_list?badge_type_code=guest&printed_status=not_printed`} href={`/events/${event_id}/badges/stats`}
class="btn preset-filled-secondary" class="btn btn-tertiary">
> <BarChart2 size="1em" aria-hidden="true" /> Badge Printing
<Printer size="1em" aria-hidden="true" /> Print Unprinted Stats
Guests
</a>
<a
href={`/events/${event_id}/badges/print_list`}
class="btn preset-filled-secondary"
>
<Printer size="1em" aria-hidden="true" /> Print All
</a> </a>
</div> </div>
</div> </div>
</details>
<div class="flex flex-wrap justify-center gap-4 mt-4"> <details class="details">
<a <summary class="summary">Basic Info</summary>
href={`/events/${event_id}/templates`} <div class="p-4">
class="btn btn-tertiary" <Ae_comp_event_settings_basic_form
> bind:event_obj
<FileText size="1em" aria-hidden="true" /> Manage Badge Templates
</a>
<a
href={`/events/${event_id}/badges/stats`}
class="btn btn-tertiary"
>
<BarChart2 size="1em" aria-hidden="true" /> Badge Printing
Stats
</a>
</div>
</div>
</details>
<details class="details">
<summary class="summary">Basic Info</summary>
<div class="p-4">
<Ae_comp_event_settings_basic_form
bind:event_obj
onsave={(data: any) => handle_save('basic_fields', data)}
/>
</div>
</details>
<details class="details">
<summary class="summary">General Config (cfg_json)</summary>
<div class="p-4">
<div class="flex justify-end">
<button
type="button"
class="btn btn-sm"
onclick={() => (cfg_json_view = 'form')}>Form</button
>
<button
type="button"
class="btn btn-sm"
onclick={() => (cfg_json_view = 'json')}>JSON</button
>
</div>
{#if cfg_json_view === 'form'}
<Ae_comp_event_settings_form
bind:cfg_json={event_obj.cfg_json}
onsave={(data: any) => handle_save('cfg_json', data)}
/>
{:else}
<AE_Comp_Editor_CodeMirror
readonly={false}
content={tmp_cfg_json_str}
bind:new_content={tmp_cfg_json_str}
show_line_numbers={true}
placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg"
/>
<button
type="button"
class="btn preset-tonal-primary"
onclick={() => {
handle_save('cfg_json', tmp_cfg_json_str);
}}>Save</button
>
{/if}
</div>
</details>
<details class="details">
<summary class="summary"
>Presentation Management (mod_pres_mgmt_json)</summary
>
<div class="p-4">
<div class="flex justify-end">
<button
type="button"
class="btn btn-sm"
onclick={() => (pres_mgmt_json_view = 'form')}
>Form</button
>
<button
type="button"
class="btn btn-sm"
onclick={() => (pres_mgmt_json_view = 'json')}
>JSON</button
>
</div>
{#if pres_mgmt_json_view === 'form'}
<Ae_comp_event_settings_pres_mgmt_form
bind:mod_pres_mgmt_json={event_obj.mod_pres_mgmt_json}
onsave={(data: any) => onsave={(data: any) =>
handle_save('mod_pres_mgmt_json', data)} handle_save('basic_fields', data)} />
/> </div>
{:else} </details>
<details class="details">
<summary class="summary">General Config (cfg_json)</summary>
<div class="p-4">
<div class="flex justify-end">
<button
type="button"
class="btn btn-sm"
onclick={() => (cfg_json_view = 'form')}
>Form</button>
<button
type="button"
class="btn btn-sm"
onclick={() => (cfg_json_view = 'json')}
>JSON</button>
</div>
{#if cfg_json_view === 'form'}
<Ae_comp_event_settings_form
bind:cfg_json={event_obj.cfg_json}
onsave={(data: any) =>
handle_save('cfg_json', data)} />
{:else}
<AE_Comp_Editor_CodeMirror
readonly={false}
content={tmp_cfg_json_str}
bind:new_content={tmp_cfg_json_str}
show_line_numbers={true}
placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg" />
<button
type="button"
class="btn preset-tonal-primary"
onclick={() => {
handle_save('cfg_json', tmp_cfg_json_str);
}}>Save</button>
{/if}
</div>
</details>
<details class="details">
<summary class="summary"
>Presentation Management (mod_pres_mgmt_json)</summary>
<div class="p-4">
<div class="flex justify-end">
<button
type="button"
class="btn btn-sm"
onclick={() => (pres_mgmt_json_view = 'form')}
>Form</button>
<button
type="button"
class="btn btn-sm"
onclick={() => (pres_mgmt_json_view = 'json')}
>JSON</button>
</div>
{#if pres_mgmt_json_view === 'form'}
<Ae_comp_event_settings_pres_mgmt_form
bind:mod_pres_mgmt_json={
event_obj.mod_pres_mgmt_json
}
onsave={(data: any) =>
handle_save('mod_pres_mgmt_json', data)} />
{:else}
<AE_Comp_Editor_CodeMirror
readonly={false}
content={tmp_pres_mgmt_json_str}
bind:new_content={tmp_pres_mgmt_json_str}
show_line_numbers={true}
placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg" />
<button
type="button"
class="btn preset-tonal-primary"
onclick={() => {
handle_save(
'mod_pres_mgmt_json',
tmp_pres_mgmt_json_str
);
}}>Save</button>
{/if}
</div>
</details>
<details class="details">
<summary class="summary">Badges (mod_badges_json)</summary>
<div class="p-4">
<div class="flex justify-end">
<button
type="button"
class="btn btn-sm"
onclick={() => (badges_json_view = 'form')}
>Form</button>
<button
type="button"
class="btn btn-sm"
onclick={() => (badges_json_view = 'json')}
>JSON</button>
</div>
{#if badges_json_view === 'form'}
<Ae_comp_event_settings_badges_form
bind:mod_badges_json={event_obj.mod_badges_json}
onsave={(data: any) =>
handle_save('mod_badges_json', data)} />
{:else}
<AE_Comp_Editor_CodeMirror
readonly={false}
content={tmp_badges_json_str}
bind:new_content={tmp_badges_json_str}
show_line_numbers={true}
placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg" />
<button
type="button"
class="btn preset-tonal-primary"
onclick={() => {
handle_save(
'mod_badges_json',
tmp_badges_json_str
);
}}>Save</button>
{/if}
</div>
</details>
<details class="details">
<summary class="summary"
>Abstracts (mod_abstracts_json)</summary>
<div class="p-4">
<div class="flex justify-end">
<button
type="button"
class="btn btn-sm"
onclick={() => (abstracts_json_view = 'form')}
>Form</button>
<button
type="button"
class="btn btn-sm"
onclick={() => (abstracts_json_view = 'json')}
>JSON</button>
</div>
{#if abstracts_json_view === 'form'}
<Ae_comp_event_settings_abstracts_form
bind:mod_abstracts_json={
event_obj.mod_abstracts_json
}
onsave={(data: any) =>
handle_save('mod_abstracts_json', data)} />
{:else}
<AE_Comp_Editor_CodeMirror
readonly={false}
content={tmp_abstracts_json_str}
bind:new_content={tmp_abstracts_json_str}
show_line_numbers={true}
placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg" />
<button
type="button"
class="btn preset-tonal-primary"
onclick={() => {
handle_save(
'mod_abstracts_json',
tmp_abstracts_json_str
);
}}>Save</button>
{/if}
</div>
</details>
<details class="details">
<summary class="summary">Exhibits (mod_exhibits_json)</summary>
<div class="p-4">
<AE_Comp_Editor_CodeMirror <AE_Comp_Editor_CodeMirror
readonly={false} readonly={false}
content={tmp_pres_mgmt_json_str} content={tmp_exhibits_json_str}
bind:new_content={tmp_pres_mgmt_json_str} bind:new_content={tmp_exhibits_json_str}
show_line_numbers={true} show_line_numbers={true}
placeholder="JSON config" placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg" class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg" />
/>
<button <button
type="button" type="button"
class="btn preset-tonal-primary" class="btn preset-tonal-primary"
onclick={() => { onclick={() => {
handle_save( handle_save(
'mod_pres_mgmt_json', 'mod_exhibits_json',
tmp_pres_mgmt_json_str tmp_exhibits_json_str
); );
}}>Save</button }}>Save</button>
>
{/if}
</div>
</details>
<details class="details">
<summary class="summary">Badges (mod_badges_json)</summary>
<div class="p-4">
<div class="flex justify-end">
<button
type="button"
class="btn btn-sm"
onclick={() => (badges_json_view = 'form')}>Form</button
>
<button
type="button"
class="btn btn-sm"
onclick={() => (badges_json_view = 'json')}>JSON</button
>
</div> </div>
{#if badges_json_view === 'form'} </details>
<Ae_comp_event_settings_badges_form
bind:mod_badges_json={event_obj.mod_badges_json} <details class="details">
onsave={(data: any) => <summary class="summary">Meetings (mod_meetings_json)</summary>
handle_save('mod_badges_json', data)} <div class="p-4">
/>
{:else}
<AE_Comp_Editor_CodeMirror <AE_Comp_Editor_CodeMirror
readonly={false} readonly={false}
content={tmp_badges_json_str} content={tmp_meetings_json_str}
bind:new_content={tmp_badges_json_str} bind:new_content={tmp_meetings_json_str}
show_line_numbers={true} show_line_numbers={true}
placeholder="JSON config" placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg" class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg" />
/>
<button <button
type="button" type="button"
class="btn preset-tonal-primary" class="btn preset-tonal-primary"
onclick={() => { onclick={() => {
handle_save( handle_save(
'mod_badges_json', 'mod_meetings_json',
tmp_badges_json_str tmp_meetings_json_str
); );
}}>Save</button }}>Save</button>
>
{/if}
</div>
</details>
<details class="details">
<summary class="summary">Abstracts (mod_abstracts_json)</summary>
<div class="p-4">
<div class="flex justify-end">
<button
type="button"
class="btn btn-sm"
onclick={() => (abstracts_json_view = 'form')}
>Form</button
>
<button
type="button"
class="btn btn-sm"
onclick={() => (abstracts_json_view = 'json')}
>JSON</button
>
</div> </div>
{#if abstracts_json_view === 'form'} </details>
<Ae_comp_event_settings_abstracts_form
bind:mod_abstracts_json={event_obj.mod_abstracts_json}
onsave={(data: any) =>
handle_save('mod_abstracts_json', data)}
/>
{:else}
<AE_Comp_Editor_CodeMirror
readonly={false}
content={tmp_abstracts_json_str}
bind:new_content={tmp_abstracts_json_str}
show_line_numbers={true}
placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg"
/>
<button
type="button"
class="btn preset-tonal-primary"
onclick={() => {
handle_save(
'mod_abstracts_json',
tmp_abstracts_json_str
);
}}>Save</button
>
{/if}
</div>
</details>
<details class="details">
<summary class="summary">Exhibits (mod_exhibits_json)</summary>
<div class="p-4">
<AE_Comp_Editor_CodeMirror
readonly={false}
content={tmp_exhibits_json_str}
bind:new_content={tmp_exhibits_json_str}
show_line_numbers={true}
placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg"
/>
<button
type="button"
class="btn preset-tonal-primary"
onclick={() => {
handle_save(
'mod_exhibits_json',
tmp_exhibits_json_str
);
}}>Save</button
> </div>
</details>
<details class="details">
<summary class="summary">Meetings (mod_meetings_json)</summary>
<div class="p-4">
<AE_Comp_Editor_CodeMirror
readonly={false}
content={tmp_meetings_json_str}
bind:new_content={tmp_meetings_json_str}
show_line_numbers={true}
placeholder="JSON config"
class_li="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg"
/>
<button
type="button"
class="btn preset-tonal-primary"
onclick={() => {
handle_save(
'mod_meetings_json',
tmp_meetings_json_str
);
}}>Save</button
> </div>
</details>
</div>
{:else}
<p>Loading event data...</p>
{/if}
{#if show_create_badge_modal}
<Modal bind:open={show_create_badge_modal}>
<div class="card p-4">
<h3 class="h3">Create New Badge</h3>
<Comp_badge_create_form
{event_id}
onsuccess={() => {
show_create_badge_modal = false;
}}
oncancel={() => (show_create_badge_modal = false)}
/>
</div> </div>
</Modal> {:else}
{/if} <p>Loading event data...</p>
{/if}
{#if show_upload_badge_modal} {#if show_create_badge_modal}
<Modal bind:open={show_upload_badge_modal}> <Modal bind:open={show_create_badge_modal}>
<div class="card p-4"> <div class="card p-4">
<h3 class="h3">Upload Badges (CSV)</h3> <h3 class="h3">Create New Badge</h3>
<Comp_badge_upload_form <Comp_badge_create_form
{event_id} {event_id}
onsuccess={() => { onsuccess={() => {
show_upload_badge_modal = false; show_create_badge_modal = false;
}} }}
oncancel={() => (show_upload_badge_modal = false)} oncancel={() => (show_create_badge_modal = false)} />
/> </div>
</div> </Modal>
</Modal> {/if}
{/if}
{#if show_upload_badge_modal}
<Modal bind:open={show_upload_badge_modal}>
<div class="card p-4">
<h3 class="h3">Upload Badges (CSV)</h3>
<Comp_badge_upload_form
{event_id}
onsuccess={() => {
show_upload_badge_modal = false;
}}
oncancel={() => (show_upload_badge_modal = false)} />
</div>
</Modal>
{/if}
{:else} {:else}
<!-- Non-administrator landed here — show a brief message while the onMount redirect fires --> <!-- Non-administrator landed here — show a brief message while the onMount redirect fires -->
<section class="flex flex-col items-center justify-center grow text-center space-y-4 py-20"> <section
<div class="p-6 bg-error-500/10 rounded-full"> class="flex grow flex-col items-center justify-center space-y-4 py-20 text-center">
<div class="bg-error-500/10 rounded-full p-6">
<Lock size={64} class="text-error-500" /> <Lock size={64} class="text-error-500" />
</div> </div>
<h1 class="h1 font-black">Access Restricted</h1> <h1 class="h1 font-black">Access Restricted</h1>
<p class="max-w-md opacity-70">Event settings require administrator access. Redirecting…</p> <p class="max-w-md opacity-70">
<a href={`/events/${event_id}`} class="btn preset-filled-primary">Return to Event</a> Event settings require administrator access. Redirecting…
</p>
<a href={`/events/${event_id}`} class="btn preset-filled-primary"
>Return to Event</a>
</section> </section>
{/if} {/if}

View File

@@ -1,16 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { key_val } from '$lib/stores/ae_stores'; import type { key_val } from '$lib/stores/ae_stores';
interface Props { interface Props {
mod_abstracts_json: key_val | null | undefined; mod_abstracts_json: key_val | null | undefined;
onsave?: (data: key_val) => void; onsave?: (data: key_val) => void;
} }
let { mod_abstracts_json = $bindable({}), onsave }: Props = $props(); let { mod_abstracts_json = $bindable({}), onsave }: Props = $props();
function save() { function save() {
if (onsave && mod_abstracts_json) onsave(mod_abstracts_json); if (onsave && mod_abstracts_json) onsave(mod_abstracts_json);
} }
</script> </script>
<div class="space-y-4"> <div class="space-y-4">
@@ -22,8 +22,7 @@
<input <input
type="number" type="number"
class="input" class="input"
bind:value={mod_abstracts_json.name_char_limit} bind:value={mod_abstracts_json.name_char_limit} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -32,8 +31,7 @@
<input <input
type="number" type="number"
class="input" class="input"
bind:value={mod_abstracts_json.text_char_limit} bind:value={mod_abstracts_json.text_char_limit} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -42,8 +40,7 @@
<input <input
type="datetime-local" type="datetime-local"
class="input" class="input"
bind:value={mod_abstracts_json.deadline_new} bind:value={mod_abstracts_json.deadline_new} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -52,8 +49,7 @@
<input <input
type="datetime-local" type="datetime-local"
class="input" class="input"
bind:value={mod_abstracts_json.deadline_updates} bind:value={mod_abstracts_json.deadline_updates} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -61,8 +57,9 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_abstracts_json.confirm_email_w_link} bind:checked={
/> mod_abstracts_json.confirm_email_w_link
} />
<span>Confirm Email with Link</span> <span>Confirm Email with Link</span>
</label> </label>
</div> </div>
@@ -72,8 +69,7 @@
<input <input
type="email" type="email"
class="input" class="input"
bind:value={mod_abstracts_json.confirm_from_email} bind:value={mod_abstracts_json.confirm_from_email} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -82,8 +78,7 @@
<input <input
type="text" type="text"
class="input" class="input"
bind:value={mod_abstracts_json.confirm_from_name} bind:value={mod_abstracts_json.confirm_from_name} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -92,14 +87,14 @@
<input <input
type="email" type="email"
class="input" class="input"
bind:value={mod_abstracts_json.confirm_to_email_override} bind:value={
/> mod_abstracts_json.confirm_to_email_override
} />
</label> </label>
</div> </div>
</div> </div>
{/if} {/if}
<button type="button" class="btn preset-tonal-primary" onclick={save} <button type="button" class="btn preset-tonal-primary" onclick={save}
>Save</button >Save</button>
>
</div> </div>

View File

@@ -1,83 +1,106 @@
<script lang="ts"> <script lang="ts">
import type { key_val } from '$lib/stores/ae_stores'; import type { key_val } from '$lib/stores/ae_stores';
interface Props { interface Props {
mod_badges_json: key_val | null | undefined; mod_badges_json: key_val | null | undefined;
onsave?: (data: key_val) => void; onsave?: (data: key_val) => void;
}
let { mod_badges_json = $bindable({}), onsave }: Props = $props();
/**
* edit_permissions — controls which fields each access level may edit in the badge review form.
* Stored as mod_badges_json.edit_permissions.
*
* Structure:
* authenticated.can_edit — fields attendees (passcode-validated) may edit
* trusted.can_edit — fields trusted staff may edit
* administrator.can_edit — '*' (all) or a specific field list
*
* Default attendee fields: full_name_override, professional_title_override,
* affiliations_override, location_override
* Default trusted fields: above + email, badge_type_code
*/
const all_attendee_fields = [
{ key: 'full_name_override', label: 'Full Name (override)' },
{
key: 'professional_title_override',
label: 'Professional Title (override)'
},
{ key: 'affiliations_override', label: 'Affiliations (override)' },
{ key: 'location_override', label: 'Location (override)' }
];
const all_staff_fields = [
...all_attendee_fields,
{ key: 'email', label: 'Email' },
{ key: 'badge_type_code', label: 'Badge Type Code' }
];
// Ensure edit_permissions sub-object exists
function ensure_permissions() {
if (!mod_badges_json) return;
if (!mod_badges_json.edit_permissions) {
mod_badges_json.edit_permissions = {};
} }
if (!mod_badges_json.edit_permissions.authenticated) {
let { mod_badges_json = $bindable({}), onsave }: Props = $props(); mod_badges_json.edit_permissions.authenticated = {
can_edit: [
/** 'full_name_override',
* edit_permissions — controls which fields each access level may edit in the badge review form. 'professional_title_override',
* Stored as mod_badges_json.edit_permissions. 'affiliations_override',
* 'location_override'
* Structure: ]
* authenticated.can_edit — fields attendees (passcode-validated) may edit };
* trusted.can_edit — fields trusted staff may edit
* administrator.can_edit — '*' (all) or a specific field list
*
* Default attendee fields: full_name_override, professional_title_override,
* affiliations_override, location_override
* Default trusted fields: above + email, badge_type_code
*/
const all_attendee_fields = [
{ key: 'full_name_override', label: 'Full Name (override)' },
{ key: 'professional_title_override', label: 'Professional Title (override)' },
{ key: 'affiliations_override', label: 'Affiliations (override)' },
{ key: 'location_override', label: 'Location (override)' }
];
const all_staff_fields = [
...all_attendee_fields,
{ key: 'email', label: 'Email' },
{ key: 'badge_type_code', label: 'Badge Type Code' }
];
// Ensure edit_permissions sub-object exists
function ensure_permissions() {
if (!mod_badges_json) return;
if (!mod_badges_json.edit_permissions) {
mod_badges_json.edit_permissions = {};
}
if (!mod_badges_json.edit_permissions.authenticated) {
mod_badges_json.edit_permissions.authenticated = {
can_edit: ['full_name_override', 'professional_title_override', 'affiliations_override', 'location_override']
};
}
if (!mod_badges_json.edit_permissions.trusted) {
mod_badges_json.edit_permissions.trusted = {
can_edit: ['full_name_override', 'professional_title_override', 'affiliations_override', 'location_override', 'email', 'badge_type_code']
};
}
if (!mod_badges_json.edit_permissions.administrator) {
mod_badges_json.edit_permissions.administrator = { can_edit: '*' };
}
} }
if (!mod_badges_json.edit_permissions.trusted) {
function is_field_enabled(level: 'authenticated' | 'trusted', field_key: string): boolean { mod_badges_json.edit_permissions.trusted = {
const cfg = mod_badges_json?.edit_permissions?.[level]?.can_edit; can_edit: [
if (!cfg) return false; 'full_name_override',
if (cfg === '*') return true; 'professional_title_override',
return Array.isArray(cfg) && cfg.includes(field_key); 'affiliations_override',
'location_override',
'email',
'badge_type_code'
]
};
} }
if (!mod_badges_json.edit_permissions.administrator) {
function toggle_field(level: 'authenticated' | 'trusted', field_key: string) { mod_badges_json.edit_permissions.administrator = { can_edit: '*' };
ensure_permissions();
if (!mod_badges_json?.edit_permissions?.[level]) return;
let fields: string[] = mod_badges_json.edit_permissions[level].can_edit;
if (!Array.isArray(fields)) fields = [];
if (fields.includes(field_key)) {
mod_badges_json.edit_permissions[level].can_edit = fields.filter((f: string) => f !== field_key);
} else {
mod_badges_json.edit_permissions[level].can_edit = [...fields, field_key];
}
} }
}
function save() { function is_field_enabled(
if (onsave && mod_badges_json) onsave(mod_badges_json); level: 'authenticated' | 'trusted',
field_key: string
): boolean {
const cfg = mod_badges_json?.edit_permissions?.[level]?.can_edit;
if (!cfg) return false;
if (cfg === '*') return true;
return Array.isArray(cfg) && cfg.includes(field_key);
}
function toggle_field(level: 'authenticated' | 'trusted', field_key: string) {
ensure_permissions();
if (!mod_badges_json?.edit_permissions?.[level]) return;
let fields: string[] = mod_badges_json.edit_permissions[level].can_edit;
if (!Array.isArray(fields)) fields = [];
if (fields.includes(field_key)) {
mod_badges_json.edit_permissions[level].can_edit = fields.filter(
(f: string) => f !== field_key
);
} else {
mod_badges_json.edit_permissions[level].can_edit = [
...fields,
field_key
];
} }
}
function save() {
if (onsave && mod_badges_json) onsave(mod_badges_json);
}
</script> </script>
<div class="space-y-4"> <div class="space-y-4">
@@ -88,8 +111,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_badges_json.badge_id_only_search} bind:checked={mod_badges_json.badge_id_only_search} />
/>
<span>Badge ID Only Search</span> <span>Badge ID Only Search</span>
</label> </label>
</div> </div>
@@ -98,8 +120,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_badges_json.enable_mass_print} bind:checked={mod_badges_json.enable_mass_print} />
/>
<span>Enable Mass Print</span> <span>Enable Mass Print</span>
</label> </label>
</div> </div>
@@ -108,8 +129,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_badges_json.enable_add_badge_btn} bind:checked={mod_badges_json.enable_add_badge_btn} />
/>
<span>Enable Add Badge Button</span> <span>Enable Add Badge Button</span>
</label> </label>
</div> </div>
@@ -118,8 +138,9 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_badges_json.enable_upload_badge_li_btn} bind:checked={
/> mod_badges_json.enable_upload_badge_li_btn
} />
<span>Enable Upload Badge List Button</span> <span>Enable Upload Badge List Button</span>
</label> </label>
</div> </div>
@@ -128,8 +149,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_badges_json.enable_search_qr} bind:checked={mod_badges_json.enable_search_qr} />
/>
<span>Enable Search by QR</span> <span>Enable Search by QR</span>
</label> </label>
</div> </div>
@@ -142,8 +162,7 @@
<input <input
type="text" type="text"
class="input" class="input"
bind:value={mod_badges_json.qr_type} bind:value={mod_badges_json.qr_type} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -152,8 +171,7 @@
<input <input
type="text" type="text"
class="input" class="input"
bind:value={mod_badges_json.trusted_passcode} bind:value={mod_badges_json.trusted_passcode} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -162,20 +180,20 @@
<input <input
type="text" type="text"
class="input" class="input"
bind:value={mod_badges_json.administrator_passcode} bind:value={mod_badges_json.administrator_passcode} />
/>
</label> </label>
</div> </div>
</div> </div>
<details class="space-y-3"> <details class="space-y-3">
<summary class="cursor-pointer font-medium text-sm"> <summary class="cursor-pointer text-sm font-medium">
Badge Review — Editable Field Permissions Badge Review — Editable Field Permissions
</summary> </summary>
<div class="space-y-4 pt-2 pl-2"> <div class="space-y-4 pt-2 pl-2">
<p class="text-xs text-gray-500"> <p class="text-xs text-gray-500">
Controls which fields each access level may edit on the Badge Review page. Controls which fields each access level may edit on the
Staff (Trusted) defaults include all attendee fields plus Email and Badge Type Code. Badge Review page. Staff (Trusted) defaults include all
attendee fields plus Email and Badge Type Code.
Administrators can always edit everything. Administrators can always edit everything.
</p> </p>
@@ -184,13 +202,20 @@
<p class="text-sm font-medium">Attendees (passcode link)</p> <p class="text-sm font-medium">Attendees (passcode link)</p>
<div class="grid grid-cols-2 gap-x-4 gap-y-1"> <div class="grid grid-cols-2 gap-x-4 gap-y-1">
{#each all_attendee_fields as field (field.key)} {#each all_attendee_fields as field (field.key)}
<label class="label flex items-center gap-2 text-sm"> <label
class="label flex items-center gap-2 text-sm">
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
checked={is_field_enabled('authenticated', field.key)} checked={is_field_enabled(
onchange={() => toggle_field('authenticated', field.key)} 'authenticated',
/> field.key
)}
onchange={() =>
toggle_field(
'authenticated',
field.key
)} />
<span>{field.label}</span> <span>{field.label}</span>
</label> </label>
{/each} {/each}
@@ -202,13 +227,17 @@
<p class="text-sm font-medium">Staff (Trusted access)</p> <p class="text-sm font-medium">Staff (Trusted access)</p>
<div class="grid grid-cols-2 gap-x-4 gap-y-1"> <div class="grid grid-cols-2 gap-x-4 gap-y-1">
{#each all_staff_fields as field (field.key)} {#each all_staff_fields as field (field.key)}
<label class="label flex items-center gap-2 text-sm"> <label
class="label flex items-center gap-2 text-sm">
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
checked={is_field_enabled('trusted', field.key)} checked={is_field_enabled(
onchange={() => toggle_field('trusted', field.key)} 'trusted',
/> field.key
)}
onchange={() =>
toggle_field('trusted', field.key)} />
<span>{field.label}</span> <span>{field.label}</span>
</label> </label>
{/each} {/each}
@@ -217,13 +246,14 @@
<!-- Administrator note --> <!-- Administrator note -->
<p class="text-xs text-gray-400 italic"> <p class="text-xs text-gray-400 italic">
Administrators always have access to all fields (not configurable). Administrators always have access to all fields (not
configurable).
</p> </p>
</div> </div>
</details> </details>
{/if} <!-- end {#if mod_badges_json} --> {/if}
<!-- end {#if mod_badges_json} -->
<button type="button" class="btn preset-tonal-primary" onclick={save} <button type="button" class="btn preset-tonal-primary" onclick={save}
>Save</button >Save</button>
>
</div> </div>

View File

@@ -1,16 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { key_val } from '$lib/stores/ae_stores'; import type { key_val } from '$lib/stores/ae_stores';
interface Props { interface Props {
event_obj: key_val; event_obj: key_val;
onsave?: (data: key_val) => void; onsave?: (data: key_val) => void;
} }
let { event_obj = $bindable(), onsave }: Props = $props(); let { event_obj = $bindable(), onsave }: Props = $props();
function save() { function save() {
if (onsave) onsave(event_obj); if (onsave) onsave(event_obj);
} }
</script> </script>
<div class="space-y-4"> <div class="space-y-4">
@@ -31,8 +31,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={event_obj.conference} bind:checked={event_obj.conference} />
/>
<span>Conference</span> <span>Conference</span>
</label> </label>
</div> </div>
@@ -62,8 +61,7 @@
<input <input
type="datetime-local" type="datetime-local"
class="input" class="input"
bind:value={event_obj.start_datetime} bind:value={event_obj.start_datetime} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -72,8 +70,7 @@
<input <input
type="datetime-local" type="datetime-local"
class="input" class="input"
bind:value={event_obj.end_datetime} bind:value={event_obj.end_datetime} />
/>
</label> </label>
</div> </div>
<div> <div>
@@ -83,6 +80,5 @@
</label> </label>
</div> </div>
<button type="button" class="btn preset-tonal-primary" onclick={save} <button type="button" class="btn preset-tonal-primary" onclick={save}
>Save</button >Save</button>
>
</div> </div>

View File

@@ -1,16 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { key_val } from '$lib/stores/ae_stores'; import type { key_val } from '$lib/stores/ae_stores';
interface Props { interface Props {
cfg_json: key_val | null | undefined; cfg_json: key_val | null | undefined;
onsave?: (data: key_val) => void; onsave?: (data: key_val) => void;
} }
let { cfg_json = $bindable({}), onsave }: Props = $props(); let { cfg_json = $bindable({}), onsave }: Props = $props();
function save() { function save() {
if (onsave && cfg_json) onsave(cfg_json); if (onsave && cfg_json) onsave(cfg_json);
} }
</script> </script>
<div class="space-y-4"> <div class="space-y-4">
@@ -18,17 +18,22 @@
<div> <div>
<label class="label"> <label class="label">
<span>Short Name</span> <span>Short Name</span>
<input type="text" class="input" bind:value={cfg_json.short_name} /> <input
type="text"
class="input"
bind:value={cfg_json.short_name} />
</label> </label>
</div> </div>
<div> <div>
<label class="label"> <label class="label">
<span>Medium Name</span> <span>Medium Name</span>
<input type="text" class="input" bind:value={cfg_json.med_name} /> <input
type="text"
class="input"
bind:value={cfg_json.med_name} />
</label> </label>
</div> </div>
{/if} {/if}
<button type="button" class="btn preset-tonal-primary" onclick={save} <button type="button" class="btn preset-tonal-primary" onclick={save}
>Save</button >Save</button>
>
</div> </div>

View File

@@ -1,16 +1,16 @@
<script lang="ts"> <script lang="ts">
import type { key_val } from '$lib/stores/ae_stores'; import type { key_val } from '$lib/stores/ae_stores';
interface Props { interface Props {
mod_pres_mgmt_json: key_val | null | undefined; mod_pres_mgmt_json: key_val | null | undefined;
onsave?: (data: key_val) => void; onsave?: (data: key_val) => void;
} }
let { mod_pres_mgmt_json = $bindable({}), onsave }: Props = $props(); let { mod_pres_mgmt_json = $bindable({}), onsave }: Props = $props();
function save() { function save() {
if (onsave && mod_pres_mgmt_json) onsave(mod_pres_mgmt_json); if (onsave && mod_pres_mgmt_json) onsave(mod_pres_mgmt_json);
} }
</script> </script>
<div class="space-y-4"> <div class="space-y-4">
@@ -21,8 +21,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.lock_config} bind:checked={mod_pres_mgmt_json.lock_config} />
/>
<span>Lock Config</span> <span>Lock Config</span>
</label> </label>
</div> </div>
@@ -31,8 +30,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.hide__location_code} bind:checked={mod_pres_mgmt_json.hide__location_code} />
/>
<span>Hide Location Code</span> <span>Hide Location Code</span>
</label> </label>
</div> </div>
@@ -41,8 +39,9 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.hide__presentation_code} bind:checked={
/> mod_pres_mgmt_json.hide__presentation_code
} />
<span>Hide Presentation Code</span> <span>Hide Presentation Code</span>
</label> </label>
</div> </div>
@@ -51,8 +50,9 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.hide__presenter_code} bind:checked={
/> mod_pres_mgmt_json.hide__presenter_code
} />
<span>Hide Presenter Code</span> <span>Hide Presenter Code</span>
</label> </label>
</div> </div>
@@ -61,8 +61,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.hide__session_code} bind:checked={mod_pres_mgmt_json.hide__session_code} />
/>
<span>Hide Session Code</span> <span>Hide Session Code</span>
</label> </label>
</div> </div>
@@ -71,8 +70,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.limit__navigation} bind:checked={mod_pres_mgmt_json.limit__navigation} />
/>
<span>Limit Navigation</span> <span>Limit Navigation</span>
</label> </label>
</div> </div>
@@ -81,8 +79,7 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.limit__options} bind:checked={mod_pres_mgmt_json.limit__options} />
/>
<span>Limit Options</span> <span>Limit Options</span>
</label> </label>
</div> </div>
@@ -91,8 +88,9 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.require__presenter_agree} bind:checked={
/> mod_pres_mgmt_json.require__presenter_agree
} />
<span>Require Presenter Agreement</span> <span>Require Presenter Agreement</span>
</label> </label>
</div> </div>
@@ -101,8 +99,9 @@
<input <input
type="checkbox" type="checkbox"
class="checkbox" class="checkbox"
bind:checked={mod_pres_mgmt_json.require__session_agree} bind:checked={
/> mod_pres_mgmt_json.require__session_agree
} />
<span>Require Session Agreement</span> <span>Require Session Agreement</span>
</label> </label>
</div> </div>
@@ -115,8 +114,9 @@
<input <input
type="text" type="text"
class="input" class="input"
bind:value={mod_pres_mgmt_json.label__person_external_id} bind:value={
/> mod_pres_mgmt_json.label__person_external_id
} />
</label> </label>
</div> </div>
<div> <div>
@@ -125,8 +125,9 @@
<input <input
type="text" type="text"
class="input" class="input"
bind:value={mod_pres_mgmt_json.label__session_poc_type} bind:value={
/> mod_pres_mgmt_json.label__session_poc_type
} />
</label> </label>
</div> </div>
<div> <div>
@@ -135,14 +136,14 @@
<input <input
type="text" type="text"
class="input" class="input"
bind:value={mod_pres_mgmt_json.label__session_poc_name} bind:value={
/> mod_pres_mgmt_json.label__session_poc_name
} />
</label> </label>
</div> </div>
</div> </div>
{/if} {/if}
<button type="button" class="btn preset-tonal-primary" onclick={save} <button type="button" class="btn preset-tonal-primary" onclick={save}
>Save</button >Save</button>
>
</div> </div>

View File

@@ -1,202 +1,201 @@
<script lang="ts"> <script lang="ts">
interface Props { interface Props {
// /** @type {import('./$types').PageData} */ // /** @type {import('./$types').PageData} */
data: any; data: any;
event_session_id: string; event_session_id: string;
lq__event_session_obj: any; lq__event_session_obj: any;
lq__auth__event_presenter_obj: any; lq__auth__event_presenter_obj: any;
} }
let { let {
data, data,
event_session_id, event_session_id,
lq__event_session_obj, lq__event_session_obj,
lq__auth__event_presenter_obj lq__auth__event_presenter_obj
}: Props = $props(); }: Props = $props();
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { import {
ae_snip, ae_snip,
ae_loc, ae_loc,
ae_sess, ae_sess,
ae_api, ae_api,
ae_trig, ae_trig,
slct, slct,
slct_trigger slct_trigger
} from '$lib/stores/ae_stores'; } from '$lib/stores/ae_stores';
import { import {
events_loc, events_loc,
events_sess, events_sess,
events_slct, events_slct,
events_trigger, events_trigger,
events_trig_kv events_trig_kv
} from '$lib/stores/ae_events_stores'; } from '$lib/stores/ae_events_stores';
import { LogIn, X } from '@lucide/svelte'; import { LogIn, X } from '@lucide/svelte';
onMount(() => { onMount(() => {
console.log('Browser environment detected.'); console.log('Browser environment detected.');
console.log(
`lq__auth__event_presenter_obj = `,
$lq__auth__event_presenter_obj
);
let url_person_id = data.url.searchParams.get('person_id');
let url_person_pass = data.url.searchParams.get('person_pass');
let url_presentation_id = data.url.searchParams.get('presentation_id');
let url_presenter_id = data.url.searchParams.get('presenter_id');
let url_session_id = data.url.searchParams.get('session_id');
// This should be turned into a function to correctly authenticate the person and allow them access to their presentations and presenter details.
if (url_person_pass) {
console.log( console.log(
`lq__auth__event_presenter_obj = `, `ae_events_pres_mgmt session [slug] +page.svelte: event_session_id=${$events_slct.event_session_id}; person_id=${url_person_id}; person_pass=${url_person_pass}; presentation_id=${url_presentation_id}; presenter_id=${url_presenter_id}`
$lq__auth__event_presenter_obj
); );
let url_person_id = data.url.searchParams.get('person_id'); // Using temporary session values first.
let url_person_pass = data.url.searchParams.get('person_pass'); $events_sess.auth__entered_key = url_person_id;
let url_presentation_id = data.url.searchParams.get('presentation_id'); $events_sess.auth__entered_passcode = url_person_pass;
let url_presenter_id = data.url.searchParams.get('presenter_id');
let url_session_id = data.url.searchParams.get('session_id');
// This should be turned into a function to correctly authenticate the person and allow them access to their presentations and presenter details. $events_sess.auth__person.id = url_person_id;
if (url_person_pass) { $events_sess.auth__person.presentation_id = url_presentation_id;
console.log( $events_sess.auth__person.presenter_id = url_presenter_id;
`ae_events_pres_mgmt session [slug] +page.svelte: event_session_id=${$events_slct.event_session_id}; person_id=${url_person_id}; person_pass=${url_person_pass}; presentation_id=${url_presentation_id}; presenter_id=${url_presenter_id}` $events_sess.auth__person.session_id = url_session_id; // For POC or LCI Champions for sessions. Do not set for a presenter!
);
// Using temporary session values first. $events_sess.auth__kv.person[url_person_id] = true;
$events_sess.auth__entered_key = url_person_id; $events_sess.auth__kv.session[url_session_id] = true; // For POC or LCI Champions for sessions. Do not set for a presenter!
$events_sess.auth__entered_passcode = url_person_pass; $events_sess.auth__kv.presentation[url_presentation_id] = true;
$events_sess.auth__kv.presenter[url_presenter_id] = true;
$events_sess.auth__person.id = url_person_id; // We need to set the selected presentation and presenter objects based on the respective IDs.
$events_sess.auth__person.presentation_id = url_presentation_id; if (url_session_id) {
$events_sess.auth__person.presenter_id = url_presenter_id; $events_slct.auth__event_session_id = url_session_id;
$events_sess.auth__person.session_id = url_session_id; // For POC or LCI Champions for sessions. Do not set for a presenter! }
if (url_presentation_id && url_presenter_id) {
$events_sess.auth__kv.person[url_person_id] = true; $events_slct.auth__event_presentation_id = url_presentation_id;
$events_sess.auth__kv.session[url_session_id] = true; // For POC or LCI Champions for sessions. Do not set for a presenter! $events_slct.auth__event_presenter_id = url_presenter_id;
$events_sess.auth__kv.presentation[url_presentation_id] = true;
$events_sess.auth__kv.presenter[url_presenter_id] = true;
// We need to set the selected presentation and presenter objects based on the respective IDs.
if (url_session_id) {
$events_slct.auth__event_session_id = url_session_id;
}
if (url_presentation_id && url_presenter_id) {
$events_slct.auth__event_presentation_id = url_presentation_id;
$events_slct.auth__event_presenter_id = url_presenter_id;
}
if (url_presenter_id) {
presenter_sign_in();
}
if (url_session_id) {
session_sign_in();
}
console.log('Remove the sign in fields from the URL.');
data.url.searchParams.delete('person_id');
data.url.searchParams.delete('person_pass');
data.url.searchParams.delete('presentation_id');
data.url.searchParams.delete('presenter_id');
data.url.searchParams.delete('session_id');
let new_url = data.url.toString();
console.log(new_url);
// We need to set browser history and force all load functions to rerun.
goto(new_url, { replaceState: true, invalidateAll: true });
} }
});
// For session point of contact (moderator, chair, LCI Champions). if (url_presenter_id) {
function session_sign_in() { presenter_sign_in();
console.log('Session sign in with URL values'); }
$ae_loc.access_type = 'public'; // Just below trusted access used by staff. if (url_session_id) {
// $ae_loc.administrator_access = false; session_sign_in();
// $ae_loc.trusted_access = false; }
$ae_loc.public_access = true;
$ae_loc.authenticated_access = true;
$events_loc.auth__person.id = $events_sess.auth__person.id; // person_id console.log('Remove the sign in fields from the URL.');
$events_loc.auth__person.person_id = $events_sess.auth__person.id; data.url.searchParams.delete('person_id');
$events_loc.auth__person.entered_key = $events_sess.auth__entered_key; // need to verify entered_key... data.url.searchParams.delete('person_pass');
data.url.searchParams.delete('presentation_id');
data.url.searchParams.delete('presenter_id');
data.url.searchParams.delete('session_id');
$events_loc.auth__kv.person[$events_sess.auth__person.person_id] = true; let new_url = data.url.toString();
$events_loc.auth__kv.session[$events_sess.auth__person.session_id] = console.log(new_url);
true;
$events_loc.auth__kv.presentation[
$events_sess.auth__person.presentation_id
] = false; // Set to false for session POC (LCI Champions).
$events_loc.auth__kv.presenter[$events_sess.auth__person.presenter_id] =
false; // Set to false for session POC (LCI Champions).
// Setting again here... just because for now. // We need to set browser history and force all load functions to rerun.
// $events_slct.event_presentation_id = $events_sess.auth__person.presentation_id; goto(new_url, { replaceState: true, invalidateAll: true });
// $events_slct.event_presenter_id = $events_sess.auth__person.presenter_id;
} }
});
// For presenters within a session presentation. // For session point of contact (moderator, chair, LCI Champions).
function presenter_sign_in() { function session_sign_in() {
console.log('Presenter sign in with URL values'); console.log('Session sign in with URL values');
console.log(event_session_id); $ae_loc.access_type = 'public'; // Just below trusted access used by staff.
// $ae_loc.administrator_access = false;
// $ae_loc.trusted_access = false;
$ae_loc.public_access = true;
$ae_loc.authenticated_access = true;
$ae_loc.access_type = 'authenticated'; // Just below public access used for the session POC. $events_loc.auth__person.id = $events_sess.auth__person.id; // person_id
// $ae_loc.administrator_access = false; $events_loc.auth__person.person_id = $events_sess.auth__person.id;
// $ae_loc.trusted_access = false; $events_loc.auth__person.entered_key = $events_sess.auth__entered_key; // need to verify entered_key...
$ae_loc.public_access = false;
$ae_loc.authenticated_access = true;
$ae_loc.person_id = $events_sess.auth__person.id; $events_loc.auth__kv.person[$events_sess.auth__person.person_id] = true;
$events_loc.auth__kv.session[$events_sess.auth__person.session_id] = true;
$events_loc.auth__kv.presentation[
$events_sess.auth__person.presentation_id
] = false; // Set to false for session POC (LCI Champions).
$events_loc.auth__kv.presenter[$events_sess.auth__person.presenter_id] =
false; // Set to false for session POC (LCI Champions).
$events_loc.auth__person.id = $events_sess.auth__person.id; // person_id // Setting again here... just because for now.
$events_loc.auth__person.person_id = $events_sess.auth__person.id; // $events_slct.event_presentation_id = $events_sess.auth__person.presentation_id;
// $events_loc.auth__person.entered_key = $events_sess.auth__entered_key; // also person_id in this case // $events_slct.event_presenter_id = $events_sess.auth__person.presenter_id;
// $lq__auth__event_presenter_obj.full_name }
// $events_loc.auth__person.email = 'test@example.com';
// $events_loc.auth__person.full_name = 'Test Person';
$events_loc.auth__person.presenter_id =
$events_sess.auth__person.presenter_id;
$events_loc.auth__kv.person[$events_sess.auth__person.person_id] = true; // For presenters within a session presentation.
// $events_loc.auth__kv.session[$events_sess.auth__person.session_id] = 'read'; // Set to 'read' for presenters. function presenter_sign_in() {
$events_loc.auth__kv.session[event_session_id] = 'read'; // Set to 'read' for presenters. console.log('Presenter sign in with URL values');
$events_loc.auth__kv.presentation[
$events_sess.auth__person.presentation_id
] = true; // true implies read/write access
$events_loc.auth__kv.presenter[$events_sess.auth__person.presenter_id] =
true; // true implies read/write access
// Setting again here... just because for now. console.log(event_session_id);
// $events_slct.auth__event_presentation_id = $events_sess.auth__person.presentation_id;
// $events_slct.auth__event_presenter_id = $events_sess.auth__person.presenter_id;
$events_loc.auth__person.presentation_id = $ae_loc.access_type = 'authenticated'; // Just below public access used for the session POC.
$events_sess.auth__person.presentation_id; // $ae_loc.administrator_access = false;
$events_loc.auth__person.presenter_id = // $ae_loc.trusted_access = false;
$events_sess.auth__person.presenter_id; $ae_loc.public_access = false;
} $ae_loc.authenticated_access = true;
function sign_out() { $ae_loc.person_id = $events_sess.auth__person.id;
$ae_loc.authenticated_access = false;
$ae_loc.access_type = 'anonymous';
$events_loc.auth__person = { $events_loc.auth__person.id = $events_sess.auth__person.id; // person_id
id: null, $events_loc.auth__person.person_id = $events_sess.auth__person.id;
email: null, // $events_loc.auth__person.entered_key = $events_sess.auth__entered_key; // also person_id in this case
full_name: null, // $lq__auth__event_presenter_obj.full_name
entered_key: null, // $events_loc.auth__person.email = 'test@example.com';
entered_passcode: null, // $events_loc.auth__person.full_name = 'Test Person';
person_id: null, $events_loc.auth__person.presenter_id =
presenter_id: null, $events_sess.auth__person.presenter_id;
presentation_id: null,
session_id: null
};
$events_loc.auth__kv = {
event: {},
session: {},
presentation: {},
presenter: {},
person: {}
};
$events_sess.auth__person.presenter_id = null; $events_loc.auth__kv.person[$events_sess.auth__person.person_id] = true;
// $events_sess.auth__person.presentation_id = null; // $events_loc.auth__kv.session[$events_sess.auth__person.session_id] = 'read'; // Set to 'read' for presenters.
$events_sess.auth__person.session_id = null; $events_loc.auth__kv.session[event_session_id] = 'read'; // Set to 'read' for presenters.
} $events_loc.auth__kv.presentation[
$events_sess.auth__person.presentation_id
] = true; // true implies read/write access
$events_loc.auth__kv.presenter[$events_sess.auth__person.presenter_id] =
true; // true implies read/write access
// Setting again here... just because for now.
// $events_slct.auth__event_presentation_id = $events_sess.auth__person.presentation_id;
// $events_slct.auth__event_presenter_id = $events_sess.auth__person.presenter_id;
$events_loc.auth__person.presentation_id =
$events_sess.auth__person.presentation_id;
$events_loc.auth__person.presenter_id =
$events_sess.auth__person.presenter_id;
}
function sign_out() {
$ae_loc.authenticated_access = false;
$ae_loc.access_type = 'anonymous';
$events_loc.auth__person = {
id: null,
email: null,
full_name: null,
entered_key: null,
entered_passcode: null,
person_id: null,
presenter_id: null,
presentation_id: null,
session_id: null
};
$events_loc.auth__kv = {
event: {},
session: {},
presentation: {},
presenter: {},
person: {}
};
$events_sess.auth__person.presenter_id = null;
// $events_sess.auth__person.presentation_id = null;
$events_sess.auth__person.session_id = null;
}
</script> </script>
<span> <span>
@@ -207,9 +206,8 @@
onclick={() => { onclick={() => {
sign_out(); sign_out();
alert('You have been signed out.'); alert('You have been signed out.');
}} }}>
> <X size="1em" class="mx-1 inline" />
<X size="1em" class="inline mx-1" />
Sign Out Sign Out
{$lq__auth__event_presenter_obj?.given_name {$lq__auth__event_presenter_obj?.given_name
? `- ${$lq__auth__event_presenter_obj?.given_name}` ? `- ${$lq__auth__event_presenter_obj?.given_name}`
@@ -217,8 +215,7 @@
</button> </button>
{:else if $events_sess.auth__person.presenter_id || $events_sess.auth__person.session_id} {:else if $events_sess.auth__person.presenter_id || $events_sess.auth__person.session_id}
<div <div
class="border border-gray-200 p-2 rounded-md m-2 text-center space-y-2" class="m-2 space-y-2 rounded-md border border-gray-200 p-2 text-center">
>
<div class="text-sm text-gray-500"> <div class="text-sm text-gray-500">
Use the link that was sent to your email address to sign in or Use the link that was sent to your email address to sign in or
enter your key and passcode to sign in. enter your key and passcode to sign in.
@@ -230,19 +227,21 @@
placeholder="Key" placeholder="Key"
value={$events_sess.auth__entered_key ?? ''} value={$events_sess.auth__entered_key ?? ''}
oninput={(e) => oninput={(e) =>
($events_sess.auth__entered_key = (e.target as HTMLInputElement).value)} ($events_sess.auth__entered_key = (
/> e.target as HTMLInputElement
).value)} />
<input <input
type="text" type="text"
class="input max-w-36" class="input max-w-36"
placeholder="Passcode" placeholder="Passcode"
value={$events_sess.auth__entered_passcode ?? ''} value={$events_sess.auth__entered_passcode ?? ''}
oninput={(e) => oninput={(e) =>
($events_sess.auth__entered_passcode = (e.target as HTMLInputElement).value)} ($events_sess.auth__entered_passcode = (
/> e.target as HTMLInputElement
).value)} />
<button <button
type="button" type="button"
class="btn btn-md preset-tonal-primary border border-primary-500" class="btn btn-md preset-tonal-primary border-primary-500 border"
onclick={() => { onclick={() => {
console.log('Sign in with URL values'); console.log('Sign in with URL values');
@@ -267,9 +266,8 @@
// Setting again here... just because for now. // Setting again here... just because for now.
// $events_slct.event_presentation_id = $events_sess.auth__person.presentation_id; // $events_slct.event_presentation_id = $events_sess.auth__person.presentation_id;
// $events_slct.event_presenter_id = $events_sess.auth__person.presenter_id; // $events_slct.event_presenter_id = $events_sess.auth__person.presenter_id;
}} }}>
> <LogIn size="1em" class="mx-1 inline" />
<LogIn size="1em" class="inline mx-1" />
Sign In Sign In
</button> </button>
</div> </div>