remove unused old frontend

This commit is contained in:
2025-05-01 16:22:46 +02:00
parent d3fddf34d9
commit 3a84989a9e
33 changed files with 0 additions and 6354 deletions

View File

@@ -1,39 +0,0 @@
/.nyc_output
/coverage
/lib
/node_modules
/*.config.js
!/.vscode
!/.github
!/.devcontainer
/prettier-playground
/tests/fixtures/rules/indent/invalid/ts
/tests/fixtures/rules/indent/invalid/ts-v5
/tests/fixtures/rules/indent/invalid/snippets01-input.svelte
/tests/fixtures/rules/indent/valid/
/tests/fixtures/rules/no-unused-class-name/valid/invalid-style01-input.svelte
/tests/fixtures/rules/no-unused-class-name/valid/unknown-lang01-input.svelte
/tests/fixtures/rules/valid-compile/invalid/ts
/tests/fixtures/rules/valid-compile/valid/babel
/tests/fixtures/rules/valid-compile/valid/ts
/tests/fixtures/rules/prefer-style-directive
/tests/fixtures/rules/@typescript-eslint
/tests/fixtures/rules/valid-compile/valid/svelte3-options-custom-element-input.svelte
/tests/fixtures/rules/mustache-spacing/valid/always/snippet-render01-input.svelte
/tests/fixtures/rules/mustache-spacing/invalid/snippet-render01-input.svelte
/.svelte-kit
/svelte.config-dist.js
/build
/docs-svelte-kit/shim/eslint.mjs
/docs-svelte-kit/shim/assert.mjs
!/.*.js
/docs-svelte-kit/src/routes/*.md
/docs-svelte-kit/src/routes/**/*.md
/docs-svelte-kit/src/app.html
# JSONSchema bug?
/.devcontainer/devcontainer.json
# Parser bug?
/tests/fixtures/rules/indent/invalid/const-tag01-input.svelte
/tests/fixtures/rules/indent/invalid/const-tag01-output.svelte

View File

@@ -1,19 +0,0 @@
module.exports = {
extends: ['plugin:svelte/base', 'plugin:svelte/recommended', 'plugin:svelte/prettier'],
overrides: [
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser'
}
],
env: {
es6: true
},
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true
},
sourceType: 'module'
}
};

View File

@@ -1 +0,0 @@
engine-strict=true

View File

@@ -1,8 +0,0 @@
.svelte-kit
.type-coverage
build
/lib
.npmrc
.eslintignore
/tests/fixtures/rules/indent/valid/
.changeset

View File

@@ -1,31 +0,0 @@
'use strict';
module.exports = {
useTabs: true,
singleQuote: true,
trailingComma: 'none',
printWidth: 100,
plugins: ['prettier-plugin-svelte'],
overrides: [
{
files: ['.*rc'],
excludeFiles: ['.browserslistrc', '.npmrc', '.nvmrc'],
options: {
parser: 'json'
}
},
{
files: ['*.svelte'],
options: {
bracketSameLine: false
}
},
{
files: ['*.md', 'package.json', '**/package.json'],
options: {
useTabs: false,
tabWidth: 2
}
}
]
};

View File

@@ -1,38 +0,0 @@
# create-svelte
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +0,0 @@
{
"name": "frontend",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"format": "npx prettier --write --plugin prettier-plugin-svelte .",
"lint": "npx eslint --ext .svelte --ext .js ."
},
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/eslint-parser": "^7.23.10",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-static": "^3.0.1",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"autoprefixer": "^10.4.19",
"daisyui": "^4.10.2",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-svelte": "^2.35.1",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.2.2",
"svelte": "^4.2.12",
"tailwindcss": "^3.4.3",
"vite": "^5.0.3"
},
"type": "module",
"dependencies": {
"@dagrejs/dagre": "github:dagrejs/dagre",
"@xyflow/svelte": "^0.0.41",
"oidc-client-ts": "^3.0.1",
"svelte-eslint-parser": "^0.33.1"
}
}

View File

@@ -1,6 +0,0 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};

View File

