2 Commits

Author SHA1 Message Date
Scott Idem
deea250a85 fix(badges): add fallback badge_type_code_li when template has no badge_type_list
badge_type_code_li was returning [] when the template had no badge_type_list,
causing the Badge Type field to be hidden entirely in the Staff section.
Add same fallback default as create form and search filter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 18:07:24 -04:00
Scott Idem
4d43fd8a67 fix(badges): move Badge Type field to top of Staff section
Was at the bottom after print position controls — now first item in
Staff Adjustments, before Hide/Unhide Badge, where staff expect it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 18:03:50 -04:00

View File

@@ -269,13 +269,27 @@ async function handle_print_badge() {
// --- Badge type list from template ---
// Each item: { code: string, name: string }. Used for the badge type dropdown.
// Falls back to a default list when the template has no badge_type_list configured.
// Keep in sync with ae_comp__badge_search.svelte and ae_comp__badge_create_form.svelte.
// TODO: drive all three from the template so this is event-agnostic.
const default_badge_type_code_li = [
{ code: 'attendee', name: 'In-Person Attendee' },
{ code: 'sponsor', name: 'Adapt26 Sponsor' },
{ code: 'staff', name: 'Staff' },
{ code: 'guest', name: 'Guest' },
{ code: 'volunteer', name: 'Volunteer' },
{ code: 'member', name: 'Member' },
{ code: 'nonmember', name: 'Non-Member' },
{ code: 'test', name: 'Test' }
];
let badge_type_code_li = $derived.by((): { code: string; name: string }[] => {
const raw = $lq__event_badge_template_obj?.badge_type_list;
if (!raw) return [];
if (!raw) return default_badge_type_code_li;
try {
return JSON.parse(raw);
const parsed = JSON.parse(raw);
return Array.isArray(parsed) && parsed.length > 0 ? parsed : default_badge_type_code_li;
} catch {
return [];
return default_badge_type_code_li;
}
});
@@ -1661,6 +1675,92 @@ let allow_tracking_open = $derived(
<div class="ctrl-accordion" class:open={staff_open}>
<div class="ctrl-accordion-inner space-y-1 pt-0.5">
<!-- === BADGE TYPE === (only when template defines badge_type_list) -->
{#if badge_type_code_li.length > 0}
<div
class="field-card overflow-hidden rounded-lg"
class:field-card--active={active_field === 'badge_type'}>
<div class="flex items-center gap-2 px-2 py-1">
<div class="min-w-0 flex-1">
<p class="field-label">Badge Type</p>
{#if badge_type_display}
<p class="truncate leading-snug">
{badge_type_display}
</p>
{:else}
<p class="text-xs text-gray-400 italic">
Tap ✎ to assign
</p>
{/if}
</div>
<button
type="button"
class="btn btn-xs preset-tonal-primary shrink-0 transition-colors"
onclick={() => toggle_field('badge_type')}
aria-expanded={active_field === 'badge_type'}
aria-controls="field-form-badge-type"
title="Edit badge type"
aria-label="Edit badge type">
{#if active_field === 'badge_type'}<ChevronDown
size="12" />{:else}<Pencil
size="12" />{/if}
</button>
</div>
<div
class="ctrl-accordion"
class:open={active_field === 'badge_type'}>
<div class="ctrl-accordion-inner">
<div
id="field-form-badge-type"
class="border-t border-gray-200 bg-gray-50 px-2 pt-1.5 pb-2 dark:border-gray-700 dark:bg-gray-800">
<select
id="ctrl-badge-type"
name="ctrl-badge-type"
class="select w-full"
bind:this={select_ref_badge_type}
bind:value={edit_badge_type_code}>
<option value={null}
> Select badge type —</option>
{#each badge_type_code_li as item (item.code)}
<option value={item.code}
>{item.name}</option>
{/each}
</select>
{@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
)}
</div>
</div>
</div>
</div>
{/if}
<!-- === HIDE BADGE ===
Removes this badge from search results for all users.
Use for duplicates, test records, or badges that should not be printed.
@@ -1935,92 +2035,6 @@ let allow_tracking_open = $derived(
{/if}
</div>
<!-- === BADGE TYPE === (only when template defines badge_type_list) -->
{#if badge_type_code_li.length > 0}
<div
class="field-card overflow-hidden rounded-lg"
class:field-card--active={active_field ===
'badge_type'}>
<div class="flex items-center gap-2 px-2 py-1">
<div class="min-w-0 flex-1">
<p class="field-label">Badge Type</p>
{#if badge_type_display}
<p class="truncate leading-snug">
{badge_type_display}
</p>
{:else}
<p class="text-xs text-gray-400 italic">
Tap ✎ to assign
</p>
{/if}
</div>
<button
type="button"
class="btn btn-xs preset-tonal-primary shrink-0 transition-colors"
onclick={() => toggle_field('badge_type')}
aria-expanded={active_field === 'badge_type'}
aria-controls="field-form-badge-type"
title="Edit badge type"
aria-label="Edit badge type">
{#if active_field === 'badge_type'}<ChevronDown
size="12" />{:else}<Pencil
size="12" />{/if}
</button>
</div>
<div
class="ctrl-accordion"
class:open={active_field === 'badge_type'}>
<div class="ctrl-accordion-inner">
<div
id="field-form-badge-type"
class="border-t border-gray-200 bg-gray-50 px-2 pt-1.5 pb-2 dark:border-gray-700 dark:bg-gray-800">
<select
id="ctrl-badge-type"
name="ctrl-badge-type"
class="select w-full"
bind:this={select_ref_badge_type}
bind:value={edit_badge_type_code}>
<option value={null}
> Select badge type —</option>
{#each badge_type_code_li as item (item.code)}
<option value={item.code}
>{item.name}</option>
{/each}
</select>
{@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
)}
</div>
</div>
</div>
</div>
{/if}
</div>
<!-- ctrl-accordion-inner staff -->
</div>