diff --git a/documentation/PROJECT__AE_Events_Badges_Review_Print.md b/documentation/PROJECT__AE_Events_Badges_Review_Print.md index dec3f813..efa20530 100644 --- a/documentation/PROJECT__AE_Events_Badges_Review_Print.md +++ b/documentation/PROJECT__AE_Events_Badges_Review_Print.md @@ -110,20 +110,24 @@ Print page edit access needs to be opened to attendee-level permissions, not jus The permission model, field list, and `can_edit()` helper from `ae_comp__badge_review_form.svelte` should be the reference. See Design Intent section above. -### ⏳ TASK 4.1: Auto-Scaling Badge Text v2 — IN PROGRESS (2026-03-12) -**Files created:** -- `src/lib/elements/action_fit_text.ts` — Svelte action: binary-search font scaling with - MutationObserver + ResizeObserver + requestAnimationFrame. -- `src/lib/elements/element_fit_text.svelte` — Component wrapper. Key prop: `height` (required - for binary search to work — without it, offsetHeight == scrollHeight always). -- `src/routes/events/.../ae_comp__badge_obj_view_v2.svelte` — V2 badge render using - Element_fit_text for name/title/affiliations/location in display mode. - `fit_heights` derived object provides layout-aware heights per field per badge layout. - `font_size_*` props default to `undefined` (auto-scale) rather than numeric defaults (v1 behavior). - Manual overrides from print controls still work — any number disables auto-scale for that field. +### ✅ TASK 4.1: Auto-Scaling Badge Text v2 — COMPLETE (2026-03-12) +**Files created/updated:** +- `src/lib/elements/action_fit_text.ts` — Svelte action +- `src/lib/elements/element_fit_text.svelte` — Component wrapper +- `src/routes/events/.../ae_comp__badge_obj_view_v2.svelte` — V2 badge render (canonical) + Debug blocks gated behind `$ae_loc.edit_mode` (hidden in production). +- `print/+page.svelte` — Always uses v2 now. v1/v2 toggle removed. Header redesigned for kiosk UX. +- `ae_comp__badge_print_controls.svelte` — Identity card at top, pronouns moved to attendee section, + "Staff adjustments" divider before badge_type field. +- `print_list/+page.svelte` — Updated to import v2. +- `ae_comp__badge_obj_view.svelte` (v1) — **Moved to ~/tmp/gemini_trash/** -**Toggle:** `v1`/`v2` button in print page header. V1 preserved as fallback. -**Status:** Working — heights in `fit_heights` still need visual tuning with real badge stock. +**Kiosk UX improvements (2026-03-12):** +- Print page header: cleaner, shows name + "Ready"/"Printed N×" status chip, event name. + Header Print Now button removed (duplicate); only Re-print shortcut visible in trusted+edit mode. +- Controls right panel: identity card at top confirms who the badge belongs to before printing. + Pronouns field is now an attendee-level field (was trusted-only). Staff section labelled. +- Debug JSON blocks in v2 badge render hidden behind global edit_mode flag. ### ✅ TASK 3: Badge Print Controls Panel — COMPLETE (2026-03-02) 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 deleted file mode 100644 index 110bc946..00000000 --- a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view.svelte +++ /dev/null @@ -1,1628 +0,0 @@ - - - - - - - - -
- {$lq__event_badge_template_obj?.name ?? '—'} - | - {$lq__event_badge_template_obj?.layout ?? '(no layout)'} -
- - - -
-

Debug Information