@@ -1,79 +0,0 @@
<!doctype html>
<html lang="en" style="width: 100%; height: 100%">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" style="width: 100vw; height: 100vh">
<div style="display: contents; width: 100vw; height: 100vh" class="bg-base-100">
%sveltekit.body%
</div>
<div
class="dropdown mb-72"
style="position: absolute; left: auto; right: 3vw; top: 10px; bottom: auto"
>
<div tabindex="0" role="button" class="btn m-1">
Theme
<svg
width="12px"
height="12px"
class="h-2 w-2 fill-current opacity-60 inline-block"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 2048 2048"
>
<path d="M1799 349l242 241-1017 1017L7 590l242-241 775 775 775-775z"></path>
</svg>
</div>
<ul tabindex="0" class="dropdown-content z-[1] p-2 shadow-2xl bg-base-300 rounded-box w-36">
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Light"
value="light"
/>
</li>
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Dark"
value="dark"
/>
</li>
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Cyberpunk"
value="cyberpunk"
/>
</li>
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Synthwave"
value="synthwave"
/>
</li>
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Retro"
value="retro"
/>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -1,66 +0,0 @@
import { UserManager, WebStorageStateStore, type User } from 'oidc-client-ts';
import { isAuthenticated, user } from './stores';
import { PUBLIC_ZITADEL_CLIENT_ID, PUBLIC_ISSUER } from '$env/static/public';
import { goto } from '$app/navigation';
import { browser } from '$app/environment';
let userManager: UserManager;
if (browser) {
const host_url = window.location.href.startsWith('http://')
? 'http://localhost:5173'
: 'https://' + window.location.hostname;
const config = {
authority: PUBLIC_ISSUER, // At Zitadel Project Console > [Your project] > [Your application] > URLs - Issuer
client_id: PUBLIC_ZITADEL_CLIENT_ID, // At Zitadel Project Console > [Your project] > [Your application] > Configuration - Client ID
redirect_uri: host_url + '/callback', // At Zitadel Project Console > [Your project] > [Your application] > URLs - Login Redirect URI
response_type: 'code',
scope: 'openid profile email',
post_logout_redirect_uri: host_url,
userStore: new WebStorageStateStore({ store: window.localStorage }),
automaticSilentRenew: true,
silent_redirect_uri: host_url + '/silent-refresh'
};
userManager = new UserManager(config);
userManager.events.addUserLoaded((loadedUser: User) => {
console.log('userManager.events.addUserLoaded');
user.set(loadedUser);
isAuthenticated.set(true);
});
userManager.events.addUserUnloaded(() => {
console.log('userManager.events.addUserUnloaded');
user.set(null);
isAuthenticated.set(false);
});
}
async function login(): Promise<void> {
console.log('UserManager.login()');
if (browser) {
await userManager.signinRedirect();
}
}
async function logout(): Promise<void> {
if (browser) {
await userManager.signoutRedirect();
}
}
async function handleCallback(): Promise<void> {
if (browser) {
await userManager.signinRedirectCallback();
goto('/');
}
}
async function handleSilentCallback(): Promise<void> {
if (browser) {
await userManager.signinSilentCallback();
goto('/');
}
}
export { login, logout, handleCallback, handleSilentCallback };

View File

