diff --git a/src/routes/events/[event_id]/(badges)/README.md b/src/routes/events/[event_id]/(badges)/README.md index b7b9e4f8..4fcbe4a2 100644 --- a/src/routes/events/[event_id]/(badges)/README.md +++ b/src/routes/events/[event_id]/(badges)/README.md @@ -3,4 +3,4 @@ This directory contains the files for the new Event Badges module (v3). Detailed documentation can be found here: -@documentation/MODULE__AE_Events_Badges.md +@documentation/MODULE\_\_AE_Events_Badges.md diff --git a/src/routes/events/[event_id]/(badges)/badges/+layout.svelte b/src/routes/events/[event_id]/(badges)/badges/+layout.svelte index 8a03d32a..470c5040 100644 --- a/src/routes/events/[event_id]/(badges)/badges/+layout.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/+layout.svelte @@ -1,38 +1,38 @@ - {@render children?.()} diff --git a/src/routes/events/[event_id]/(badges)/badges/+page.svelte b/src/routes/events/[event_id]/(badges)/badges/+page.svelte index 33d03428..0e7576ab 100644 --- a/src/routes/events/[event_id]/(badges)/badges/+page.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/+page.svelte @@ -1,363 +1,351 @@ @@ -376,9 +364,8 @@ {#if $events_sess?.badges?.search_status === 'loading' && event_badge_id_li.length === 0}
- + class="flex flex-col items-center justify-center p-10 text-center opacity-50"> +

Loading badges...

{:else} diff --git a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view.svelte b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view.svelte index 177c980f..a5b7ea8b 100644 --- a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view.svelte @@ -1,363 +1,431 @@ -
- {$lq__event_badge_template_obj?.name ?? '—'} +
+ {$lq__event_badge_template_obj?.name ?? '—'} | - {$lq__event_badge_template_obj?.layout ?? '(no layout)'} + {$lq__event_badge_template_obj?.layout ?? '(no layout)'} | - v3 + v3 {#if $ae_loc.edit_mode} | {/if}
@@ -366,40 +434,36 @@ id="event_badge_{$lq__event_badge_obj?.event_badge_id}" data-layout={$lq__event_badge_template_obj?.layout ?? 'badge_4x6_fanfold'} class="event_badge_wrapper event_badge print_area - flex flex-row flex-wrap gap-4 + mx-auto flex min-h-[6.0in] max-w-[8.5in] + flex-row flex-wrap items-stretch justify-center - p-2 mx-auto - min-h-[6.0in] - max-w-[8.5in] overflow-visible - " -> - + gap-4 + overflow-visible p-2 + "> {#if $lq__event_badge_obj && $lq__event_badge_template_obj}
+ style={demo_bg_style}> + absolute top-1 left-4 text-xs + text-gray-500 italic + transition-all group-hover:text-red-800 + print:hidden + "> {#if show_badge_back}Front of badge{:else}Badge preview{/if} @@ -407,28 +471,25 @@
+ min-h-[.50in] + max-w-full overflow-hidden + p-0 + hover:outline-2 hover:outline-gray-500/75 hover:outline-dashed + "> check header path + alt="check header path" />
{:else}
+ alt="check badge logo" />
{/if} @@ -937,20 +1002,26 @@ {#if $ae_loc.edit_mode} -
-

Debug Information

-
{JSON.stringify($lq__event_badge_obj, null, 2)}
+
+

Debug Information

+
{JSON.stringify(
+                $lq__event_badge_obj,
+                null,
+                2
+            )}
-
{JSON.stringify($lq__event_badge_template_obj, null, 2)}
-
+
{JSON.stringify(
+                $lq__event_badge_template_obj,
+                null,
+                2
+            )}
+
{/if} diff --git a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_print_controls.svelte b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_print_controls.svelte index 66dd58dc..06696884 100644 --- a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_print_controls.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_print_controls.svelte @@ -1,453 +1,625 @@ {#snippet font_ctrl(key: 'name' | 'title' | 'affiliations' | 'location')} {@const cur = - key === 'name' ? font_size_name : - key === 'title' ? font_size_title : - key === 'affiliations' ? font_size_affiliations : font_size_location} -
+ aria-label="{key} font size controls"> Font size for {key}: - + aria-label="Decrease {key} font size">− + {cur !== null ? `${cur}px` : 'Auto'} + aria-label="Increase {key} font size">+ {#if cur !== null} + aria-label="Reset {key} font size to auto">↺ {/if}
{/snippet} @@ -502,10 +677,16 @@ is_dirty: Save uses warning style when changed, invisible when clean. Layout always fixed: [Revert (or gap)] [Save] [X] Buttons are always rendered to keep X pinned at the right end. --> -{#snippet field_actions(field_key: string, on_save: () => void, on_cancel: () => void, on_revert?: () => void, is_dirty = false)} +{#snippet field_actions( + field_key: string, + on_save: () => void, + on_cancel: () => void, + on_revert?: () => void, + is_dirty = false +)} {@const status = field_save_status[field_key]} {@const save_visible = is_dirty || (status && status !== 'idle')} -
+
+ aria-hidden={!on_revert}> + aria-label="Cancel editing">
{/snippet} @@ -567,21 +747,22 @@ Both: Trusted+ only; edit mode allows reprints. --> {#if can_print} -
+
{#if is_printed && print_status === 'idle'} -

+

Already printed {print_count}×

{/if} @@ -616,15 +797,15 @@ {/if}
-
-
- - - {#if field_shown('name')} -
-
-
-

Name

- {#if get_display('full_name_override', 'full_name')} -

{get_display('full_name_override', 'full_name')}

- {:else} -

{field_editable('name') ? 'Tap ✎ to add' : 'Not set'}

- {/if} -
- {#if field_editable('name')} - - {/if} -
- {@render font_ctrl('name')} - -
-
-
- {#if is_global_edit_mode} - - {/if} - - {@render field_actions( - 'name', - () => save_field('name', { full_name_override: edit_full_name_override || null }), - () => cancel_field('name'), - $lq__event_badge_obj?.full_name_override - ? () => save_field('name', { full_name_override: null }) - : undefined, - is_dirty_name - )} -
-
-
-
- {/if} - - - {#if field_shown('title')} -
-
-
-

Title

- {#if get_display('professional_title_override', 'professional_title')} -

{get_display('professional_title_override', 'professional_title')}

- {:else} -

Tap ✎ to add

- {/if} -
- {#if field_editable('title')} - - {/if} -
- {@render font_ctrl('title')} -
-
-
- {#if is_global_edit_mode} - - {/if} - - {@render field_actions( - 'title', - () => save_field('title', { professional_title_override: edit_professional_title_override || null }), - () => cancel_field('title'), - $lq__event_badge_obj?.professional_title_override - ? () => save_field('title', { professional_title_override: null }) - : undefined, - is_dirty_title - )} -
-
-
-
- {/if} - - - {#if field_shown('affiliations')} -
-
-
-

Affiliations

- {#if get_display('affiliations_override', 'affiliations')} -

{get_display('affiliations_override', 'affiliations')}

- {:else} -

Tap ✎ to add

- {/if} -
- {#if field_editable('affiliations')} - - {/if} -
- {@render font_ctrl('affiliations')} -
-
-
- {#if is_global_edit_mode} - - {/if} - - {@render field_actions( - 'affiliations', - () => save_field('affiliations', { affiliations_override: edit_affiliations_override || null }), - () => cancel_field('affiliations'), - $lq__event_badge_obj?.affiliations_override - ? () => save_field('affiliations', { affiliations_override: null }) - : undefined, - is_dirty_affiliations - )} -
-
-
-
- {/if} - - - {#if field_shown('location')} -
-
-
-

Location

- {#if get_display('location_override', 'location')} -

{get_display('location_override', 'location')}

- {:else} -

Tap ✎ to add

- {/if} -
- {#if field_editable('location')} - - {/if} -
- {@render font_ctrl('location')} -
-
-
- {#if is_global_edit_mode} - - {/if} - - {@render field_actions( - 'location', - () => save_field('location', { location_override: edit_location_override || null }), - () => cancel_field('location'), - $lq__event_badge_obj?.location_override - ? () => save_field('location', { location_override: null }) - : undefined, - is_dirty_location - )} -
-
-
-
- {/if} - - - {#if field_shown('allow_tracking')} -
-
-
-

Lead Scanning

-

- {$lq__event_badge_obj?.allow_tracking ? 'Allowed' : 'Not allowed'} -

-
- {#if field_editable('allow_tracking')} - - {/if} -
-
-
-
- - -
- - - +
+ {#if field_editable('name')} + + {/if} +
+ {@render font_ctrl('name')} + +
+
+
+ {#if is_global_edit_mode} + + {/if} + + {@render field_actions( + 'name', + () => + save_field('name', { + full_name_override: + edit_full_name_override || null + }), + () => cancel_field('name'), + $lq__event_badge_obj?.full_name_override + ? () => + save_field('name', { + full_name_override: null + }) + : undefined, + is_dirty_name + )} +
+
-
-
-
- {/if} + {/if} - - {#if field_shown('pronouns')} -
-
-
-

Pronouns

- {#if get_display('pronouns_override', 'pronouns')} -

{get_display('pronouns_override', 'pronouns')}

- {:else} -

Tap ✎ to add

- {/if} -
- {#if field_editable('pronouns')} - - {/if} -
-
-
-
- - {@render field_actions( - 'pronouns', - () => save_field('pronouns', { pronouns_override: edit_pronouns_override || null }), - () => cancel_field('pronouns'), - $lq__event_badge_obj?.pronouns_override - ? () => save_field('pronouns', { pronouns_override: null }) - : undefined, - is_dirty_pronouns - )} + + {#if field_shown('title')} +
+
+
+

Title

+ {#if get_display('professional_title_override', 'professional_title')} +

+ {get_display( + 'professional_title_override', + 'professional_title' + )} +

+ {:else} +

+ Tap ✎ to add +

+ {/if} +
+ {#if field_editable('title')} + + {/if} +
+ {@render font_ctrl('title')} +
+
+
+ {#if is_global_edit_mode} + + {/if} + + {@render field_actions( + 'title', + () => + save_field('title', { + professional_title_override: + edit_professional_title_override || + null + }), + () => cancel_field('title'), + $lq__event_badge_obj?.professional_title_override + ? () => + save_field('title', { + professional_title_override: + null + }) + : undefined, + is_dirty_title + )} +
+
+
-
-
-
- {/if} + {/if} -
-
+ + {#if field_shown('affiliations')} +
+
+
+

Affiliations

+ {#if get_display('affiliations_override', 'affiliations')} +

+ {get_display( + 'affiliations_override', + 'affiliations' + )} +

+ {:else} +

+ Tap ✎ to add +

+ {/if} +
+ {#if field_editable('affiliations')} + + {/if} +
+ {@render font_ctrl('affiliations')} +
+
+
+ {#if is_global_edit_mode} + + {/if} + + {@render field_actions( + 'affiliations', + () => + save_field('affiliations', { + affiliations_override: + edit_affiliations_override || + null + }), + () => cancel_field('affiliations'), + $lq__event_badge_obj?.affiliations_override + ? () => + save_field('affiliations', { + affiliations_override: null + }) + : undefined, + is_dirty_affiliations + )} +
+
+
+
+ {/if} + + + {#if field_shown('location')} +
+
+
+

Location

+ {#if get_display('location_override', 'location')} +

+ {get_display( + 'location_override', + 'location' + )} +

+ {:else} +

+ Tap ✎ to add +

+ {/if} +
+ {#if field_editable('location')} + + {/if} +
+ {@render font_ctrl('location')} +
+
+
+ {#if is_global_edit_mode} + + {/if} + + {@render field_actions( + 'location', + () => + save_field('location', { + location_override: + edit_location_override || null + }), + () => cancel_field('location'), + $lq__event_badge_obj?.location_override + ? () => + save_field('location', { + location_override: null + }) + : undefined, + is_dirty_location + )} +
+
+
+
+ {/if} + + + {#if field_shown('allow_tracking')} +
+
+
+

Lead Scanning

+

+ {$lq__event_badge_obj?.allow_tracking + ? 'Allowed' + : 'Not allowed'} +

+
+ {#if field_editable('allow_tracking')} + + {/if} +
+
+
+
+ + +
+ + + +
+
+
+
+
+ {/if} + + + {#if field_shown('pronouns')} +
+
+
+

Pronouns

+ {#if get_display('pronouns_override', 'pronouns')} +

+ {get_display( + 'pronouns_override', + 'pronouns' + )} +

+ {:else} +

+ Tap ✎ to add +

+ {/if} +
+ {#if field_editable('pronouns')} + + {/if} +
+
+
+
+ + {@render field_actions( + 'pronouns', + () => + save_field('pronouns', { + pronouns_override: + edit_pronouns_override || null + }), + () => cancel_field('pronouns'), + $lq__event_badge_obj?.pronouns_override + ? () => + save_field('pronouns', { + pronouns_override: null + }) + : undefined, + is_dirty_pronouns + )} +
+
+
+
+ {/if} +
+ +
+ {#if is_trusted} -
-
- - -
- -
+
+ +
- -
- -
+ +
+ +
- -
- -
+ +
+ +
- -
- -
+ +
+ +
- -
-

- Print position - saved to browser -

-
- -
- L/R - - {print_offset_x > 0 ? '+' : ''}{print_offset_x.toFixed(1)} mm - -
- -
- U/D - - {print_offset_y > 0 ? '+' : ''}{print_offset_y.toFixed(1)} mm - -
-
- {#if print_offset_x !== 0 || print_offset_y !== 0} - - {/if} -
- - - {#if badge_type_code_li.length > 0} -
-
-
-

Badge Type

- {#if badge_type_display} -

{badge_type_display}

- {:else} -

Tap ✎ to assign

- {/if} -
- -
-
-
-
- - {@render field_actions( - 'badge_type', - () => save_field('badge_type', { - badge_type_code_override: edit_badge_type_code, - // Keep badge_type_override in sync with the name. - // See PROJECT__AE_Events_Badges_Review_Print.md for edge-case notes. - badge_type_override: edit_badge_type_code - ? (badge_type_code_li.find(item => item.code === edit_badge_type_code)?.name ?? edit_badge_type_code) - : null - }), - () => cancel_field('badge_type'), - $lq__event_badge_obj?.badge_type_code_override - ? () => save_field('badge_type', { badge_type_code_override: null, badge_type_override: null }) - : undefined, - is_dirty_badge_type - )} +
+

+ Print position + saved to browser +

+
+ +
+ L/R + + {print_offset_x > 0 + ? '+' + : ''}{print_offset_x.toFixed(1)} mm + +
+ +
+ U/D + + {print_offset_y > 0 + ? '+' + : ''}{print_offset_y.toFixed(1)} mm +
+ {#if print_offset_x !== 0 || print_offset_y !== 0} + + {/if}
+ + + {#if badge_type_code_li.length > 0} +
+
+
+

Badge Type

+ {#if badge_type_display} +

+ {badge_type_display} +

+ {:else} +

+ Tap ✎ to assign +

+ {/if} +
+ +
+
+
+
+ + {@render field_actions( + 'badge_type', + () => + save_field('badge_type', { + badge_type_code_override: + edit_badge_type_code, + // Keep badge_type_override in sync with the name. + // See PROJECT__AE_Events_Badges_Review_Print.md for edge-case notes. + badge_type_override: + edit_badge_type_code + ? (badge_type_code_li.find( + (item) => + item.code === + edit_badge_type_code + )?.name ?? + edit_badge_type_code) + : null + }), + () => cancel_field('badge_type'), + $lq__event_badge_obj?.badge_type_code_override + ? () => + save_field('badge_type', { + badge_type_code_override: + null, + badge_type_override: null + }) + : undefined, + is_dirty_badge_type + )} +
+
+
+
+ {/if}
- {/if} - -
-
- + +
+ {/if} -
{ if (e.target === tc_dialog_ref) tc_dialog_ref?.close(); }} -> -
-
-

+ class="w-full max-w-md rounded-xl border border-gray-200 bg-white p-0 shadow-2xl dark:border-gray-700 dark:bg-gray-900" + onclick={(e) => { + if (e.target === tc_dialog_ref) tc_dialog_ref?.close(); + }}> +
+
+

Lead Scanning — Terms & Conditions

+ aria-label="Close">
-
+

- By enabling lead scanning on this badge, you agree to the following: + By enabling lead scanning on this badge, you agree to the + following:

-
    -
  • Exhibitors and sponsors may scan your badge barcode to capture your contact information.
  • -
  • Information collected may include your name, professional title, organization, and location as shown on your badge.
  • -
  • Each exhibitor may use this information to follow up with you after the event for business or promotional purposes.
  • -
  • Every exhibitor is individually responsible for handling your data in compliance with applicable privacy laws (including GDPR and CCPA where applicable).
  • -
  • Disabling this option prevents future scans; it does not erase data already collected by exhibitors prior to the change.
  • +
      +
    • + Exhibitors and sponsors may scan your badge barcode to + capture your contact information. +
    • +
    • + Information collected may include your name, professional + title, organization, and location as shown on your badge. +
    • +
    • + Each exhibitor may use this information to follow up with + you after the event for business or promotional purposes. +
    • +
    • + Every exhibitor is individually responsible for handling + your data in compliance with applicable privacy laws + (including GDPR and CCPA where applicable). +
    • +
    • + Disabling this option prevents future scans; it does not + erase data already collected by exhibitors prior to the + change. +
    -

    - This preference may be updated at any time by event staff at the registration desk. +

    + This preference may be updated at any time by event staff at the + registration desk.

+ onclick={() => tc_dialog_ref?.close()}>Got it

diff --git a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_review_form.svelte b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_review_form.svelte index edb3a61f..07ac0ceb 100644 --- a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_review_form.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_review_form.svelte @@ -1,450 +1,697 @@ {#if $lq__event_badge_obj} -
- +
-
-
+
+

Badge Review

@@ -455,153 +702,188 @@ class="btn btn-sm preset-tonal-surface preset-outlined-surface-100-900" class:preset-tonal-surface={!txt_enlarge} class:preset-filled-primary={txt_enlarge} - onclick={() => { txt_enlarge = !txt_enlarge; }} - title="{txt_enlarge ? 'Decrease font size' : 'Increase font size'}" - > + onclick={() => { + txt_enlarge = !txt_enlarge; + }} + title={txt_enlarge + ? 'Decrease font size' + : 'Increase font size'}> - {txt_enlarge ? 'Smaller' : 'Larger'} + {txt_enlarge ? 'Smaller' : 'Larger'} {#if can_edit_fields.length > 0} -
- {#if local_edit_active} - - {#if has_changes} - - {/if} + + {#if save_status === 'loading'} + Saving… + {:else if save_status === 'done'} + Saved! + {:else if save_status === 'error'} + Error — try again + {:else} + Save + {/if} + + + {/if} - - {#if save_status !== 'done'} + + {#if save_status !== 'done'} + + {/if} + {:else} + {/if} - {:else} - - - {/if}
{/if}
- {#if ($lq__event_badge_obj.print_count ?? 0) > 0 || $ae_loc.edit_mode} -
-

Print Status

- {#if ($lq__event_badge_obj.print_count ?? 0) === 0} -

Not yet printed

- {:else} -

- Printed {$lq__event_badge_obj.print_count}× - {#if $lq__event_badge_obj.print_first_datetime} - — first: {ae_util.iso_datetime_formatter($lq__event_badge_obj.print_first_datetime, 'datetime_iso_12_no_seconds')} - {/if} - {#if $lq__event_badge_obj.print_last_datetime} - , last: {ae_util.iso_datetime_formatter($lq__event_badge_obj.print_last_datetime, 'datetime_iso_12_no_seconds')} - {/if} -

- {/if} +
+

+ Print Status +

+ {#if ($lq__event_badge_obj.print_count ?? 0) === 0} +

+ Not yet printed +

+ {:else} +

+ Printed {$lq__event_badge_obj.print_count}× + {#if $lq__event_badge_obj.print_first_datetime} + — first: {ae_util.iso_datetime_formatter( + $lq__event_badge_obj.print_first_datetime, + 'datetime_iso_12_no_seconds' + )} + {/if} + {#if $lq__event_badge_obj.print_last_datetime} + , last: {ae_util.iso_datetime_formatter( + $lq__event_badge_obj.print_last_datetime, + 'datetime_iso_12_no_seconds' + )} + {/if} +

+ {/if}
{/if} - - {#if qr_data_url} -
-

Badge QR Code

+
+

+ Badge QR Code +

-

- {qr_expanded ? 'Click QR to collapse' : 'Scan or click to enlarge'} +

+ {qr_expanded + ? 'Click QR to collapse' + : 'Scan or click to enlarge'}

{/if} -
- +
{#if can_edit('pronouns_override') || is_staff} -
-