Badges: allow_tracking auto-expands when true; TC modal on info button

This commit is contained in:
Scott Idem
2026-03-12 15:41:32 -04:00
parent 9888374d86
commit f74fc593b0

View File

@@ -22,7 +22,7 @@
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
import { events_func } from '$lib/ae_events_functions';
import { browser } from '$app/environment';
import { Pencil, Check, X, LoaderCircle, ChevronDown, Printer, RotateCcw } from 'lucide-svelte';
import { Pencil, Check, X, LoaderCircle, ChevronDown, Printer, RotateCcw, Info } from 'lucide-svelte';
interface Props {
event_id: string;
@@ -310,6 +310,17 @@
}
});
});
// TC modal ref for the lead scanning terms & conditions dialog
let tc_dialog_ref: HTMLDialogElement | undefined;
// allow_tracking accordion auto-expands to show the checkbox whenever the
// preference is enabled — even with no field being edited — so the current
// state is always visible at a glance. Closes while another field is open.
let allow_tracking_open = $derived(
active_field === 'allow_tracking' ||
(active_field === null && $lq__event_badge_obj?.allow_tracking === true)
);
</script>
<!-- ============================================================
@@ -686,7 +697,7 @@
{#if active_field === 'allow_tracking'}<ChevronDown size="12" />{:else}<Pencil size="12" />{/if}
</button>
</div>
<div class="ctrl-accordion" class:open={active_field === 'allow_tracking'}>
<div class="ctrl-accordion" class:open={allow_tracking_open}>
<div class="ctrl-accordion-inner">
<div id="field-form-allow-tracking" class="px-2 pb-2 pt-1.5 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800">
<label class="flex items-center gap-2 cursor-pointer select-none">
@@ -700,11 +711,44 @@
/>
<span class="text-xs">Allow exhibitor lead scanning</span>
</label>
{@render field_actions(
'allow_tracking',
() => save_field('allow_tracking', { allow_tracking: edit_allow_tracking }),
() => cancel_field('allow_tracking')
)}
<!-- Inline actions — not shared snippet because this field adds a TC info button -->
<div class="flex gap-2 mt-2">
<button
type="button"
class="btn btn-sm flex-1"
class:preset-filled-primary={!field_save_status['allow_tracking'] || field_save_status['allow_tracking'] === 'idle'}
class:preset-filled-success={field_save_status['allow_tracking'] === 'done'}
class:preset-tonal-error={field_save_status['allow_tracking'] === 'error'}
disabled={field_save_status['allow_tracking'] === 'saving'}
onclick={() => save_field('allow_tracking', { allow_tracking: edit_allow_tracking })}
title="Save changes"
aria-label="Save changes"
>
{#if field_save_status['allow_tracking'] === 'saving'}
<LoaderCircle size="14" class="animate-spin mr-1" /> Saving…
{:else if field_save_status['allow_tracking'] === 'done'}
<Check size="14" class="mr-1" /> Saved
{:else if field_save_status['allow_tracking'] === 'error'}
Error — retry
{:else}
<Check size="14" class="mr-1" /> Save
{/if}
</button>
<button
type="button"
class="btn btn-sm preset-tonal-surface"
onclick={() => cancel_field('allow_tracking')}
title="Cancel"
aria-label="Cancel editing"
><X size="14" /></button>
<button
type="button"
class="btn btn-sm preset-tonal-surface shrink-0"
onclick={() => tc_dialog_ref?.showModal()}
title="View lead scanning terms & conditions"
aria-label="View lead scanning terms and conditions"
><Info size="14" /></button>
</div>
</div>
</div>
</div>
@@ -832,6 +876,54 @@
</div>
<!-- ============================================================
Lead scanning Terms & Conditions modal
Native <dialog> (showModal) for accessibility — blocks page,
traps focus, closable via Escape key or the buttons below.
Clicking the backdrop (outside the content box) also closes.
============================================================ -->
<dialog
bind:this={tc_dialog_ref}
class="rounded-xl shadow-2xl p-0 w-full max-w-md bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700"
onclick={(e) => { if (e.target === tc_dialog_ref) tc_dialog_ref?.close(); }}
>
<div class="p-5 max-h-[80vh] overflow-y-auto">
<div class="flex items-start justify-between gap-3 mb-4">
<h2 class="text-base font-semibold leading-snug">
Lead Scanning — Terms &amp; Conditions
</h2>
<button
type="button"
class="btn btn-xs preset-tonal-surface shrink-0 mt-0.5"
onclick={() => tc_dialog_ref?.close()}
aria-label="Close"
><X size="13" /></button>
</div>
<div class="text-sm space-y-3 text-gray-700 dark:text-gray-300">
<p>
By enabling lead scanning on this badge, you agree to the following:
</p>
<ul class="list-disc pl-5 space-y-1.5 text-[13px]">
<li>Exhibitors and sponsors may scan your badge barcode to capture your contact information.</li>
<li>Information collected may include your name, professional title, organization, and location as shown on your badge.</li>
<li>Each exhibitor may use this information to follow up with you after the event for business or promotional purposes.</li>
<li>Every exhibitor is individually responsible for handling your data in compliance with applicable privacy laws (including GDPR and CCPA where applicable).</li>
<li>Disabling this option prevents future scans; it does not erase data already collected by exhibitors prior to the change.</li>
</ul>
<p class="text-[11px] text-gray-500 dark:text-gray-400 border-t border-gray-100 dark:border-gray-800 pt-2 mt-1">
This preference may be updated at any time by event staff at the registration desk.
</p>
</div>
<div class="mt-4 flex justify-end">
<button
type="button"
class="btn btn-sm preset-filled-primary"
onclick={() => tc_dialog_ref?.close()}
>Got it</button>
</div>
</div>
</dialog>
<style>
/* ---- Field card: visual "zoom" (elevation + ring) on the active card ----
box-shadow is used so the effect doesn't affect layout (no reflow).
@@ -923,4 +1015,10 @@
transform: none;
}
}
/* Native <dialog> backdrop — dimmed + blurred overlay */
dialog::backdrop {
background: rgb(0 0 0 / 0.55);
backdrop-filter: blur(3px);
}
</style>