@@ -1,215 +0,0 @@
<script lang="ts">
import { PUBLIC_API_URL } from '$env/static/public';
import { setFamilyTreeNodes } from './setFamilyTreeNodes';
import { user } from '../stores';
import { onMount } from 'svelte';
export let id = '';
let auth_token = '';
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
let relationship = '';
let dialog: HTMLDialogElement;
let payload = {
relationship: {
first_person_id: id,
relationship: relationship,
direction: '->'
},
person: {
first_name: '',
middle_name: '',
last_name: '',
mothers_first_name: '',
mothers_last_name: '',
born: '',
birthplace: '',
titles: [],
residence: '',
death: '',
deathplace: '',
life_events: [],
occupation: [],
occupation_to_display: '',
others_said: {},
photos: {},
profile_picture: 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'
}
};
function handleSubmit(event: Event) {
event.preventDefault();
if (
id &&
relationship &&
payload.person.first_name &&
payload.person.last_name &&
payload.person.born &&
payload.person.mothers_first_name &&
payload.person.mothers_last_name
) {
fetch(PUBLIC_API_URL + '/createRelationshipAndPerson', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: auth_token
},
body: JSON.stringify(payload)
}).then((response) => {
if (response.ok) {
setFamilyTreeNodes();
dialog.close();
} else {
alert('Failed to add family member! with status ' + response.status);
}
});
} else {
alert('You have to fill out all the required fields!');
}
}
onMount(() => {
if (dialog) dialog.showModal();
});
</script>
<dialog bind:this={dialog} class="modal bg-base-300">
<div class="modal-box w-11/12 max-w-5xl">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form>
<h1 class="font-bold text-lg">Create a family members profile</h1>
<p>
You can add a family member to your family tree by filling out the form below. You can update
the information later.
</p>
<form on:submit={handleSubmit} method="dialog" class="flex flex-col gap-4">
<div class="grid grid-cols-2 gap-4">
<label for="relationship" class="input input-bordered flex items-center gap-2">
Relationship type:
<select id="relationship" bind:value={relationship} required>
<option value="" disabled selected>Choose one ...</option>
<option value="Parent">Parent</option>
<option value="Child">Child</option>
<option value="Spouse">Spouse</option>
<option value="Sibling">Sibling</option>
</select>
</label>
<label for="firstName" class="input input-bordered flex items-center gap-2">
First Name:
<input
type="text"
id="firstName"
class="grow input-md"
bind:value={payload.person.first_name}
required
/>
</label>
<label for="middleName" class="input input-bordered flex items-center gap-2">
Middle Name:
<input
type="text"
id="middleName"
class="grow input-md"
bind:value={payload.person.middle_name}
/>
</label>
<label for="lastName" class="input input-bordered flex items-center gap-2">
Last Name:
<input
type="text"
id="lastName"
class="grow input-md"
bind:value={payload.person.last_name}
required
/>
</label>
<label for="born" class="input input-bordered flex items-center gap-2">
Born:
<input
type="date"
id="born"
class="grow input-md"
bind:value={payload.person.born}
required
/>
</label>
<label for="birthplace" class="input input-bordered flex items-center gap-2">
Birthplace:
<input
type="text"
id="birthplace"
class="grow input-md"
bind:value={payload.person.birthplace}
required
/>
</label>
<label for="mothersFirstName" class="input input-bordered flex items-center gap-2">
Mother's First Name:
<input
type="text"
id="mothersFirstName"
class="grow input-md"
bind:value={payload.person.mothers_first_name}
required
/>
</label>
<label for="mothersLastName" class="input input-bordered flex items-center gap-2">
Mother's Last Name:
<input
type="text"
id="mothersLastName"
class="grow input-md"
bind:value={payload.person.mothers_last_name}
required
/>
</label>
<label for="death" class="input input-bordered flex items-center gap-2">
Death:
<input type="date" id="death" class="grow input-md" bind:value={payload.person.death} />
</label>
<label for="deathplace" class="input input-bordered flex items-center gap-2">
Place of death:
<input
type="text"
id="deathplace"
class="grow input-md"
bind:value={payload.person.deathplace}
/>
</label>
<label for="residence" class="input input-bordered flex items-center gap-2">
Residence:
<input
type="text"
id="residence"
class="grow input-md"
bind:value={payload.person.residence}
/>
</label>
<label for="titles" class="input input-bordered flex items-center gap-2">
Titles:
<input type="text" id="titles" class="grow input-md" bind:value={payload.person.titles} />
</label>
</div>
<button type="submit" class="btn btn-primary w-40 place-self-end">Add</button>
</form>
</div>
</dialog>

View File

