Compare commits
2 Commits
29a24812f4
...
7d2b30b7ce
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d2b30b7ce | ||
|
|
c9b0acfa06 |
@@ -92,23 +92,29 @@ let passcode_checked = $state(false);
|
|||||||
let passcode_valid = $state(false);
|
let passcode_valid = $state(false);
|
||||||
let passcode_error = $state('');
|
let passcode_error = $state('');
|
||||||
|
|
||||||
// Auto-validate URL passcode once badge is loaded
|
// Once the badge loads: grant open access if no passcode is set, or auto-validate URL passcode.
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (url_passcode && $lq__event_badge_obj && !passcode_checked) {
|
const badge = $lq__event_badge_obj;
|
||||||
untrack(() => {
|
if (!badge || passcode_checked) return;
|
||||||
|
untrack(() => {
|
||||||
|
if (!badge.person_passcode) {
|
||||||
|
// No passcode on this badge — open access for attendees
|
||||||
|
passcode_valid = true;
|
||||||
|
passcode_checked = true;
|
||||||
|
} else if (url_passcode) {
|
||||||
check_passcode(url_passcode);
|
check_passcode(url_passcode);
|
||||||
});
|
}
|
||||||
}
|
// else: badge requires a passcode but none in URL — show the entry form
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function check_passcode(code: string) {
|
function check_passcode(code: string) {
|
||||||
passcode_checked = true;
|
passcode_checked = true;
|
||||||
const badge_passcode = $lq__event_badge_obj?.person_passcode;
|
const badge_passcode = $lq__event_badge_obj?.person_passcode;
|
||||||
if (!badge_passcode) {
|
if (!badge_passcode) {
|
||||||
// No passcode set on badge — deny access to prevent unintentional open access
|
// No passcode on badge — open access
|
||||||
passcode_valid = false;
|
passcode_valid = true;
|
||||||
passcode_error =
|
passcode_error = '';
|
||||||
'This badge does not have a review link enabled. Please contact event staff.';
|
|
||||||
} else if (code && code === badge_passcode) {
|
} else if (code && code === badge_passcode) {
|
||||||
passcode_valid = true;
|
passcode_valid = true;
|
||||||
passcode_error = '';
|
passcode_error = '';
|
||||||
@@ -294,8 +300,8 @@ let can_edit_fields: string[] = $derived.by(() => {
|
|||||||
is_staff={has_staff_access}
|
is_staff={has_staff_access}
|
||||||
{log_lvl} />
|
{log_lvl} />
|
||||||
</div>
|
</div>
|
||||||
{:else if !passcode_checked && !url_passcode}
|
{:else if !passcode_checked && !url_passcode && !!$lq__event_badge_obj?.person_passcode}
|
||||||
<!-- Passcode entry (attendee navigates directly, no URL passcode) -->
|
<!-- Passcode entry (badge requires a passcode, attendee navigated directly without one) -->
|
||||||
<div class="card max-w-sm space-y-4 p-6">
|
<div class="card max-w-sm space-y-4 p-6">
|
||||||
<h3 class="text-lg font-semibold">Enter Your Passcode</h3>
|
<h3 class="text-lg font-semibold">Enter Your Passcode</h3>
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500">
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ import {
|
|||||||
// Track per-badge copy state for the "Review Link" clipboard button
|
// Track per-badge copy state for the "Review Link" clipboard button
|
||||||
let copy_status: Record<string, 'idle' | 'copied'> = $state({});
|
let copy_status: Record<string, 'idle' | 'copied'> = $state({});
|
||||||
|
|
||||||
|
// Track which badge has a pending email confirmation (null = none pending)
|
||||||
|
let email_confirm_badge_id: string | null = $state(null);
|
||||||
|
|
||||||
// Access level shortcuts
|
// Access level shortcuts
|
||||||
let is_trusted = $derived($ae_loc.trusted_access === true);
|
let is_trusted = $derived($ae_loc.trusted_access === true);
|
||||||
let is_admin = $derived($ae_loc.administrator_access === true);
|
let is_admin = $derived($ae_loc.administrator_access === true);
|
||||||
@@ -80,8 +83,13 @@ async function copy_review_link(event_badge_obj: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace alert with actual email API call when available
|
// TODO: replace with actual email API call when available
|
||||||
function send_review_email(event_badge_obj: any) {
|
function confirm_send_review_email(event_badge_obj: any) {
|
||||||
|
email_confirm_badge_id = event_badge_obj.event_badge_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_send_review_email(event_badge_obj: any) {
|
||||||
|
email_confirm_badge_id = null;
|
||||||
const name =
|
const name =
|
||||||
event_badge_obj?.full_name_override ??
|
event_badge_obj?.full_name_override ??
|
||||||
event_badge_obj?.full_name ??
|
event_badge_obj?.full_name ??
|
||||||
@@ -404,16 +412,34 @@ let visible_badge_obj_li = $derived(
|
|||||||
|
|
||||||
<!-- 4. Email Review Link: Manager+ always; Administrator + Edit Mode otherwise -->
|
<!-- 4. Email Review Link: Manager+ always; Administrator + Edit Mode otherwise -->
|
||||||
{#if is_admin && (is_edit_mode || is_manager)}
|
{#if is_admin && (is_edit_mode || is_manager)}
|
||||||
<button
|
{#if email_confirm_badge_id === event_badge_obj.event_badge_id}
|
||||||
type="button"
|
<!-- Inline confirmation: shown after clicking Email Link -->
|
||||||
class="hover:text-primary-800-200 hover:bg-primary-200-800 active:bg-surface-200-700 flex items-center gap-1 px-3 py-2 text-base font-bold transition-colors duration-1000 hover:duration-300 min-w-0 preset-tonal-primary rounded-lg border border-primary-200-800"
|
<div class="flex items-center gap-2 px-2 py-1 rounded-lg bg-warning-100 dark:bg-warning-900/30 border border-warning-300 dark:border-warning-700 text-sm">
|
||||||
onclick={() =>
|
<span class="text-warning-800 dark:text-warning-200 font-medium">Send link to {display_name}?</span>
|
||||||
send_review_email(event_badge_obj)}
|
<button
|
||||||
title="Email a review link to {display_name}">
|
type="button"
|
||||||
<Mail size="1em" />
|
class="flex items-center gap-1 px-2 py-1 rounded font-bold preset-filled-warning-500 text-sm"
|
||||||
<span class="hidden sm:inline"
|
onclick={() => do_send_review_email(event_badge_obj)}>
|
||||||
>Email Link</span>
|
<Mail size="0.9em" />
|
||||||
</button>
|
Send
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="flex items-center gap-1 px-2 py-1 rounded font-bold preset-tonal-surface text-sm"
|
||||||
|
onclick={() => { email_confirm_badge_id = null; }}>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="hover:text-primary-800-200 hover:bg-primary-200-800 active:bg-surface-200-700 flex items-center gap-1 px-3 py-2 text-base font-bold transition-colors duration-1000 hover:duration-300 min-w-0 preset-tonal-primary rounded-lg border border-primary-200-800"
|
||||||
|
onclick={() => confirm_send_review_email(event_badge_obj)}
|
||||||
|
title="Email a review link to {display_name}">
|
||||||
|
<Mail size="1em" />
|
||||||
|
<span class="hidden sm:inline">Email Link</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user