From d2084de4d88916b5a438d58c12c711a02a247a46 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Tue, 6 Jan 2026 16:16:31 -0500 Subject: [PATCH] Fix 500 error, add Address/Contact placeholders, and enhance Person activity view - Fixed broken import path in /core dashboard - Simplified core layout data requirements to prevent crashes - Implemented V3 CRUD and Dexie tables for Addresses and Contacts - Created placeholder management pages for /core/addresses and /core/contacts - Added 'Linked Activity & Content' section to Person detail page to show related events and posts --- src/lib/ae_core/ae_core__address.ts | 79 +++++++++++++++ src/lib/ae_core/ae_core__contact.ts | 79 +++++++++++++++ src/lib/ae_core/db_core.ts | 16 +++ src/routes/core/+layout.svelte | 8 +- src/routes/core/+page.ts | 14 ++- src/routes/core/addresses/+page.svelte | 81 ++++++++++++++++ src/routes/core/contacts/+page.svelte | 91 +++++++++++++++++ .../core/people/[person_id]/+page.svelte | 97 ++++++++++++++++++- 8 files changed, 460 insertions(+), 5 deletions(-) create mode 100644 src/lib/ae_core/ae_core__address.ts create mode 100644 src/lib/ae_core/ae_core__contact.ts create mode 100644 src/routes/core/addresses/+page.svelte create mode 100644 src/routes/core/contacts/+page.svelte diff --git a/src/lib/ae_core/ae_core__address.ts b/src/lib/ae_core/ae_core__address.ts new file mode 100644 index 00000000..f7e06e60 --- /dev/null +++ b/src/lib/ae_core/ae_core__address.ts @@ -0,0 +1,79 @@ +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_core } from '$lib/ae_core/db_core'; + +const ae_promises: key_val = {}; + +export interface Address { + id: string; + address_id: string; + address_id_random: string; + account_id: string; + account_id_random: string; + + for_type?: string; + for_id?: string; + for_id_random?: string; + + city: string; + state_province: string; + country: string; + + enable: null | boolean; + hide?: null | boolean; + priority?: null | boolean; + sort?: null | number; + group?: null | string; + notes?: null | string; + created_on: Date; + updated_on?: null | Date; +} + +export async function load_ae_obj_li__address({ + api_cfg, + for_obj_type, + for_obj_id, + enabled = 'enabled', + hidden = 'not_hidden', + log_lvl = 0 +}: { + api_cfg: any; + for_obj_type?: string; + for_obj_id?: string; + enabled?: 'all' | 'enabled' | 'not_enabled'; + hidden?: 'all' | 'hidden' | 'not_hidden'; + log_lvl?: number; +}) { + ae_promises.load__address_obj_li = await api.get_ae_obj_li_v3({ + api_cfg, + obj_type: 'address', + for_obj_type, + for_obj_id, + enabled, + hidden, + log_lvl + }).then(async (result) => { + if (result && Array.isArray(result)) { + const processed = await process_ae_obj__address_props({ obj_li: result, log_lvl }); + await db_save_ae_obj_li__ae_obj({ + db_instance: db_core, + table_name: 'address', + obj_li: processed, + properties_to_save: ['id', 'address_id', 'address_id_random', 'city', 'state_province', 'country', 'enable'], + log_lvl + }); + return result; + } + return []; + }); + return ae_promises.load__address_obj_li; +} + +export async function process_ae_obj__address_props({ obj_li, log_lvl = 0 }: { obj_li: any[], log_lvl?: number }) { + return obj_li.map(obj => { + const new_obj = { ...obj }; + new_obj.id = obj.address_id_random; + return new_obj; + }); +} diff --git a/src/lib/ae_core/ae_core__contact.ts b/src/lib/ae_core/ae_core__contact.ts new file mode 100644 index 00000000..b883747b --- /dev/null +++ b/src/lib/ae_core/ae_core__contact.ts @@ -0,0 +1,79 @@ +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_core } from '$lib/ae_core/db_core'; + +const ae_promises: key_val = {}; + +export interface Contact { + id: string; + contact_id: string; + contact_id_random: string; + account_id: string; + account_id_random: string; + + for_type?: string; + for_id?: string; + for_id_random?: string; + + name: string; + email: string; + phone: string; + + enable: null | boolean; + hide?: null | boolean; + priority?: null | boolean; + sort?: null | number; + group?: null | string; + notes?: null | string; + created_on: Date; + updated_on?: null | Date; +} + +export async function load_ae_obj_li__contact({ + api_cfg, + for_obj_type, + for_obj_id, + enabled = 'enabled', + hidden = 'not_hidden', + log_lvl = 0 +}: { + api_cfg: any; + for_obj_type?: string; + for_obj_id?: string; + enabled?: 'all' | 'enabled' | 'not_enabled'; + hidden?: 'all' | 'hidden' | 'not_hidden'; + log_lvl?: number; +}) { + ae_promises.load__contact_obj_li = await api.get_ae_obj_li_v3({ + api_cfg, + obj_type: 'contact', + for_obj_type, + for_obj_id, + enabled, + hidden, + log_lvl + }).then(async (result) => { + if (result && Array.isArray(result)) { + const processed = await process_ae_obj__contact_props({ obj_li: result, log_lvl }); + await db_save_ae_obj_li__ae_obj({ + db_instance: db_core, + table_name: 'contact', + obj_li: processed, + properties_to_save: ['id', 'contact_id', 'contact_id_random', 'name', 'email', 'phone', 'enable'], + log_lvl + }); + return result; + } + return []; + }); + return ae_promises.load__contact_obj_li; +} + +export async function process_ae_obj__contact_props({ obj_li, log_lvl = 0 }: { obj_li: any[], log_lvl?: number }) { + return obj_li.map(obj => { + const new_obj = { ...obj }; + new_obj.id = obj.contact_id_random; + return new_obj; + }); +} diff --git a/src/lib/ae_core/db_core.ts b/src/lib/ae_core/db_core.ts index 0f6e6c2f..ea18d732 100644 --- a/src/lib/ae_core/db_core.ts +++ b/src/lib/ae_core/db_core.ts @@ -173,6 +173,8 @@ export class MySubClassedDexie extends Dexie { account!: Table; site!: Table; site_domain!: Table; + address!: Table; + contact!: Table; constructor() { super('ae_core_db'); @@ -219,6 +221,20 @@ export class MySubClassedDexie extends Dexie { id, site_domain_id, site_domain_id_random, site_id, site_id_random, domain, + enable, hide, priority, sort, group, created_on, updated_on`, + + address: ` + id, address_id, address_id_random, + account_id, account_id_random, + for_type, for_id, for_id_random, + city, state_province, country, + enable, hide, priority, sort, group, created_on, updated_on`, + + contact: ` + id, contact_id, contact_id_random, + account_id, account_id_random, + for_type, for_id, for_id_random, + name, email, phone, enable, hide, priority, sort, group, created_on, updated_on` }); } diff --git a/src/routes/core/+layout.svelte b/src/routes/core/+layout.svelte index ce689423..4a08773d 100644 --- a/src/routes/core/+layout.svelte +++ b/src/routes/core/+layout.svelte @@ -1,6 +1,6 @@ + +
+
+
+ +

Address Management

+
+ +
+ + {#if loading} +
+ {:else if address_li.length === 0} +
+

No addresses found for this account.

+
+ {:else} +
+ + + + + + + + + + + + {#each address_li as addr} + + + + + + + + {/each} + +
CityState/ProvinceCountryStatusActions
{addr.city || '--'}{addr.state_province || '--'}{addr.country || '--'} + + {addr.enable ? 'Enabled' : 'Disabled'} + + + +
+
+ {/if} +
diff --git a/src/routes/core/contacts/+page.svelte b/src/routes/core/contacts/+page.svelte new file mode 100644 index 00000000..8ea1a47c --- /dev/null +++ b/src/routes/core/contacts/+page.svelte @@ -0,0 +1,91 @@ + + +
+
+
+ +

Contact Management

+
+ +
+ + {#if loading} +
+ {:else if contact_li.length === 0} +
+

No contacts found for this account.

+
+ {:else} +
+ + + + + + + + + + + + {#each contact_li as con} + + + + + + + + {/each} + +
NameEmailPhoneStatusActions
+
+ + {con.name || '--'} +
+
+
+ + {con.email || '--'} +
+
{con.phone || '--'} + + {con.enable ? 'Enabled' : 'Disabled'} + + + +
+
+ {/if} +
diff --git a/src/routes/core/people/[person_id]/+page.svelte b/src/routes/core/people/[person_id]/+page.svelte index c718fadc..7a5ab482 100644 --- a/src/routes/core/people/[person_id]/+page.svelte +++ b/src/routes/core/people/[person_id]/+page.svelte @@ -28,7 +28,9 @@ import Person_view from './../../person_view.svelte'; import { load_ae_obj_li__user } from '$lib/ae_core/ae_core__user'; import { update_ae_obj__person } from '$lib/ae_core/ae_core__person'; - import { Users, Link, Unlink, UserPlus, ShieldCheck, User } from 'lucide-svelte'; + import { qry_ae_obj_li__event } from '$lib/ae_events/ae_events__event'; + import { load_ae_obj_li__post } from '$lib/ae_posts/ae_posts__post'; + import { Users, Link, Unlink, UserPlus, ShieldCheck, User, Calendar, MessageSquare, History } from 'lucide-svelte'; interface Props { data: any; @@ -54,6 +56,36 @@ let loading_users = $state(false); let show_link_ui = $state(false); + let related_events: any[] = $state([]); + let related_posts: any[] = $state([]); + let loading_activity = $state(false); + + async function load_activity() { + if (!$slct.person_id) return; + loading_activity = true; + + // Load related data using search queries + // Assuming person_id_random is the field name in these objects + const [events, posts] = await Promise.all([ + qry_ae_obj_li__event({ + api_cfg: $ae_api, + for_obj_id: $ae_loc.account_id, + params: { person_id_random: $slct.person_id }, + log_lvl: 1 + }), + load_ae_obj_li__post({ + api_cfg: $ae_api, + for_obj_id: $ae_loc.account_id, + params: { person_id_random: $slct.person_id }, + log_lvl: 1 + }) + ]); + + related_events = events || []; + related_posts = posts || []; + loading_activity = false; + } + async function load_unlinked_users() { if (!$ae_loc.manager_access) return; loading_users = true; @@ -95,6 +127,14 @@ }); } + onMount(() => { + if (!$ae_loc.manager_access) { + goto('/core'); + return; + } + load_activity(); + }); + if (!$ae_loc.person) { $ae_loc.person = {}; } @@ -246,6 +286,61 @@ {/if} + + +
+
+ + Linked Activity & Content +
+ +
+ +
+

+ Related Events +

+ {#if loading_activity} +
+ {:else if related_events.length === 0} +

No related events found.

+ {:else} + + {/if} +
+ + +
+

+ Related Posts +

+ {#if loading_activity} +
+ {:else if related_posts.length === 0} +

No related posts found.

+ {:else} + + {/if} +
+
+
{/if} {#if !$lq__person_obj}