From 79ce1dae04d933f2cf5f7495a4060690e7fac887 Mon Sep 17 00:00:00 2001 From: Vargha Csongor Date: Sat, 26 Apr 2025 22:29:32 +0200 Subject: [PATCH] create profile editor and viewer --- apps/app/src/lib/graph/PersonMenu.svelte | 67 +++++++++++++++++++ apps/app/src/lib/graph/model.ts | 12 ++++ apps/app/src/lib/graph/node_click.ts | 14 ++++ .../src/lib/profile/LifeEventsTimeline.svelte | 26 +++++++ apps/app/src/lib/profile/MediaGallery.svelte | 22 ++++++ apps/app/src/lib/profile/Modal.svelte | 50 ++++++++++++++ apps/app/src/lib/profile/ModalButtons.svelte | 20 ++++++ apps/app/src/lib/profile/OtherDetails.svelte | 40 +++++++++++ apps/app/src/lib/profile/ProfileHeader.svelte | 31 +++++++++ apps/app/src/routes/+page.svelte | 22 ++++++ 10 files changed, 304 insertions(+) create mode 100644 apps/app/src/lib/graph/PersonMenu.svelte create mode 100644 apps/app/src/lib/graph/model.ts create mode 100644 apps/app/src/lib/graph/node_click.ts create mode 100644 apps/app/src/lib/profile/LifeEventsTimeline.svelte create mode 100644 apps/app/src/lib/profile/MediaGallery.svelte create mode 100644 apps/app/src/lib/profile/Modal.svelte create mode 100644 apps/app/src/lib/profile/ModalButtons.svelte create mode 100644 apps/app/src/lib/profile/OtherDetails.svelte create mode 100644 apps/app/src/lib/profile/ProfileHeader.svelte diff --git a/apps/app/src/lib/graph/PersonMenu.svelte b/apps/app/src/lib/graph/PersonMenu.svelte new file mode 100644 index 0000000..9eedcd5 --- /dev/null +++ b/apps/app/src/lib/graph/PersonMenu.svelte @@ -0,0 +1,67 @@ + + + + + diff --git a/apps/app/src/lib/graph/model.ts b/apps/app/src/lib/graph/model.ts new file mode 100644 index 0000000..9c2e912 --- /dev/null +++ b/apps/app/src/lib/graph/model.ts @@ -0,0 +1,12 @@ +export interface NodeMenu { + onClick: () => void; + deleteNode: () => void; + createRelationshipAndNode: () => void; + addRelationship: () => void; + addRecipe: (() => void) | undefined; + addAdmin: (() => void) | undefined; + top: number | undefined; + left: number | undefined; + right: number | undefined; + bottom: number | undefined; +} \ No newline at end of file diff --git a/apps/app/src/lib/graph/node_click.ts b/apps/app/src/lib/graph/node_click.ts new file mode 100644 index 0000000..ca916d6 --- /dev/null +++ b/apps/app/src/lib/graph/node_click.ts @@ -0,0 +1,14 @@ +import type { components } from '$lib/api/api.gen'; +import type { Node } from '@xyflow/svelte'; + +export function handleNodeClick(set_panel_options:(person:components['schemas']['PersonProperties']&{id:number})=>void): ({ + detail: { event, node } +}: { + detail: { event: MouseEvent; node: Node }; +}) => void { + return ({ detail: { event, node } }) => { + event.preventDefault(); + node.data.id = Number(node.id); + set_panel_options(node.data as components['schemas']['PersonProperties']&{id:number}); + } +} \ No newline at end of file diff --git a/apps/app/src/lib/profile/LifeEventsTimeline.svelte b/apps/app/src/lib/profile/LifeEventsTimeline.svelte new file mode 100644 index 0000000..4415a4b --- /dev/null +++ b/apps/app/src/lib/profile/LifeEventsTimeline.svelte @@ -0,0 +1,26 @@ + + +{#if draftPerson.life_events?.length} +
{life_events()}
+ +{/if} diff --git a/apps/app/src/lib/profile/MediaGallery.svelte b/apps/app/src/lib/profile/MediaGallery.svelte new file mode 100644 index 0000000..4a5c105 --- /dev/null +++ b/apps/app/src/lib/profile/MediaGallery.svelte @@ -0,0 +1,22 @@ + + + {#if draftPerson.photos?.length || draftPerson.videos?.length} +
{photos()} & {video()}
+
+ {#each draftPerson.photos ?? [] as picture} + {picture.description + {/each} + {#each draftPerson.videos ?? [] as video} + + {/each} +
+ {/if} + \ No newline at end of file diff --git a/apps/app/src/lib/profile/Modal.svelte b/apps/app/src/lib/profile/Modal.svelte new file mode 100644 index 0000000..38fac5f --- /dev/null +++ b/apps/app/src/lib/profile/Modal.svelte @@ -0,0 +1,50 @@ + + +{#if open} + +{/if} diff --git a/apps/app/src/lib/profile/ModalButtons.svelte b/apps/app/src/lib/profile/ModalButtons.svelte new file mode 100644 index 0000000..209f778 --- /dev/null +++ b/apps/app/src/lib/profile/ModalButtons.svelte @@ -0,0 +1,20 @@ + + +
+

{biography()}

+
+ + +
+
diff --git a/apps/app/src/lib/profile/OtherDetails.svelte b/apps/app/src/lib/profile/OtherDetails.svelte new file mode 100644 index 0000000..ddc744a --- /dev/null +++ b/apps/app/src/lib/profile/OtherDetails.svelte @@ -0,0 +1,40 @@ + + +
+ {#each Object.entries(draftPerson) as [key, value]} + {#if !skipFields.includes(key)} +
+

+ {(msg as any)[key]() ?? key}: + {#if editorMode} + + {:else} + {JSON.stringify(value) ?? '-'} + {/if} +

+
+ {/if} + {/each} +
diff --git a/apps/app/src/lib/profile/ProfileHeader.svelte b/apps/app/src/lib/profile/ProfileHeader.svelte new file mode 100644 index 0000000..23f9429 --- /dev/null +++ b/apps/app/src/lib/profile/ProfileHeader.svelte @@ -0,0 +1,31 @@ + + +
+ {#if draftPerson.profile_picture} +
+ {profile_picture()} +
+ {/if} + +
+
+

{first_name()}: {#if editorMode}{:else}{draftPerson.first_name ?? '-'}{/if}

+

{last_name()}: {#if editorMode}{:else}{draftPerson.last_name ?? '-'}{/if}

+

{middle_name()}: {#if editorMode}{:else}{draftPerson.middle_name ?? '-'}{/if}

+

{born()}: {#if editorMode}{:else}{draftPerson.born ?? '-'}{/if}

+

{biological_sex()}: {#if editorMode}{:else}{draftPerson.biological_sex ?? '-'}{/if}

+
+
+

{email()}: {#if editorMode}{:else}{draftPerson.email ?? '-'}{/if}

+

Limit: {#if editorMode}{:else}{draftPerson.limit ?? '-'}{/if}

+

{mothers_first_name()}: {#if editorMode}{:else}{draftPerson.mothers_first_name ?? '-'}{/if}

+

{mothers_last_name()}: {#if editorMode}{:else}{draftPerson.mothers_last_name ?? '-'}{/if}

+
+
+
+ \ No newline at end of file diff --git a/apps/app/src/routes/+page.svelte b/apps/app/src/routes/+page.svelte index b9edd98..2d44704 100644 --- a/apps/app/src/routes/+page.svelte +++ b/apps/app/src/routes/+page.svelte @@ -5,9 +5,18 @@ import '@xyflow/svelte/dist/style.css'; import type { Node, Edge, NodeTypes, NodeProps } from '@xyflow/svelte'; import PersonNode from '$lib/graph/PersonNode.svelte'; + import PersonModal from '$lib/profile/Modal.svelte'; import type { components } from '$lib/api/api.gen'; + import { handleNodeClick } from '$lib/graph/node_click'; + import PersonMenu from '$lib/graph/PersonMenu.svelte'; + import type { NodeMenu } from '$lib/graph/model'; + let { data, form }: PageProps = $props(); const nodeTypes: NodeTypes = { personNode: PersonNode }; + let selectedPerson: components['schemas']['PersonProperties'] & {id:number|null} = $state({id: null}); + let openPersonPanel = $state(false); + let openPersonMenu: NodeMenu = $state({}); + let ppl = data.people; if (ppl === undefined) { ppl = []; @@ -25,6 +34,17 @@ } ]); let edges = $state.raw([]); + + handleNodeClick( + ( + person: components['schemas']['PersonProperties'] & { + id: number; + } + ) => { + openPersonPanel = true; + selectedPerson = person; + } + ); @@ -43,6 +63,8 @@ > + +