-
-    {JSON.stringify($lq__event_badge_obj, null, 2)}
-
- -
-    {JSON.stringify($lq__event_badge_template_obj, null, 2)}
-
-
diff --git a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view_v2.svelte b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view_v2.svelte index bdb28af1..d3d8036d 100644 --- a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view_v2.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_obj_view_v2.svelte @@ -929,21 +929,15 @@ -
+{#if $ae_loc.edit_mode} +

Debug Information

-    {JSON.stringify($lq__event_badge_obj, null, 2)}
-
+ class="whitespace-pre-wrap break-words text-xs max-h-32 overflow-auto p-2 bg-surface-200 border border-surface-300 rounded mt-4" + >{JSON.stringify($lq__event_badge_obj, null, 2)}
-    {JSON.stringify($lq__event_badge_template_obj, null, 2)}
-
+ class="whitespace-pre-wrap break-words text-xs max-h-32 overflow-auto p-2 bg-surface-200 border border-surface-300 rounded mt-4" + >{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 9d87f5ee..8c5a9cf4 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 @@ -319,11 +319,26 @@ Main panel ============================================================ --> - +{#if $lq__event_badge_obj} +
+

Badge Station

+

+ {$lq__event_badge_obj.full_name_override ?? $lq__event_badge_obj.full_name ?? '—'} +

+ {#if badge_type_display} +

{badge_type_display}

+ {/if} +

+ #{$lq__event_badge_obj.event_badge_id} +

+
+{/if} + + + when not yet printed, OR when global AE Edit Mode is active (allows reprints). --> {#if can_print}
+
+ {#if active_field === 'pronouns'} +
+ + + {@render field_actions( + 'pronouns', + () => save_field('pronouns', { pronouns_override: edit_pronouns_override || null }), + () => cancel_field('pronouns') + )} +
+ {/if} +
+ {#if is_trusted} - -
-
-
-

Pronouns

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

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

- {:else} -

Not set — tap ✎ to add

- {/if} -
- -
- {#if active_field === 'pronouns'} -
- - - {@render field_actions( - 'pronouns', - () => save_field('pronouns', { pronouns_override: edit_pronouns_override || null }), - () => cancel_field('pronouns') - )} -
- {/if} + +
+

+ + Staff adjustments + +

diff --git a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/print/+page.svelte b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/print/+page.svelte index 3f7b830b..c2815a2a 100644 --- a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/print/+page.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/print/+page.svelte @@ -16,14 +16,9 @@ import { page } from '$app/state'; import { ArrowLeft, Eye, LoaderCircle, Mail, Printer } from 'lucide-svelte'; - import Comp_badge_obj_view from '../ae_comp__badge_obj_view.svelte'; import Comp_badge_obj_view_v2 from '../ae_comp__badge_obj_view_v2.svelte'; import Comp_badge_print_controls from '../ae_comp__badge_print_controls.svelte'; - // V2 toggle: temporary — lets staff compare auto-scaling text (v2) vs heuristic sizing (v1). - // Remove once v2 is verified and v1 is retired. - let use_v2 = $state(false); - let event_badge_id = $derived(page.params.badge_id); let event_id = $derived(page.params.event_id); @@ -89,11 +84,7 @@ alert(`PLACEHOLDER: An email will be sent to ${name} at ${email}. Use that link to review your ${event_name} badge.`); } - // Print mode: display only — ae_comp__badge_obj_view handles print count + window.print() - // The "Print Now" header button below only triggers window.print() for convenience; - // print count is incremented by the print button inside ae_comp__badge_obj_view. - - // Font size overrides (px). null = auto-sizing from ae_comp__badge_obj_view. + // Font size overrides (px). null = auto-sizing (Element_fit_text binary search). // Controls live in Comp_badge_print_controls (right panel) via $bindable(). // Constants and adjust logic are defined there; only the state lives here so // the values can be forwarded to both the controls and the badge render. @@ -150,10 +141,10 @@ {#if $lq__event_badge_obj && $lq__event_badge_obj.event_id && event_badge_id} - +
- +
-

- {$lq__event_badge_obj.full_name_override ?? $lq__event_badge_obj.full_name ?? '— no name —'} -

- {#if is_printed} -

- Printed {print_count}× - {#if $lq__event_badge_obj.print_last_datetime} - — last {new Date($lq__event_badge_obj.print_last_datetime).toLocaleString()} - {/if} +

+

+ {$lq__event_badge_obj.full_name_override ?? $lq__event_badge_obj.full_name ?? '— no name —'} +

+ {#if is_printed} + + + Printed {print_count}× + + {:else} + Ready + {/if} +
+ {#if $events_loc?.title} +

{$events_loc.title}

+ {:else if is_printed && $lq__event_badge_obj.print_last_datetime} +

+ Last printed {new Date($lq__event_badge_obj.print_last_datetime).toLocaleString()}

{/if}
- +
- - - - - - {#if is_trusted && (!is_printed || is_edit_mode)} + + {#if is_trusted && is_printed && is_edit_mode} {/if} - + {#if is_trusted && is_edit_mode} {/if} - {#if !is_printed || (is_trusted && is_edit_mode)}
- +
- {#if use_v2} - - - {:else} - - {/if} + +