@@ -1,80 +0,0 @@
<script lang="ts">
import { PUBLIC_API_URL } from '$env/static/public';
import { setFamilyTreeNodes } from './setFamilyTreeNodes';
import { user } from '$lib/stores';
import { onMount } from 'svelte';
export let id = '';
let relationship = '';
let second_person_id = '';
let dialog: HTMLDialogElement; // HTMLDialogElement
let auth_token = '';
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
function handleSubmit(event: SubmitEvent) {
event.preventDefault();
if (second_person_id && id && relationship) {
const payload = {
first_person_id: id,
second_person_id: second_person_id,
relationship: relationship,
direction: '->'
};
fetch(PUBLIC_API_URL + '/relationship', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: auth_token
},
body: JSON.stringify(payload)
}).then((response) => {
if (response.ok) {
setFamilyTreeNodes();
dialog.close();
} else {
alert('Failed to add relationship! with status ' + response.status);
}
});
} else {
alert('You have to fill out all the fields!');
}
}
onMount(() => {
if (dialog) dialog.showModal();
});
</script>
<dialog bind:this={dialog} class="modal bg-base-300">
<div class="modal-box w-11/12 max-w-5xl">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form>
<h1 class="font-bold text-lg">Add a relationship</h1>
<p>
Ask your relative to give you their id and set what kind of relationship you have with them.
</p>
<form on:submit={handleSubmit} method="dialog">
<label for="id" class="input input-bordered flex items-center gap-2">
ID:
<input type="text" id="id" class="grow" bind:value={id} required />
</label>
<label for="relationship">Relationship type:</label>
<select id="relationship" bind:value={relationship} required>
<option value="" disabled selected>Choose one ...</option>
<option value="Parent">Parent</option>
<option value="Child">Child</option>
<option value="Spouse">Spouse</option>
<option value="Sibling">Sibling</option>
</select>
<button type="submit" class="btn btn-primary">Add</button>
</form>
</div>
</dialog>

View File

@@ -1,152 +0,0 @@
<script lang="ts">
import { PUBLIC_API_URL } from '$env/static/public';
import { onMount } from 'svelte';
import { user } from '../stores';
let auth_token = '';
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
let dialog: HTMLDialogElement;
let payload = {
first_name: '',
middle_name: '',
last_name: '',
mothers_first_name: '',
mothers_last_name: '',
born: '',
birthplace: '',
titles: [],
residence: '',
life_events: [],
occupation: [],
occupation_to_display: '',
photos: {},
profile_picture: 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'
};
function handleSubmit(event: Event) {
event.preventDefault();
if (
payload.first_name &&
payload.last_name &&
payload.born &&
payload.mothers_first_name &&
payload.mothers_last_name
) {
payload.born = new Date(payload.born).toISOString();
fetch(PUBLIC_API_URL + '/person', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer' + auth_token
},
body: JSON.stringify(payload)
}).then((response) => {
if (response.ok) {
dialog.close();
} else {
alert('Failed to create profile! with status ' + response.status);
}
});
} else {
alert('You have to fill out all the required fields!');
}
}
onMount(() => {
if (dialog) dialog.showModal();
});
</script>
<dialog bind:this={dialog} class="modal bg-base-300">
<div class="modal-box w-11/12 max-w-5xl flex flex-col gap-4">
<h1 class="font-bold text-lg">Create your profile</h1>
<p>To start building your family tree fill this form. You can add more information later.</p>
<form on:submit={handleSubmit} method="dialog">
<div class="grid grid-cols-2 gap-4">
<label class="input input-bordered flex items-center gap-2" for="firstName">
First Name:
<input
type="text"
id="firstName"
class="grow input-md"
bind:value={payload.first_name}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="middleName">
Middle Name:
<input
type="text"
id="middleName"
class="grow input-md"
bind:value={payload.middle_name}
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="lastName">
Last Name:
<input
type="text"
id="lastName"
class="grow input-md"
bind:value={payload.last_name}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="born">
Born:
<input type="date" id="born" class="grow input-md" bind:value={payload.born} required />
</label>
<label class="input input-bordered flex items-center gap-2" for="birthplace">
Birthplace:
<input
type="text"
id="birthplace"
class="grow input-md"
bind:value={payload.birthplace}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="mothersFirstName">
Mother's First Name:
<input
type="text"
id="mothersFirstName"
class="grow input-md"
bind:value={payload.mothers_first_name}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="mothersLastName">
Mother's Last Name:
<input
type="text"
id="mothersLastName"
class="grow input-md"
bind:value={payload.mothers_last_name}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="residence">
Residence:
<input type="text" id="residence" class="grow input-md" bind:value={payload.residence} />
</label>
<label class="input input-bordered flex items-center gap-2" for="titles">
Titles:
<input type="text" id="titles" class="grow input-md" bind:value={payload.titles} />
</label>
<button type="submit" class="btn btn-primary w-40 place-self-end">Add</button>
</div>
</form>
</div>
</dialog>

