diff --git a/src/lib/ae_events/ae_events__event_person.ts b/src/lib/ae_events/ae_events__event_person.ts new file mode 100644 index 00000000..5fe37495 --- /dev/null +++ b/src/lib/ae_events/ae_events__event_person.ts @@ -0,0 +1,42 @@ +import type { key_val } from '$lib/stores/ae_stores'; +import { api } from '$lib/api/api'; + +const ae_promises: key_val = {}; + +/** + * create_ae_obj__event_person + * Creates a new event_person record linked to an event. + * Used as the first step of manual one-off badge creation. + * The returned event_person_id is then passed to create_ae_obj__event_badge. + */ +export async function create_ae_obj__event_person({ + api_cfg, + event_id, + data_kv, + params = {}, + log_lvl = 0 +}: { + api_cfg: any; + event_id: string; + data_kv: key_val; + params?: key_val; + log_lvl?: number; +}): Promise { + if (log_lvl) { + console.log( + `*** create_ae_obj__event_person() *** event_id=${event_id}` + ); + } + + ae_promises.create__event_person = await api.create_nested_obj({ + api_cfg, + parent_type: 'event', + parent_id: event_id, + child_type: 'event_person', + fields: data_kv, + params, + log_lvl + }); + + return ae_promises.create__event_person; +} diff --git a/src/lib/ae_events/ae_events_functions.ts b/src/lib/ae_events/ae_events_functions.ts index 1242e38b..ab7a991e 100644 --- a/src/lib/ae_events/ae_events_functions.ts +++ b/src/lib/ae_events/ae_events_functions.ts @@ -33,6 +33,8 @@ import * as event_presenter from '$lib/ae_events/ae_events__event_presenter'; import * as event_badge from '$lib/ae_events/ae_events__event_badge'; +import { create_ae_obj__event_person } from '$lib/ae_events/ae_events__event_person'; + import * as event_badge_template from '$lib/ae_events/ae_events__event_badge_template'; const export_obj = { @@ -46,6 +48,9 @@ const export_obj = { update_ae_obj__event: event.update_ae_obj__event, sync_config__event_pres_mgmt: event.sync_config__event_pres_mgmt, + // Event Person + create_ae_obj__event_person: create_ae_obj__event_person, + // Event Badges load_ae_obj_id__event_badge: event_badge.load_ae_obj_id__event_badge, load_ae_obj_li__event_badge: event_badge.load_ae_obj_li__event_badge, diff --git a/src/routes/events/[event_id]/(badges)/badges/+page.svelte b/src/routes/events/[event_id]/(badges)/badges/+page.svelte index 0e7576ab..972a0ce9 100644 --- a/src/routes/events/[event_id]/(badges)/badges/+page.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/+page.svelte @@ -28,8 +28,32 @@ import { events_func } from '$lib/ae_events/ae_events_functions'; import Comp_badge_search from './ae_comp__badge_search.svelte'; import Comp_badge_obj_li from './ae_comp__badge_obj_li.svelte'; +import Comp_badge_create_form from './ae_comp__badge_create_form.svelte'; -import { LoaderCircle } from '@lucide/svelte'; +import { LoaderCircle, UserPlus } from '@lucide/svelte'; + +// Load templates for this event so the create form can show the selector and +// derive badge_type_code_li from whichever template the user picks. +$effect(() => { + const event_id = $events_slct?.event_id; + if (!event_id) return; + events_func.load_ae_obj_li__event_badge_template({ + api_cfg: $ae_api, + event_id, + log_lvl: 0 + }); +}); + +let lq__badge_template_li = $derived( + liveQuery(async () => { + const event_id = $events_slct?.event_id; + if (!event_id) return []; + return await db_events.badge_template + .where('event_id') + .equals(event_id) + .sortBy('name'); + }) +); // *** Initialization & Store Guard *** // Ensure all search fields are initialized to prevent circular undefined triggers if ($events_loc.badges) { @@ -52,6 +76,7 @@ if ($events_loc.badges) { // Variables let show_create_badge_modal: boolean = $state(false); let show_upload_badge_modal: boolean = $state(false); +let create_badge_dialog: HTMLDialogElement | undefined = $state(); let event_badge_id_li: Array = $state([]); let search_debounce_timer: any = null; @@ -362,6 +387,49 @@ async function handle_search_refresh(params: any) { +{#if $ae_loc.edit_mode} +
+ +
+{/if} + + + { if (e.target === create_badge_dialog) { create_badge_dialog?.close(); show_create_badge_modal = false; } }} + onclose={() => { show_create_badge_modal = false; }}> +
+

Create Badge

+
+ {#if show_create_badge_modal} + { + create_badge_dialog?.close(); + show_create_badge_modal = false; + // Trigger a remote-first refresh so the new badge appears in results + $events_loc.badges.search_version = ($events_loc.badges.search_version ?? 0) + 1; + $events_loc.badges.qry__remote_first = true; + }} + oncancel={() => { + create_badge_dialog?.close(); + show_create_badge_modal = false; + }} /> + {/if} +
+ {#if $events_sess?.badges?.search_status === 'loading' && event_badge_id_li.length === 0}
@@ -371,3 +439,13 @@ async function handle_search_refresh(params: any) { {:else} {/if} + + diff --git a/src/routes/events/[event_id]/(badges)/badges/ae_comp__badge_create_form.svelte b/src/routes/events/[event_id]/(badges)/badges/ae_comp__badge_create_form.svelte index f42f68df..d5c51b9d 100644 --- a/src/routes/events/[event_id]/(badges)/badges/ae_comp__badge_create_form.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/ae_comp__badge_create_form.svelte @@ -1,20 +1,38 @@ -
+ +
+ + +
+ + +
+ Badge will show: + {full_name_preview} + + +
+ + {#if show_name_override} + + {/if} + + {#if template_li.length > 1} + + + {/if} - - - - - -
+
+ + + + + + + {#if submit_status === 'error'} +

{error_msg || 'An error occurred. Please try again.'}

+ {/if} + +
+ {#if is_submitting} + + + {step_label} + + {/if}
- -{#if submit_status === 'success'} -

Badge created successfully!

-{:else if submit_status === 'error'} -

Error creating badge. Please try again.

-{/if}