mirror of
https://github.com/vcscsvcscs/GenerationsHeritage.git
synced 2025-08-12 13:59:08 +02:00
remove unused old frontend
This commit is contained in:
@@ -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
|
@@ -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'
|
||||
}
|
||||
};
|
@@ -1 +0,0 @@
|
||||
engine-strict=true
|
@@ -1,8 +0,0 @@
|
||||
.svelte-kit
|
||||
.type-coverage
|
||||
build
|
||||
/lib
|
||||
.npmrc
|
||||
.eslintignore
|
||||
/tests/fixtures/rules/indent/valid/
|
||||
.changeset
|
@@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
@@ -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.
|
4954
cmd/frontend/package-lock.json
generated
4954
cmd/frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
};
|
@@ -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>
|
@@ -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 };
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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);"
|
||||
/>
|
@@ -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>
|
@@ -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 };
|
@@ -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 };
|
@@ -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 };
|
@@ -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 };
|
@@ -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');
|
||||
}
|
@@ -1 +0,0 @@
|
||||
// place files you want to import through the `$lib` alias in this folder.
|
@@ -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);
|
@@ -1,3 +0,0 @@
|
||||
export const prerender = true;
|
||||
import 'tailwindcss/tailwind.css';
|
||||
import '@xyflow/svelte/dist/style.css';
|
@@ -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>
|
@@ -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>
|
@@ -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 |
@@ -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;
|
@@ -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')]
|
||||
};
|
@@ -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
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()]
|
||||
});
|
Reference in New Issue
Block a user