View File

@@ -1,61 +0,0 @@
<script lang="ts">
import { onMount } from 'svelte';
export let onClick: () => void;
export let deleteNode: () => void;
export let addRelationship: () => void;
export let addFamilymember: () => void;
export let id: string;
export let top: number | undefined;
export let left: number | undefined;
export let right: number | undefined;
export let bottom: number | undefined;
let contextMenu: HTMLDivElement;
onMount(() => {
if (top) {
contextMenu.style.top = `${top}px`;
}
if (left) {
contextMenu.style.left = `${left}px`;
}
if (right) {
contextMenu.style.right = `${right}px`;
}
if (bottom) {
contextMenu.style.bottom = `${bottom}px`;
}
});
</script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
bind:this={contextMenu}
class="context-menu bg-primary-100 rounded-lg shadow-lg"
on:click={onClick}
>
<p style="margin: 0.5em;">
<small>node: {id}</small>
</p>
<button on:click={addRelationship} class="btn">Add Relationship</button>
<button on:click={addFamilymember} class="btn">Add familymember</button>
<button on:click={deleteNode} class="btn">Delete</button>
</div>
<style>
.context-menu {
border-style: solid;
box-shadow: 10px 19px 20px rgba(0, 0, 0, 10%);
position: absolute;
z-index: 10;
}
.context-menu button {
border: none;
display: block;
padding: 0.5em;
text-align: left;
width: 100%;
}
</style>

View File

@@ -1,70 +0,0 @@
<script lang="ts">
import { Handle, Position, type NodeProps } from '@xyflow/svelte';
export let id: NodeProps['id'];
id;
export let dragHandle: NodeProps['dragHandle'] = undefined;
dragHandle;
export let type: NodeProps['type'] = undefined;
type;
export let selected: NodeProps['selected'] = undefined;
selected;
export let width: NodeProps['width'] = undefined;
width;
export let height: NodeProps['height'] = undefined;
height;
export let dragging: NodeProps['dragging'];
dragging;
export let targetPosition: NodeProps['targetPosition'] = undefined;
targetPosition;
export let sourcePosition: NodeProps['sourcePosition'] = undefined;
sourcePosition;
export let data = {
id: '',
last_name: 'Nem',
first_name: 'Ismert',
middle_name: '',
profile_picture: 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'
};
</script>
<div class="rounded-badge card card-compact bg-base-300">
<div class="card-body items-center text-center w-30">
<div class="avatar">
<figure class="w-24 mask mask-squircle">
<img src={'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'} alt="Picture of {data.last_name} {data.first_name}" />
</figure>
</div>
<h2 class="card-title text-base-content">
{data.first_name}
{data.middle_name ? data.middle_name : ''}
{data.last_name}
</h2>
</div>
</div>
<Handle
type="target"
position={Position.Top}
id="spouse"
style="transform: translate(10px, 50%); left: 0;"
/>
<Handle
type="source"
position={Position.Top}
id="spouse"
style="transform: translate(0, 50%); left: auto; right: 10px"
/>
<Handle type="target" position={Position.Top} id="parent" style="transform: translate(0, 50%);" />
<Handle
type="source"
position={Position.Bottom}
id="child"
style="transform: translate(0, -3px);"
/>
<Handle type="target" position={Position.Top} id="child" style="transform: translate(0, 50%);" />
<Handle
type="source"
position={Position.Bottom}
id="parent"
style="transform: translate(0, -3px);"
/>

View File

