refactor(leads): modularize exhibitor leads logic and stub v3 UI
This commit is contained in:
104
documentation/Aether_Events_Exhibitor_Leads_v3_detail.md
Normal file
104
documentation/Aether_Events_Exhibitor_Leads_v3_detail.md
Normal file
@@ -0,0 +1,104 @@
|
||||
Aether Events Exhibitor Leads v3 - Details
|
||||
=======
|
||||
|
||||
## [root page] Leads for Exhibitors Main Landing
|
||||
* Has a search for Exhibits section that allows for searching Exhibits by name or code.
|
||||
* Results can be sortable. They can be sorted by name, booth number, or last created/updated.
|
||||
* This is for exhibitors to find their Exhibit and sign in with the shared passcode or their assigned licensed user credentials.
|
||||
* If not signed in with Administrator Access or above, then only show results for Exhibitors that have been marked as "priority" (paid). Otherwise show all Exhibitors (to admins).
|
||||
* Has a list of Exhibits with basic info and link to Exhibit Leads management page for each Exhibit. Do not show results by default or if less than 3 characters in search and they are not signed in with Trusted Access or above.
|
||||
|
||||
|
||||
## [exhibit_id page] Exhibit Leads Module
|
||||
* This is minimalistic. Only the tabs and content needed.
|
||||
|
||||
### Header/Footer
|
||||
* Overall header/footer should hide by default once signed in. Use Aether iframe mode?
|
||||
* Leads module header should show the Exhibit name and booth number. It should also have a button to toggle the Add Lead tab and Lead List tab. There should also be a button to show the Manage/Config tab for the Exhibit.
|
||||
Header: [Name and Booth # text] [Add Lead / Lead List toggle] [Manage/Config button]
|
||||
|
||||
|
||||
### Tabs:
|
||||
I am probably using the term "tab" loosely here. It may just be sections that show/hide based on buttons or whatever. The main thing is to keep the UI simple and not overwhelm the user with too many options at once. The main flow should be to easily add leads and then view/manage those leads. The Manage/Config tab is more for the person managing the Exhibit and should be separate from the lead capture and management interface.
|
||||
|
||||
1. Start - Sign In / Licenses / Payment
|
||||
2. Add - Search/QR
|
||||
3. Leads - List of Attendee Leads for Exhibitor
|
||||
4. Manage - Leads (app and exhibit) Manage
|
||||
|
||||
|
||||
### [tab 1] Start / Sign In / Payment
|
||||
* Only shows when not signed in as Exhibit Licensed Leads User
|
||||
* Show notification and or message that this is a PWA and can be installed on their device for easier access.
|
||||
|
||||
* Sign in with Exhibit passcode
|
||||
* This will then allow them to Manage the Exhibit License
|
||||
* Sign in with Exhibit Licensed user
|
||||
* This will then allow them to Manage the Exhibit License
|
||||
* Payment - Leads Payment
|
||||
* Not Paid: <span class="fas fa-question text-red-500 m-1"></span> <span class="fas fa-credit-card mx-1"></span> Waiting for payment
|
||||
* Paid: <span class="fas fa-check text-green-500 m-1"></span> <span class="fas fa-credit-card mx-1"></span> Marked as paid
|
||||
* Need to switch to Lucide icons
|
||||
* Sections:
|
||||
* Sign in with Exhibit "shared" passcode
|
||||
* This will then allow them to Manage the Exhibit License
|
||||
* Change to Sign Out once signed in
|
||||
* Once signed in, show message to the Exhibit person. Allow them to select number of Licenses, make a payment, and manage the Licenses if paid.
|
||||
* Sign in with Exhibit Licensed user
|
||||
* This will then allow them to Manage the Exhibit License
|
||||
* Change to Sign Out once signed in
|
||||
* Once signed in, show message to the Leads user. A big button should allow them to then start adding leads.
|
||||
* Payment (Stripe) - Leads Payment
|
||||
* Only show if signed in with Exhibit "shared" passcode and not marked as paid.
|
||||
* Licenses (table):
|
||||
* A client staff (Trusted Access or above) or someone signed in with an Exhibit passcode can add/edit/remove licenses.
|
||||
* License:
|
||||
* full_name
|
||||
* email
|
||||
* passcode
|
||||
* Buttons and Inputs:
|
||||
* Sign in with Exhibit passcode
|
||||
* Sign in with Exhibit Licensed user
|
||||
* Payment - Leads Payment
|
||||
* Add/Edit/Remove Licenses (if signed in with Exhibit passcode or Trusted Access or above)
|
||||
|
||||
### [tab 2] Add - Search/QR
|
||||
* Show only when signed in as Exhibit Licensed Leads User or Trusted Access or above.
|
||||
* Allow for text search of Attendee Badge ID, QR code, name, email, or affiliations.
|
||||
* Allow for QR code scan to add Attendee Badge as Lead.
|
||||
* Once found, show basic Attendee Badge info and button to "Add as Lead".
|
||||
* If already added as Lead, show message and button to "View Lead".
|
||||
* Sections:
|
||||
* Text search
|
||||
* QR scan
|
||||
* Results with "Add as Lead" or "View Lead" button
|
||||
* Buttons and Inputs:
|
||||
* Text input for search
|
||||
* Button to trigger search
|
||||
* Button to trigger QR scan (opens camera and scans QR code on badge)
|
||||
* Button to "Add as Lead" if Attendee Badge found and not already a Lead
|
||||
* Button to "View Lead" if Attendee Badge found and already a Lead
|
||||
|
||||
### [tab 3] Leads - List of Attendee Leads for Exhibitor
|
||||
* Allow for toggle between showing all per Exhibit and per licensed user based on their email address. Not perfect, but works well enough.
|
||||
* Allow for easy edit or remove
|
||||
* Buttons and Inputs:
|
||||
* Button to Export Data - CSV or XLSX
|
||||
* Toggle for show/hide Hidden records
|
||||
* Select options for sorting: Newest added first, Oldest added first, Alpha ascending, Alpha descending, Last updated first
|
||||
|
||||
### [tab 4] Manage - Leads (app and exhibit) Manage
|
||||
* Show list of Leads added for this Exhibit.
|
||||
* Allow for easy edit or remove
|
||||
* Allow for sorting: Newest added first, Oldest added first, Alpha ascending, Alpha descending, Last updated first
|
||||
* Allow for toggle for show/hide Hidden records
|
||||
* Allow for filtering by Licensed user email address
|
||||
* Buttons and Inputs:
|
||||
* Button to Export Data - CSV or XLSX
|
||||
* Toggle for show/hide Hidden records
|
||||
* Select options for sorting: Newest added first, Oldest added first, Alpha ascending, Alpha descending, Last updated first
|
||||
* Filter by Licensed user email address (dropdown of emails that have added leads for this Exhibit)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,16 +17,4 @@ export const editable_fields__event_exhibit = [
|
||||
'sort',
|
||||
'group',
|
||||
'notes'
|
||||
];
|
||||
|
||||
export const editable_fields__event_exhibit_tracking = [
|
||||
'exhibitor_notes',
|
||||
'responses_json',
|
||||
'data_json',
|
||||
'enable',
|
||||
'hide',
|
||||
'priority',
|
||||
'sort',
|
||||
'group',
|
||||
'notes'
|
||||
];
|
||||
];
|
||||
@@ -3,49 +3,10 @@ import { api } from '$lib/api/api';
|
||||
|
||||
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
import type { ae_EventExhibit, ae_EventExhibitTracking } from '$lib/types/ae_types';
|
||||
import type { ae_EventExhibit } from '$lib/types/ae_types';
|
||||
|
||||
const ae_promises: key_val = {};
|
||||
|
||||
// --- PROPERTIES TO SAVE ---
|
||||
export const properties_to_save_exhibit_tracking = [
|
||||
'id',
|
||||
'event_exhibit_tracking_id',
|
||||
'event_exhibit_id',
|
||||
'event_badge_id',
|
||||
'event_person_id',
|
||||
'external_person_id',
|
||||
'exhibitor_notes',
|
||||
'responses_json',
|
||||
'data_json',
|
||||
'event_exhibit_name',
|
||||
'event_badge_title_names',
|
||||
'event_badge_given_name',
|
||||
'event_badge_family_name',
|
||||
'event_badge_designations',
|
||||
'event_badge_full_name',
|
||||
'event_badge_full_name_override',
|
||||
'event_badge_professional_title',
|
||||
'event_badge_professional_title_override',
|
||||
'event_badge_affiliations',
|
||||
'event_badge_affiliations_override',
|
||||
'event_badge_email',
|
||||
'event_badge_email_override',
|
||||
'event_badge_location',
|
||||
'event_badge_location_override',
|
||||
'event_badge_country',
|
||||
'enable',
|
||||
'hide',
|
||||
'priority',
|
||||
'sort',
|
||||
'group',
|
||||
'notes',
|
||||
'created_on',
|
||||
'updated_on',
|
||||
'tmp_sort_1',
|
||||
'tmp_sort_2'
|
||||
];
|
||||
|
||||
// --- PROPERTIES TO SAVE ---
|
||||
export const properties_to_save = [
|
||||
'id',
|
||||
@@ -126,20 +87,6 @@ async function _process_generic_props<T extends Record<string, any>>({
|
||||
return processed_obj_li;
|
||||
}
|
||||
|
||||
export async function process_ae_obj__exhibit_tracking_props({
|
||||
obj_li,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
obj_li: any[];
|
||||
log_lvl?: number;
|
||||
}) {
|
||||
return _process_generic_props({
|
||||
obj_li,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
export async function process_ae_obj__exhibit_props({
|
||||
obj_li,
|
||||
log_lvl = 0
|
||||
@@ -287,334 +234,6 @@ export async function load_ae_obj_li__exhibit({
|
||||
return ae_promises.load__event_exhibit_obj_li || [];
|
||||
}
|
||||
|
||||
// Updated 2026-01-20 to V3
|
||||
export async function load_ae_obj_id__exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_tracking_id,
|
||||
view = 'default',
|
||||
try_cache = false,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_tracking_id: string;
|
||||
view?: string;
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking | null> {
|
||||
try {
|
||||
ae_promises.load__event_exhibit_tracking_obj = await api.get_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
obj_id: exhibit_tracking_id,
|
||||
view,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
if (ae_promises.load__event_exhibit_tracking_obj) {
|
||||
if (try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: [ae_promises.load__event_exhibit_tracking_obj],
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
} else if (try_cache) {
|
||||
ae_promises.load__event_exhibit_tracking_obj = await db_events.exhibit_tracking.get(exhibit_tracking_id);
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (try_cache) {
|
||||
ae_promises.load__event_exhibit_tracking_obj = await db_events.exhibit_tracking.get(exhibit_tracking_id);
|
||||
}
|
||||
}
|
||||
|
||||
return ae_promises.load__event_exhibit_tracking_obj || null;
|
||||
}
|
||||
|
||||
// Updated 2026-01-20 to V3
|
||||
export async function load_ae_obj_li__exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_id,
|
||||
enabled = 'enabled',
|
||||
hidden = 'all',
|
||||
view = 'default',
|
||||
limit = 100,
|
||||
offset = 0,
|
||||
order_by_li = [
|
||||
{ priority: 'DESC' },
|
||||
{ sort: 'DESC' },
|
||||
{ updated_on: 'DESC' }
|
||||
],
|
||||
try_cache = true,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_id: string;
|
||||
enabled?: 'enabled' | 'all' | 'not_enabled';
|
||||
hidden?: 'hidden' | 'all' | 'not_hidden';
|
||||
view?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
order_by_li?: any;
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking[]> {
|
||||
try {
|
||||
ae_promises.load__event_exhibit_tracking_obj_li = await api.get_ae_obj_li_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
for_obj_type: 'event_exhibit',
|
||||
for_obj_id: exhibit_id,
|
||||
enabled,
|
||||
hidden,
|
||||
view,
|
||||
limit,
|
||||
offset,
|
||||
order_by_li,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
if (ae_promises.load__event_exhibit_tracking_obj_li) {
|
||||
if (try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: ae_promises.load__event_exhibit_tracking_obj_li,
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
} else if (try_cache) {
|
||||
ae_promises.load__event_exhibit_tracking_obj_li = await db_events.exhibit_tracking
|
||||
.where('event_exhibit_id').equals(exhibit_id)
|
||||
.toArray();
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (try_cache) {
|
||||
ae_promises.load__event_exhibit_tracking_obj_li = await db_events.exhibit_tracking
|
||||
.where('event_exhibit_id').equals(exhibit_id)
|
||||
.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
return ae_promises.load__event_exhibit_tracking_obj_li || [];
|
||||
}
|
||||
|
||||
// Updated 2026-01-20 to V3
|
||||
export async function create_ae_obj__exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_id,
|
||||
event_badge_id,
|
||||
external_person_id,
|
||||
try_cache = true,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_id: string;
|
||||
event_badge_id: string;
|
||||
external_person_id: string;
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking | null> {
|
||||
const result = await api.create_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
fields: {
|
||||
event_exhibit_id_random: exhibit_id,
|
||||
event_badge_id_random: event_badge_id,
|
||||
external_person_id
|
||||
},
|
||||
log_lvl
|
||||
});
|
||||
|
||||
if (result && try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: [result],
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Updated 2026-01-20 to V3
|
||||
export async function update_ae_obj__exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_tracking_id,
|
||||
data,
|
||||
try_cache = true,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_tracking_id: string;
|
||||
data: any;
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking | null> {
|
||||
const result = await api.update_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
obj_id: exhibit_tracking_id,
|
||||
fields: data,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
if (result && try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: [result],
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function download_export__event_exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_id,
|
||||
file_type = 'CSV',
|
||||
filename = 'exhibit_tracking_export.csv',
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_id: string;
|
||||
file_type?: string;
|
||||
filename?: string;
|
||||
log_lvl?: number;
|
||||
}) {
|
||||
const endpoint = `/event/exhibit/${exhibit_id}/tracking/export`;
|
||||
const params = {
|
||||
file_type,
|
||||
return_file: true
|
||||
};
|
||||
|
||||
return await api.get_object({
|
||||
api_cfg,
|
||||
endpoint,
|
||||
params,
|
||||
return_blob: true,
|
||||
filename,
|
||||
auto_download: true,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
// Updated 2026-01-28 to V3
|
||||
export async function search__exhibit_tracking({
|
||||
api_cfg,
|
||||
event_exhibit_id,
|
||||
fulltext_search_qry_str = null,
|
||||
enabled = 'enabled',
|
||||
hidden = 'all',
|
||||
view = 'default',
|
||||
order_by_li = { created_on: 'DESC' },
|
||||
limit = 100,
|
||||
offset = 0,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
event_exhibit_id: string;
|
||||
fulltext_search_qry_str?: string | null;
|
||||
enabled?: 'enabled' | 'all' | 'not_enabled';
|
||||
hidden?: 'hidden' | 'all' | 'not_hidden';
|
||||
view?: string;
|
||||
order_by_li?: any;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking[]> {
|
||||
if (log_lvl) {
|
||||
console.log(`*** search__exhibit_tracking() *** exhibit_id=${event_exhibit_id} ft=${fulltext_search_qry_str}`);
|
||||
}
|
||||
|
||||
const search_query: any = {
|
||||
q: '',
|
||||
and: []
|
||||
};
|
||||
|
||||
const params: key_val = {};
|
||||
|
||||
if (fulltext_search_qry_str && fulltext_search_qry_str.trim().length > 0) {
|
||||
const qry = fulltext_search_qry_str.trim();
|
||||
// Search across badge name and notes
|
||||
search_query.and.push({ field: 'event_badge_full_name', op: 'like', value: `%${qry}%` });
|
||||
params['lk_qry'] = { event_badge_full_name: qry };
|
||||
}
|
||||
|
||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
||||
|
||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
||||
|
||||
try {
|
||||
const result_get = await api.search_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
for_obj_type: 'event_exhibit',
|
||||
for_obj_id: event_exhibit_id,
|
||||
search_query,
|
||||
params,
|
||||
enabled,
|
||||
hidden,
|
||||
view,
|
||||
order_by_li,
|
||||
limit,
|
||||
offset,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
let result_li: ae_EventExhibitTracking[] = [];
|
||||
if (Array.isArray(result_get)) {
|
||||
result_li = result_get;
|
||||
} else if (result_get?.data && Array.isArray(result_get.data)) {
|
||||
result_li = result_get.data;
|
||||
}
|
||||
|
||||
if (result_li.length > 0) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: result_li,
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
return processed_obj_li;
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('search__exhibit_tracking V3 Request failed.', error);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
// Updated 2026-01-28 to V3
|
||||
export async function search__exhibit({
|
||||
api_cfg,
|
||||
@@ -705,4 +324,4 @@ export async function search__exhibit({
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export const editable_fields__event_exhibit_tracking = [
|
||||
'exhibitor_notes',
|
||||
'responses_json',
|
||||
'data_json',
|
||||
'enable',
|
||||
'hide',
|
||||
'priority',
|
||||
'sort',
|
||||
'group',
|
||||
'notes'
|
||||
];
|
||||
440
src/lib/ae_events/ae_events__exhibit_tracking.ts
Normal file
440
src/lib/ae_events/ae_events__exhibit_tracking.ts
Normal file
@@ -0,0 +1,440 @@
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
import { api } from '$lib/api/api';
|
||||
|
||||
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
import type { ae_EventExhibitTracking } from '$lib/types/ae_types';
|
||||
|
||||
const ae_promises: key_val = {};
|
||||
|
||||
// --- PROPERTIES TO SAVE ---
|
||||
export const properties_to_save_exhibit_tracking = [
|
||||
'id',
|
||||
'event_exhibit_tracking_id',
|
||||
'event_exhibit_id',
|
||||
'event_badge_id',
|
||||
'event_person_id',
|
||||
'external_person_id',
|
||||
'exhibitor_notes',
|
||||
'responses_json',
|
||||
'data_json',
|
||||
'event_exhibit_name',
|
||||
'event_badge_title_names',
|
||||
'event_badge_given_name',
|
||||
'event_badge_family_name',
|
||||
'event_badge_designations',
|
||||
'event_badge_full_name',
|
||||
'event_badge_full_name_override',
|
||||
'event_badge_professional_title',
|
||||
'event_badge_professional_title_override',
|
||||
'event_badge_affiliations',
|
||||
'event_badge_affiliations_override',
|
||||
'event_badge_email',
|
||||
'event_badge_email_override',
|
||||
'event_badge_location',
|
||||
'event_badge_location_override',
|
||||
'event_badge_country',
|
||||
'enable',
|
||||
'hide',
|
||||
'priority',
|
||||
'sort',
|
||||
'group',
|
||||
'notes',
|
||||
'created_on',
|
||||
'updated_on',
|
||||
'tmp_sort_1',
|
||||
'tmp_sort_2'
|
||||
];
|
||||
|
||||
/**
|
||||
* NON-EXPORTED LOCAL HELPER
|
||||
*/
|
||||
async function _process_generic_props<T extends Record<string, any>>({
|
||||
obj_li,
|
||||
obj_type,
|
||||
log_lvl = 0,
|
||||
specific_processor
|
||||
}: {
|
||||
obj_li: T[];
|
||||
obj_type: string;
|
||||
log_lvl?: number;
|
||||
specific_processor?: (obj: T) => Promise<T> | T;
|
||||
}): Promise<T[]> {
|
||||
if (!obj_li || obj_li.length === 0) return [];
|
||||
|
||||
const processed_obj_li: T[] = [];
|
||||
|
||||
for (const original_obj of obj_li) {
|
||||
let processed_obj = { ...original_obj };
|
||||
|
||||
for (const key in processed_obj) {
|
||||
if (key.endsWith('_random')) {
|
||||
const newKey = key.slice(0, -7);
|
||||
(processed_obj as any)[newKey] = processed_obj[key];
|
||||
}
|
||||
}
|
||||
const randomIdKey = `${obj_type}_id_random`;
|
||||
if (processed_obj[randomIdKey]) {
|
||||
(processed_obj as any).id = String(processed_obj[randomIdKey]);
|
||||
}
|
||||
|
||||
const group = processed_obj.group ?? '0';
|
||||
const priority = processed_obj.priority ? 1 : 0;
|
||||
const sort = processed_obj.sort ?? '0';
|
||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||
const name = processed_obj.name ?? '';
|
||||
|
||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
||||
|
||||
if (specific_processor) {
|
||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
||||
}
|
||||
|
||||
processed_obj_li.push(processed_obj as T);
|
||||
}
|
||||
|
||||
return processed_obj_li;
|
||||
}
|
||||
|
||||
export async function process_ae_obj__exhibit_tracking_props({
|
||||
obj_li,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
obj_li: any[];
|
||||
log_lvl?: number;
|
||||
}) {
|
||||
return _process_generic_props({
|
||||
obj_li,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
// Updated 2026-01-20 to V3
|
||||
export async function load_ae_obj_id__exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_tracking_id,
|
||||
view = 'default',
|
||||
try_cache = false,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_tracking_id: string;
|
||||
view?: string;
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking | null> {
|
||||
try {
|
||||
ae_promises.load__event_exhibit_tracking_obj = await api.get_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
obj_id: exhibit_tracking_id,
|
||||
view,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
if (ae_promises.load__event_exhibit_tracking_obj) {
|
||||
if (try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: [ae_promises.load__event_exhibit_tracking_obj],
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
} else if (try_cache) {
|
||||
ae_promises.load__event_exhibit_tracking_obj = await db_events.exhibit_tracking.get(exhibit_tracking_id);
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (try_cache) {
|
||||
ae_promises.load__event_exhibit_tracking_obj = await db_events.exhibit_tracking.get(exhibit_tracking_id);
|
||||
}
|
||||
}
|
||||
|
||||
return ae_promises.load__event_exhibit_tracking_obj || null;
|
||||
}
|
||||
|
||||
// Updated 2026-01-20 to V3
|
||||
export async function load_ae_obj_li__exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_id,
|
||||
enabled = 'enabled',
|
||||
hidden = 'all',
|
||||
view = 'default',
|
||||
limit = 100,
|
||||
offset = 0,
|
||||
order_by_li = [
|
||||
{ priority: 'DESC' },
|
||||
{ sort: 'DESC' },
|
||||
{ updated_on: 'DESC' }
|
||||
],
|
||||
try_cache = true,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_id: string;
|
||||
enabled?: 'enabled' | 'all' | 'not_enabled';
|
||||
hidden?: 'hidden' | 'all' | 'not_hidden';
|
||||
view?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
order_by_li?: any;
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking[]> {
|
||||
try {
|
||||
ae_promises.load__event_exhibit_tracking_obj_li = await api.get_ae_obj_li_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
for_obj_type: 'event_exhibit',
|
||||
for_obj_id: exhibit_id,
|
||||
enabled,
|
||||
hidden,
|
||||
view,
|
||||
limit,
|
||||
offset,
|
||||
order_by_li,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
if (ae_promises.load__event_exhibit_tracking_obj_li) {
|
||||
if (try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: ae_promises.load__event_exhibit_tracking_obj_li,
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
} else if (try_cache) {
|
||||
ae_promises.load__event_exhibit_tracking_obj_li = await db_events.exhibit_tracking
|
||||
.where('event_exhibit_id').equals(exhibit_id)
|
||||
.toArray();
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (try_cache) {
|
||||
ae_promises.load__event_exhibit_tracking_obj_li = await db_events.exhibit_tracking
|
||||
.where('event_exhibit_id').equals(exhibit_id)
|
||||
.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
return ae_promises.load__event_exhibit_tracking_obj_li || [];
|
||||
}
|
||||
|
||||
// Updated 2026-01-20 to V3
|
||||
export async function create_ae_obj__exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_id,
|
||||
event_badge_id,
|
||||
external_person_id,
|
||||
try_cache = true,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_id: string;
|
||||
event_badge_id: string;
|
||||
external_person_id: string;
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking | null> {
|
||||
const result = await api.create_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
fields: {
|
||||
event_exhibit_id_random: exhibit_id,
|
||||
event_badge_id_random: event_badge_id,
|
||||
external_person_id
|
||||
},
|
||||
log_lvl
|
||||
});
|
||||
|
||||
if (result && try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: [result],
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Updated 2026-01-20 to V3
|
||||
export async function update_ae_obj__exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_tracking_id,
|
||||
data,
|
||||
try_cache = true,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_tracking_id: string;
|
||||
data: any;
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking | null> {
|
||||
const result = await api.update_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
obj_id: exhibit_tracking_id,
|
||||
fields: data,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
if (result && try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: [result],
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function download_export__event_exhibit_tracking({
|
||||
api_cfg,
|
||||
exhibit_id,
|
||||
file_type = 'CSV',
|
||||
filename = 'exhibit_tracking_export.csv',
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
exhibit_id: string;
|
||||
file_type?: string;
|
||||
filename?: string;
|
||||
log_lvl?: number;
|
||||
}) {
|
||||
const endpoint = `/event/exhibit/${exhibit_id}/tracking/export`;
|
||||
const params = {
|
||||
file_type,
|
||||
return_file: true
|
||||
};
|
||||
|
||||
return await api.get_object({
|
||||
api_cfg,
|
||||
endpoint,
|
||||
params,
|
||||
return_blob: true,
|
||||
filename,
|
||||
auto_download: true,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
// Updated 2026-01-28 to V3
|
||||
export async function search__exhibit_tracking({
|
||||
api_cfg,
|
||||
event_exhibit_id,
|
||||
fulltext_search_qry_str = null,
|
||||
enabled = 'enabled',
|
||||
hidden = 'all',
|
||||
view = 'default',
|
||||
order_by_li = { created_on: 'DESC' },
|
||||
limit = 100,
|
||||
offset = 0,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any;
|
||||
event_exhibit_id: string;
|
||||
fulltext_search_qry_str?: string | null;
|
||||
enabled?: 'enabled' | 'all' | 'not_enabled';
|
||||
hidden?: 'hidden' | 'all' | 'not_hidden';
|
||||
view?: string;
|
||||
order_by_li?: any;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_EventExhibitTracking[]> {
|
||||
if (log_lvl) {
|
||||
console.log(`*** search__exhibit_tracking() *** exhibit_id=${event_exhibit_id} ft=${fulltext_search_qry_str}`);
|
||||
}
|
||||
|
||||
const search_query: any = {
|
||||
q: '',
|
||||
and: []
|
||||
};
|
||||
|
||||
const params: key_val = {};
|
||||
|
||||
if (fulltext_search_qry_str && fulltext_search_qry_str.trim().length > 0) {
|
||||
const qry = fulltext_search_qry_str.trim();
|
||||
// Search across badge name and notes
|
||||
search_query.and.push({ field: 'event_badge_full_name', op: 'like', value: `%${qry}%` });
|
||||
params['lk_qry'] = { event_badge_full_name: qry };
|
||||
}
|
||||
|
||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
||||
|
||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
||||
|
||||
try {
|
||||
const result_get = await api.search_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'event_exhibit_tracking',
|
||||
for_obj_type: 'event_exhibit',
|
||||
for_obj_id: event_exhibit_id,
|
||||
search_query,
|
||||
params,
|
||||
enabled,
|
||||
hidden,
|
||||
view,
|
||||
order_by_li,
|
||||
limit,
|
||||
offset,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
let result_li: ae_EventExhibitTracking[] = [];
|
||||
if (Array.isArray(result_get)) {
|
||||
result_li = result_get;
|
||||
} else if (result_get?.data && Array.isArray(result_get.data)) {
|
||||
result_li = result_get.data;
|
||||
}
|
||||
|
||||
if (result_li.length > 0) {
|
||||
const processed_obj_li = await process_ae_obj__exhibit_tracking_props({
|
||||
obj_li: result_li,
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_events,
|
||||
table_name: 'exhibit_tracking',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save_exhibit_tracking,
|
||||
log_lvl
|
||||
});
|
||||
return processed_obj_li;
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('search__exhibit_tracking V3 Request failed.', error);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -9,14 +9,17 @@ import * as event_file from '$lib/ae_events/ae_events__event_file';
|
||||
import {
|
||||
load_ae_obj_id__exhibit,
|
||||
load_ae_obj_li__exhibit,
|
||||
search__exhibit,
|
||||
search__exhibit
|
||||
} from '$lib/ae_events/ae_events__exhibit';
|
||||
|
||||
import {
|
||||
search__exhibit_tracking,
|
||||
load_ae_obj_id__exhibit_tracking,
|
||||
load_ae_obj_li__exhibit_tracking,
|
||||
create_ae_obj__exhibit_tracking,
|
||||
update_ae_obj__exhibit_tracking,
|
||||
download_export__event_exhibit_tracking
|
||||
} from '$lib/ae_events/ae_events__exhibit';
|
||||
} from '$lib/ae_events/ae_events__exhibit_tracking';
|
||||
|
||||
import * as event_location from '$lib/ae_events/ae_events__event_location';
|
||||
|
||||
@@ -68,15 +71,15 @@ const export_obj = {
|
||||
update_ae_obj__event_device: event_device.update_ae_obj__event_device,
|
||||
|
||||
// Event Exhibits
|
||||
handle_load_ae_obj_id__exhibit: load_ae_obj_id__exhibit,
|
||||
handle_load_ae_obj_li__exhibit: load_ae_obj_li__exhibit,
|
||||
load_ae_obj_id__exhibit: load_ae_obj_id__exhibit,
|
||||
load_ae_obj_li__exhibit: load_ae_obj_li__exhibit,
|
||||
search__exhibit: search__exhibit,
|
||||
handle_load_ae_obj_id__exhibit_tracking: load_ae_obj_id__exhibit_tracking,
|
||||
handle_load_ae_obj_li__exhibit_tracking: load_ae_obj_li__exhibit_tracking,
|
||||
load_ae_obj_id__exhibit_tracking: load_ae_obj_id__exhibit_tracking,
|
||||
load_ae_obj_li__exhibit_tracking: load_ae_obj_li__exhibit_tracking,
|
||||
search__exhibit_tracking: search__exhibit_tracking,
|
||||
handle_create_ae_obj__exhibit_tracking: create_ae_obj__exhibit_tracking,
|
||||
handle_update_ae_obj__exhibit_tracking: update_ae_obj__exhibit_tracking,
|
||||
handle_download_export__event_exhibit_tracking: download_export__event_exhibit_tracking,
|
||||
create_ae_obj__exhibit_tracking: create_ae_obj__exhibit_tracking,
|
||||
update_ae_obj__exhibit_tracking: update_ae_obj__exhibit_tracking,
|
||||
download_export__event_exhibit_tracking: download_export__event_exhibit_tracking,
|
||||
|
||||
// Event Files
|
||||
load_ae_obj_id__event_file: event_file.load_ae_obj_id__event_file,
|
||||
|
||||
@@ -48,11 +48,11 @@ Represents a single lead captured by an exhibitor. It links an exhibitor to an a
|
||||
|
||||
- `/events/[event_id]/(leads)`: The main entry point for the Leads module within a specific event, typically displays a list of available exhibits.
|
||||
- `+page.svelte`: Renders the list of exhibits.
|
||||
- `+page.ts`: Loads the data for available exhibits using `events_func.handle_load_ae_obj_li__exhibit`.
|
||||
- `+page.ts`: Loads the data for available exhibits using `events_func.load_ae_obj_li__exhibit`.
|
||||
- `+layout.svelte`/`+layout.ts`: Provides a common layout and data for the module, including a submenu.
|
||||
- `/events/[event_id]/(leads)/exhibit/[slug]`: Dynamic route for managing leads for a specific exhibitor within an event. The `[slug]` corresponds to `event_exhibit_id`.
|
||||
- `+page.svelte`: The primary interface for an exhibitor, orchestrating lead capture and management components.
|
||||
- `+page.ts`: Loads specific `Exhibit` data and associated `Exhibit_tracking` (leads) using `events_func.handle_load_ae_obj_id__exhibit` and `events_func.handle_load_ae_obj_li__exhibit_tracking`.
|
||||
- `+page.ts`: Loads specific `Exhibit` data and associated `Exhibit_tracking` (leads) using `events_func.load_ae_obj_id__exhibit` and `events_func.load_ae_obj_li__exhibit_tracking`.
|
||||
|
||||
### Core Components (within `src/routes/events/[event_id]/(leads)/exhibit/[slug]/`)
|
||||
|
||||
|
||||
25
src/routes/events/[event_id]/(leads)/leads/+layout.ts
Normal file
25
src/routes/events/[event_id]/(leads)/leads/+layout.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/+layout.ts
|
||||
* Leads Module Level Layout Loader.
|
||||
*/
|
||||
import { browser } from '$app/environment';
|
||||
import { events_func } from '$lib/ae_events_functions';
|
||||
|
||||
export async function load({ params, parent }) {
|
||||
const parent_data = await parent();
|
||||
const account_id = parent_data.account_id;
|
||||
const ae_acct = parent_data[account_id];
|
||||
const event_id = params.event_id;
|
||||
|
||||
if (browser) {
|
||||
events_func.load_ae_obj_id__event({
|
||||
api_cfg: ae_acct.api,
|
||||
event_id: event_id,
|
||||
log_lvl: 0
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
...parent_data
|
||||
};
|
||||
}
|
||||
25
src/routes/events/[event_id]/(leads)/leads/+page.ts
Normal file
25
src/routes/events/[event_id]/(leads)/leads/+page.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/+page.ts
|
||||
* Exhibit Finder Page Loader.
|
||||
*/
|
||||
import { browser } from '$app/environment';
|
||||
import { events_func } from '$lib/ae_events_functions';
|
||||
|
||||
export async function load({ params, parent }) {
|
||||
const parent_data = await parent();
|
||||
const account_id = parent_data.account_id;
|
||||
const ae_acct = parent_data[account_id];
|
||||
const event_id = params.event_id;
|
||||
|
||||
if (browser && event_id) {
|
||||
events_func.load_ae_obj_li__exhibit({
|
||||
api_cfg: ae_acct.api,
|
||||
for_obj_type: 'event',
|
||||
for_obj_id: event_id,
|
||||
limit: 100,
|
||||
log_lvl: 0
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/+layout.svelte
|
||||
* Exhibitor Dashboard Layout.
|
||||
*/
|
||||
interface Props {
|
||||
children?: import('svelte').Snippet;
|
||||
}
|
||||
|
||||
let { children }: Props = $props();
|
||||
|
||||
import { events_slct } from '$lib/stores/ae_events_stores';
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
|
||||
let lq__exhibit_obj = $derived(
|
||||
liveQuery(async () => {
|
||||
if (!$events_slct.exhibit_id) return null;
|
||||
return await db_events.exhibit.get($events_slct.exhibit_id);
|
||||
})
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="exhibit-layout flex flex-col h-full w-full">
|
||||
{@render children?.()}
|
||||
</div>
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/+layout.ts
|
||||
* Exhibitor Dashboard Loader.
|
||||
*/
|
||||
import { browser } from '$app/environment';
|
||||
import { events_func } from '$lib/ae_events_functions';
|
||||
import { events_slct } from '$lib/stores/ae_events_stores';
|
||||
|
||||
export async function load({ params, parent }) {
|
||||
const parent_data = await parent();
|
||||
const account_id = parent_data.account_id;
|
||||
const ae_acct = parent_data[account_id];
|
||||
const exhibit_id = params.exhibit_id;
|
||||
|
||||
// Sync to store for components
|
||||
events_slct.update(s => {
|
||||
s.exhibit_id = exhibit_id;
|
||||
return s;
|
||||
});
|
||||
|
||||
if (browser && exhibit_id) {
|
||||
events_func.load_ae_obj_id__exhibit({
|
||||
api_cfg: ae_acct.api,
|
||||
exhibit_id: exhibit_id,
|
||||
log_lvl: 0
|
||||
});
|
||||
|
||||
events_func.load_ae_obj_li__exhibit_tracking({
|
||||
api_cfg: ae_acct.api,
|
||||
for_obj_type: 'event_exhibit',
|
||||
for_obj_id: exhibit_id,
|
||||
limit: 250,
|
||||
log_lvl: 0
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -228,7 +228,7 @@
|
||||
const exhibit_id = page.params.exhibit_id;
|
||||
if (!exhibit_id) return;
|
||||
|
||||
await events_func.handle_download_export__event_exhibit_tracking({
|
||||
await events_func.download_export__event_exhibit_tracking({
|
||||
api_cfg: $ae_api,
|
||||
exhibit_id: exhibit_id,
|
||||
log_lvl: 1
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__exhibit_license_list.svelte
|
||||
* Exhibitor License Management Stub.
|
||||
*/
|
||||
</script>
|
||||
|
||||
<div class="exhibit-license-list p-4 card">
|
||||
<h3 class="h3">Staff Licenses</h3>
|
||||
<p>Placeholder for license assignment logic.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__exhibit_payment.svelte
|
||||
* Leads Payment Stub.
|
||||
*/
|
||||
</script>
|
||||
|
||||
<div class="exhibit-payment p-4 card">
|
||||
<h3 class="h3">Payment & Licensing</h3>
|
||||
<p>Placeholder for Stripe integration.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__exhibit_signin.svelte
|
||||
* Exhibitor Login Form Stub.
|
||||
*/
|
||||
</script>
|
||||
|
||||
<div class="exhibit-signin p-4 card">
|
||||
<h3 class="h3">Exhibitor Sign In</h3>
|
||||
<p>Placeholder for login logic.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_manual_search.svelte
|
||||
* Manual Attendee Search Stub.
|
||||
*/
|
||||
</script>
|
||||
|
||||
<div class="lead-manual-search p-4 card">
|
||||
<h3 class="h3">Manual Search</h3>
|
||||
<p>Placeholder for attendee lookup.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_qr_scanner.svelte
|
||||
* Badge QR Scanner Stub.
|
||||
*/
|
||||
</script>
|
||||
|
||||
<div class="lead-qr-scanner p-4 card">
|
||||
<h3 class="h3">Scan Badge</h3>
|
||||
<p>Placeholder for QR scanner component.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_tab__add.svelte
|
||||
* Tab 2: Add - Search / QR Scan Stub.
|
||||
*/
|
||||
import Comp_lead_qr_scanner from './ae_comp__lead_qr_scanner.svelte';
|
||||
import Comp_lead_manual_search from './ae_comp__lead_manual_search.svelte';
|
||||
|
||||
let show_qr = $state(true);
|
||||
</script>
|
||||
|
||||
<div class="ae-tab-add p-4 space-y-4">
|
||||
<div class="flex gap-2">
|
||||
<button type="button" class="btn btn-sm" onclick={() => show_qr = true}>QR</button>
|
||||
<button type="button" class="btn btn-sm" onclick={() => show_qr = false}>Search</button>
|
||||
</div>
|
||||
{#if show_qr} <Comp_lead_qr_scanner /> {:else} <Comp_lead_manual_search /> {/if}
|
||||
</div>
|
||||
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_tab__list.svelte
|
||||
* Tab 3: Leads List Stub.
|
||||
*/
|
||||
import Comp_exhibit_tracking_obj_li from './ae_comp__exhibit_tracking_obj_li.svelte';
|
||||
|
||||
interface Props {
|
||||
lq__event_exhibit_tracking_obj_li: any;
|
||||
}
|
||||
let { lq__event_exhibit_tracking_obj_li }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="ae-tab-list p-4 space-y-4">
|
||||
<h3 class="h3">Captured Leads</h3>
|
||||
<Comp_exhibit_tracking_obj_li {lq__event_exhibit_tracking_obj_li} />
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/lead/[exhibit_tracking_id]/+page.ts
|
||||
* Lead Detail Page Loader.
|
||||
* Responsible for loading a single exhibit tracking record and its associated badge data.
|
||||
*/
|
||||
import { browser } from '$app/environment';
|
||||
import { events_func } from '$lib/ae_events_functions';
|
||||
|
||||
export async function load({ params, parent }) {
|
||||
const parent_data = await parent();
|
||||
const account_id = parent_data.account_id;
|
||||
const ae_acct = parent_data[account_id];
|
||||
const exhibit_tracking_id = params.exhibit_tracking_id;
|
||||
|
||||
if (browser && exhibit_tracking_id) {
|
||||
// Refresh the specific Lead (Tracking) object
|
||||
events_func.load_ae_obj_id__exhibit_tracking({
|
||||
api_cfg: ae_acct.api,
|
||||
exhibit_tracking_id: exhibit_tracking_id,
|
||||
log_lvl: 0
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/[event_id]/(leads)/leads/lead/[exhibit_tracking_id]/ae_comp__lead_detail_form.svelte
|
||||
* Lead Detail Form Stub.
|
||||
*/
|
||||
</script>
|
||||
|
||||
<div class="lead-detail-form p-4 card">
|
||||
<h3 class="h3">Lead Details</h3>
|
||||
<p>Placeholder for qualifiers and notes.</p>
|
||||
</div>
|
||||
Reference in New Issue
Block a user