feat(badges): implement badge print controls panel and refine badge overrides

- Create ae_comp__badge_print_controls.svelte: A fixed-right-edge panel for per-field accordion controls, font size adjustments, and inline editing.
- Refactor print/+page.svelte to integrate the new controls panel and standardize font size state management via $bindable() props.
- Update ae_comp__badge_obj_view.svelte and ae_comp__badge_review_form.svelte to correctly sync badge_type_code_override and badge_type_override.
- Improve badge_type_name derivation logic to prioritize staff overrides.
- Hide unused receipt/ticket sections in badge view pending future redesign.
- Update documentation (PROJECT and TODO) to reflect completion of Task 3.
This commit is contained in:
Scott Idem
2026-03-02 19:47:11 -05:00
parent 32e9550ca2
commit 5c3823f41a
8 changed files with 873 additions and 167 deletions

View File

@@ -1,15 +1,96 @@
# PROJECT: AE Events Badges — Review Form & Print Font Controls
**Created:** 2026-02-27
**Last Updated:** 2026-02-27
**Last Updated:** 2026-03-02
**Branch:** `ae_app_3x_llm`
**Priority:** HIGH — first live event is Axonius, NYC, mid-April 2026
**Owner:** Scott Idem / One Sky IT
**Status:** ✅ TASK 1 (Badge Review Form) COMPLETE | ✅ TASK 2 (Print Font Controls) COMPLETE — v1
**Status:** ✅ TASK 1 COMPLETE | ✅ TASK 2 COMPLETE | ✅ TASK 3 COMPLETE | ⏳ TASK 4 NEXT UP
---
## Implementation Status (2026-02-27)
## Next Up for Badges (TASK 4)
### 1. QR Code on Badge Front — `ae_comp__badge_obj_view.svelte`
The badge template has a `show_qr` flag (or similar). When toggled on, the QR code should
appear on the front face of the printed badge. Currently QR is only shown on the review form.
- Check the badge template fields for the QR toggle field name (`show_qr`, `qr_enabled`, etc.)
via `ae_describe event_badge_template` and inspect `ae_comp__badge_obj_view.svelte`.
- The QR code data URL is generated with:
```typescript
qr_data_url = await core_func.js_generate_qr_code('obj', {
obj_type: 'event_badge',
obj_id: event_badge_id
});
```
See `ae_comp__badge_review_form.svelte` for the working pattern.
- Position on badge: typically bottom-right corner of the badge face, sized to fit within
the template's layout constraints. Do NOT alter structural badge dimensions.
- Must be hidden on `ae_comp__badge_obj_view.svelte` when `show_qr` is falsy.
### 2. Badge Print Controls — UX Improvements (ae_comp__badge_print_controls.svelte)
- Scott has identified areas for improvement — TBD next session
- Consider: keyboard shortcuts (+ / -) for font sizing while a field is active
- Consider: "Apply to all badges" workflow for font size presets
### 3. Leads Module
Next major work after badge polish. See `documentation/MODULE__AE_Events_Leads.md` (if it
exists) for context. Exhibitor lead scanning via QR code.
---
## Implementation Status
### ✅ TASK 3: Badge Print Controls Panel — COMPLETE (2026-03-02)
**Files created/modified:**
- `ae_comp__badge_print_controls.svelte` — NEW. Right-edge control panel with per-field
accordion sections. Font size controls + inline edit forms gated by access level.
- `print/+page.svelte` — layout changed from `flex-row` to fixed right panel.
**Design decisions:**
- Controls panel is `position: fixed right-0 top-20 bottom-0 w-64` — out of normal flow,
always visible regardless of viewport width. `top-20` (80px) clears the page header.
- Badge area gets `pr-64` to prevent content from hiding under the fixed panel.
`print:pr-0` and `print:hidden` on the panel restore a clean print layout.
- `bg-white dark:bg-zinc-900` gives the panel a solid background to prevent bleed-through.
**Per-field accordion structure (one open at a time):**
| Field | Access | Font Controls |
| --- | --- | --- |
| Name | Trusted+ edit | ✅ |
| Professional Title | All auth edit | ✅ |
| Affiliations | All auth edit (textarea) | ✅ |
| Location | All auth edit | ✅ |
| Lead Scanning (allow_tracking) | All auth edit | — |
| Pronouns | Trusted+ edit | — |
| Badge Type | Trusted+, only when template has badge_type_list | — |
**Access level note:**
`is_trusted = $derived($ae_loc.trusted_access === true)` — covers Trusted, Administrator,
Manager, Super (cascade). No need to OR in `administrator_access`.
**badge_type_override coupling:**
When badge type is changed via dropdown, both `badge_type_code_override` AND
`badge_type_override` are saved together (name comes from template list). Same behavior in
`ae_comp__badge_obj_view.svelte` and `ae_comp__badge_review_form.svelte`.
Edge case: custom names (e.g. code=`member`, name=`"Life Member"`) must be set manually in DB.
**Font size config (moved from print page to controls component):**
| Field | Default px | Range | Step |
|--------------|------------|----------|------|
| Name | 58px | 2080px | 2px |
| Title | 34px | 1456px | 2px |
| Affiliations | 38px | 1460px | 2px |
| Location | 34px | 1456px | 2px |
Font sizes flow back to the parent via `$bindable()` props so `ae_comp__badge_obj_view`
stays in sync without prop-drilling through a third component.
---
### ✅ TASK 1: Badge Review Form — COMPLETE
@@ -245,6 +326,13 @@ This allows for rich text formatting (bold, italic, line breaks, etc.) in badge
|---|---|---|
| `email_override` | email input | Fallback display: `email` |
| `badge_type_code_override` | select | Options: member, non-member, guest, exhibitor, staff, test; also updates `badge_type_override` text |
> **Edge case — custom badge type name:** If an attendee needs a standard badge type code (for
> CSS styling) but a slightly different displayed name (e.g. code=`member`, name=`"Life Member"`),
> set `badge_type_override` directly in the DB. Do **not** use the dropdown — selecting from the
> dropdown in the UI overwrites `badge_type_override` with the standard name from the template
> list. This is an intentional trade-off: coded for the normal case (dropdown keeps both fields in
> sync), special cases handled manually by Scott in the DB.
| `registration_type_code_override` | select | Same options as badge_type for now; also updates `registration_type_override` |
| `hide` | checkbox | Label: "Hidden from search results" |
| `priority` | number input | |
@@ -380,7 +468,9 @@ $ae_loc.administrator_access // true = administrator and above
$ae_loc.edit_mode // boolean — user preference toggle (NEVER write to this from components)
```
`is_staff` prop on the review form = `administrator_access || trusted_access`.
`is_staff` prop on the review form = `$ae_loc.trusted_access`.
`trusted_access` is `true` for Trusted and every level above it (Administrator, Manager, Super)
— no need to OR in `administrator_access` since it's already implied by the cascade.
---