@@ -1,53 +0,0 @@
<script lang="ts">
import { onMount } from 'svelte';
import { fetch_profile } from './getProfile';
export let data = {
id: '',
last_name: 'Nem',
first_name: 'Ismert',
middle_name: '',
profile_picture: 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'
};
let dialog: HTMLDialogElement; // HTMLDialogElement
onMount(() => {
if (dialog) dialog.showModal();
fetch_profile(data.id).then((data) => {
data = data
});
data.profile_picture = 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png';
});
</script>
<dialog bind:this={dialog} class="modal bg-base-300">
<div class="modal-box w-11/12 max-w-5xl">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form>
<div class="hero min-h-screen bg-base-200">
<div class="hero-content flex-col lg:flex-row">
<div class="avatar max-w-sm rounded-lg shadow-2xl">
<figure class="w-24 mask mask-squircle">
<img src={data.profile_picture} alt="Picture of {data.last_name} {data.first_name}" />
</figure>
</div>
<div>
<h1 class="text-5xl font-bold">
{data.first_name}
{data.middle_name ? data.middle_name : ''}
{data.last_name}
</h1>
<p class="py-6">
Provident cupiditate voluptatem et in. Quaerat fugiat ut assumenda excepturi
exercitationem quasi. In deleniti eaque aut repudiandae et a id nisi.
</p>
</div>
</div>
</div>
<form method="dialog" class="modal-backdrop">
<button>close</button>
</form>
</div>
</dialog>

View File

@@ -1,39 +0,0 @@
import dagre from '@dagrejs/dagre';
import { Position, type Node, type Edge } from '@xyflow/svelte';
const dagreGraph = new dagre.graphlib.Graph();
const nodeWidth = 250;
const nodeHeight = 250;
function getLayoutedElements(nodes: Node[], edges: Edge[], direction = 'TB') {
dagreGraph.setDefaultEdgeLabel(() => ({}));
const isHorizontal = direction === 'LR';
dagreGraph.setGraph({ rankdir: direction });
nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
});
edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target);
});
dagre.layout(dagreGraph);
nodes.forEach((node) => {
const nodeWithPosition = dagreGraph.node(node.id);
node.targetPosition = isHorizontal ? Position.Left : Position.Top;
node.sourcePosition = isHorizontal ? Position.Right : Position.Bottom;
// We are shifting the dagre node position (anchor=center center) to the top left
// so it matches the React Flow node anchor point (top left).
node.position = {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2
};
});
return { nodes, edges };
}
export { getLayoutedElements };

View File

@@ -1,77 +0,0 @@
import { type Node, type Edge } from '@xyflow/svelte';
function AddToNodesData(data: any, i: number, pushToNodesCallback: (arg: Node) => void) {
if (data[0].Values[i] != null) {
if (Object.prototype.toString.call(data[0].Values[i]) === '[object Array]') {
data[0].Values[i].forEach((person: { ElementId: string; Props: {} }) => {
pushToNodesCallback({
id: person.ElementId,
type: 'custom',
data: person.Props,
position: { x: 0, y: 0 }
});
});
} else {
console.log(data[0].Values[i]);
pushToNodesCallback({
id: data[0].Values[i].ElementId,
type: 'custom',
data: data[0].Values[i].Props,
position: { x: 0, y: 0 }
});
}
}
}
function AddToEdgesData(data: any, i: number, pushToEdgesCallback: (arg: Edge) => void) {
if (data[0].Values[i] != null) {
if (Object.prototype.toString.call(data[0].Values[i]) === '[object Array]') {
data[0].Values[i].forEach(
(edge: {
ElementId: string;
StartElementId: string;
EndElementId: string;
Type: string;
Props: {};
}) => {
pushToEdgesCallback({
id: edge.ElementId,
source: edge.StartElementId,
sourceHandle:
edge.Type === 'Parent' ? 'parent' : edge.Type === 'Child' ? 'child' : 'spouse',
target: edge.EndElementId,
targetHandle:
edge.Type === 'Parent' ? 'child' : edge.Type === 'Child' ? 'parent' : 'spouse',
label: edge.Type,
data: edge.Props,
zIndex: edge.Type === 'Spouse' ? 1 : 0
});
}
);
} else {
console.log(data[0].Values[i]);
pushToEdgesCallback({
id: data[0].Values[i].ElementId,
source: data[0].Values[i].StartElementId,
sourceHandle:
data[0].Values[i].Type === 'Parent'
? 'parent'
: data[0].Values[i].Type === 'Child'
? 'child'
: 'spouse',
target: data[0].Values[i].EndElementId,
targetHandle:
data[0].Values[i].Type === 'Parent'
? 'child'
: data[0].Values[i].Type === 'Child'
? 'parent'
: 'spouse',
label: data[0].Values[i].Type,
data: data[0].Values[i].Props,
zIndex: data[0].Values[i].Type === 'Spouse' ? 1 : 0
});
}
}
}
export { AddToNodesData, AddToEdgesData };

View File

@@ -1,24 +0,0 @@
import { PUBLIC_API_URL } from '$env/static/public';
import { user } from '$lib/stores';
let auth_token: string;
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
async function fetch_family_tree() {
const response = await fetch(PUBLIC_API_URL + '/familyTree', {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + auth_token
}
});
const data = await response.json();
return data;
}
export { fetch_family_tree };

View File

@@ -1,24 +0,0 @@
import { PUBLIC_API_URL } from '$env/static/public';
import { user } from '$lib/stores';
let auth_token: string;
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
async function fetch_profile(id: string = '') {
const response = await fetch(PUBLIC_API_URL + '/person' + (id != '' ? '?id=' + id : ''), {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + auth_token
}
});
const data = await response.json();
return data;
}
export { fetch_profile };

View File

@@ -1,61 +0,0 @@
import { fetch_family_tree } from '$lib/family_tree/getFamilyTree';
import { getLayoutedElements } from '$lib/family_tree/dagreLayout';
import { AddToNodesData, AddToEdgesData } from '$lib/family_tree/dataAdapter';
import type { Node, Edge } from '@xyflow/svelte';
import { useEdges, useNodes } from '@xyflow/svelte';
import { fetch_profile } from './getProfile';
export async function setFamilyTreeNodes(): Promise<{
nodes: Node[];
edges: Edge[];
}> {
console.log('fetching nodes');
let layoutedElements: {
nodes: Node[];
edges: Edge[];
} = { nodes: [], edges: [] };
let nodes_data: Node[] = [];
let edges_data: Edge[] = [];
await fetch_profile().then((data) => {
nodes_data.push({
id: data.ElementId,
type: 'custom',
data: data.Props,
position: { x: 0, y: 0 }
});
});
await fetch_family_tree().then((data: []) => {
if (data.length == 0) {
return layoutedElements;
}
function pushNodeToData(node: Node) {
nodes_data.push(node);
}
AddToNodesData(data, 0, pushNodeToData);
AddToNodesData(data, 2, pushNodeToData);
AddToNodesData(data, 4, pushNodeToData);
AddToNodesData(data, 6, pushNodeToData);
AddToNodesData(data, 8, pushNodeToData);
function pushEdgeToData(edge: Edge) {
edges_data.push(edge);
}
AddToEdgesData(data, 1, pushEdgeToData);
AddToEdgesData(data, 3, pushEdgeToData);
AddToEdgesData(data, 5, pushEdgeToData);
AddToEdgesData(data, 7, pushEdgeToData);
});
console.log('Fetched nodes and edges data.');
// Remove duplicate nodes
nodes_data = nodes_data.filter(
(node, index, self) => index === self.findIndex((n) => n.id === node.id)
);
return getLayoutedElements(nodes_data, edges_data, 'TB');
}

View File

@@ -1 +0,0 @@
// place files you want to import through the `$lib` alias in this folder.

View File

@@ -1,5 +0,0 @@
import { writable } from 'svelte/store';
import type { User } from 'oidc-client-ts';
export const isAuthenticated = writable<boolean>(false);
export const user = writable<User | null>(null);

View File

@@ -1,3 +0,0 @@
export const prerender = true;
import 'tailwindcss/tailwind.css';
import '@xyflow/svelte/dist/style.css';

View File

@@ -1,139 +0,0 @@
<script lang="ts">
import { writable } from 'svelte/store';
import { onMount } from 'svelte';
import { SvelteFlowProvider, SvelteFlow, Controls, MiniMap } from '@xyflow/svelte';
import type { Node, Edge, NodeTypes } from '@xyflow/svelte';
import { isAuthenticated } from '../lib/stores';
import PersonNode from './../lib/family_tree/PersonNode.svelte';
import { setFamilyTreeNodes } from '../lib/family_tree/setFamilyTreeNodes';
import { login } from '../lib/auth';
import PersonMenu from '$lib/family_tree/PersonMenu.svelte';
import PersonPanel from '$lib/family_tree/PersonPanel.svelte';
import AddRelationship from '$lib/family_tree/AddRelationship.svelte';
import AddFamilyMember from '$lib/family_tree/AddFamilyMember.svelte';
import CreateProfile from '$lib/family_tree/CreateProfile.svelte';
let relationshipPanel = '';
let AddFamilyMemberPanel = '';
let CreateProfilePanel = false;
const nodes = writable<Node[]>([]);
const edges = writable<Edge[]>([]);
onMount(() => {
if (!$isAuthenticated) {
console.log('user is not authenticated');
login();
} else {
console.log('user is authenticated');
setFamilyTreeNodes().then((layout) => {
if (layout.nodes.length < 1) {
CreateProfilePanel = true;
} else {
nodes.set(layout.nodes);
edges.set(layout.edges);
}
});
}
});
const nodeTypes: NodeTypes = {
custom: PersonNode
};
let personPanel:
| {
id: string;
last_name: string;
first_name: string;
middle_name: string;
profile_picture: string;
}
| undefined;
let menu: { id: string; top?: number; left?: number; right?: number; bottom?: number } | null;
let width: number;
let height: number;
function handleContextMenu({
detail: { event, node }
}: {
detail: { event: MouseEvent; node: Node };
}) {
event.preventDefault();
menu = {
id: node.data.id,
top: event.clientY < height - 200 ? event.clientY : undefined,
left: event.clientX < width - 200 ? event.clientX : undefined,
right: event.clientX >= width - 200 ? width - event.clientX : undefined,
bottom: event.clientY >= height - 200 ? height - event.clientY : undefined
};
}
// Close the context menu if it's open whenever the window is clicked.
function handlePaneClick() {
menu = null;
relationshipPanel = '';
}
function handleNodeClick({
detail: { event, node }
}: {
detail: { event: MouseEvent; node: Node };
}) {
event.preventDefault();
personPanel = node.data;
}
</script>
<div style="height:100vh;">
<SvelteFlowProvider>
<SvelteFlow
{nodes}
{nodeTypes}
{edges}
on:nodecontextmenu={handleContextMenu}
on:nodeclick={handleNodeClick}
on:paneclick={handlePaneClick}
class="bg-base-100"
fitView
onlyRenderVisibleElements
>
<Controls class="bg-base-300 text-base-content" />
<MiniMap class="bg-base-200" />
{#if menu != null}
<PersonMenu
onClick={handlePaneClick}
deleteNode={() => {
console.log('delete node');
}}
addRelationship={() => {
if (menu) relationshipPanel = menu.id;
}}
addFamilymember={() => {
if (menu) AddFamilyMemberPanel = menu.id;
}}
id={menu.id}
top={menu.top}
left={menu.left}
right={menu.right}
bottom={menu.bottom}
/>
{/if}
{#if personPanel != null}
<PersonPanel data={personPanel} />
{/if}
{#if relationshipPanel != ''}
<AddRelationship id={relationshipPanel} />
{/if}
{#if AddFamilyMemberPanel != ''}
<AddFamilyMember id={AddFamilyMemberPanel} />
{/if}
{#if CreateProfilePanel}
<CreateProfile />
{/if}
</SvelteFlow>
</SvelteFlowProvider>
</div>

View File

@@ -1,11 +0,0 @@
<!-- src/routes/callback.svelte -->
<script lang="ts">
import { onMount } from 'svelte';
import { handleCallback } from '../../lib/auth';
onMount(() => {
handleCallback();
});
</script>
<div>Logging in...</div>

View File

@@ -1,10 +0,0 @@
<script lang="ts">
import { onMount } from 'svelte';
import { handleSilentCallback } from '../../lib/auth';
onMount(() => {
handleSilentCallback();
});
</script>
<div>Refreshing...</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,18 +0,0 @@
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: undefined,
precompress: false,
strict: true
})
}
};
export default config;

View File

@@ -1,12 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{html,svelte,js,ts}'],
important: true,
theme: {
extend: {}
},
daisyui: {
themes: ['light', 'dark', 'cyberpunk', 'synthwave', 'retro', 'roboto', 'dracula']
},
plugins: [require('daisyui')]
};

View File

@@ -1,14 +0,0 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
},
"include": ["src/**/*", "src/node_modules", ".svelte-kit/ambient.d.ts"] // see last element
}

View File

@@ -1,6 +0,0 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()]
});