fix sidebar and some other design issues

This commit is contained in:
2025-04-29 23:29:31 +02:00
parent 69c43d6d79
commit 68c73ca859
11 changed files with 2280 additions and 2284 deletions

View File

@@ -41,7 +41,7 @@
<select
bind:value={current_theme}
data-choose-theme
class="btn btn-ghost btn-xs h-8 min-h-0 px-4 py-0 text-sm"
class="btn btn-soft btn-xs h-8 min-h-0 px-4 py-0 text-sm"
onchange={set_theme}
>
<option value="" disabled={current_theme !== ''}>

File diff suppressed because it is too large Load Diff

View File

@@ -63,12 +63,4 @@
}
</script>
<BaseEdge path={edgePath} {markerEnd} {style} />
<EdgeLabelRenderer>
<div
class="button-edge__label nodrag nopan"
style:transform="translate(-50%, -50%) translate({labelX}px,{labelY}px)"
>
<button class="button-edge__button" onclick={onEdgeClick}>{edgeLabel}</button>
</div>
</EdgeLabelRenderer>
<BaseEdge path={edgePath} {markerEnd} {style} onclick={onEdgeClick}/>

View File

@@ -1,16 +1,29 @@
<!-- <svelte:options immutable /> -->
<script lang="ts">
import { Handle, Position, useConnection, type NodeProps } from '@xyflow/svelte';
import { Handle, Position, type NodeProps } from '@xyflow/svelte';
import type { components } from '$lib/api/api.gen';
import { isValidConnection } from './connection.js';
type $$Props = NodeProps;
export let data: NodeProps['data'] & components['schemas']['PersonProperties'];
let nodeColor = ' bg-neutral text-neutral-content';
switch (data.biological_sex) {
case ('female'):
nodeColor = ' bg-secondary text-secondary-content';
break;
case ('male'):
nodeColor = ' bg-primary text-primary-content';
break;
case ('intersex'):
nodeColor = ' bg-accent text-accent-content';
break;
}
</script>
<div
class="card card-compact bg-primary-content text-primary flex h-40 w-40 flex-col items-center justify-center rounded-full shadow-lg"
class={"card card-compact flex h-40 w-40 flex-col items-center justify-center rounded-full shadow-lg" + nodeColor}
>
<Handle
class="customHandle"
@@ -32,7 +45,7 @@
<div class="avatar mb-2" style="z-index: 2; cursor: pointer;">
<div
class="ring-accent ring-offset-accent bg-accent w-24 rounded-full border-0 ring ring-offset-1"
class="bg-accent w-24 rounded-full border-0 ring-offset-1"
>
<img
src={data.profile_picture || 'https://cdn-icons-png.flaticon.com/512/10628/10628885.png'}

View File

@@ -79,7 +79,7 @@
{/if}
</div>
<div class="grid flex-1 grid-cols-1 gap-4 md:grid-cols-2">
<div>
<div class="flex flex-col gap-2">
<p>
<strong>{first_name()}: </strong>
{#if editorMode}<input
@@ -141,7 +141,7 @@
{:else}{callMessageFunction(person.biological_sex as MessageKeys) ?? '-'}{/if}
</p>
</div>
<div>
<div class="flex flex-col gap-2">
<p>
<strong>{email()}:</strong>
{#if editorMode}<input
@@ -165,8 +165,8 @@
</p>
<p><strong>{id()}: </strong>{' ' + (person.id ?? '-')}</p>
<p><strong>Limit: </strong>{' ' + (person.limit ?? '-')}</p>
{#if editorMode && (person.google_id === undefined || person.google_id === null || person.google_id !== '')}
<button class="btn btn-accent-soft btn-sm">{create_invite_code()}</button>
{#if editorMode && (person.google_id === undefined || person.google_id === null || person.google_id === '')}
<button class="btn btn-soft btn-accent btn-m">{create_invite_code()}</button>
{/if}
</div>
</div>

View File

@@ -1,12 +1,10 @@
<script>
<script lang="ts">
export let show = false;
export let clicked = false;
</script>
{#if show}
<label for="my-drawer" class="btn btn-circle drawer-button swap swap-rotate">
<!-- this hidden checkbox controls the state -->
<input id="my-drawer" type="checkbox" class="drawer-toggle" />
<label for="my-drawer" class={"drawer-button btn btn-circle swap swap-rotate" + (clicked?" swap-active":"")}>
<!-- hamburger icon -->
<svg
class="swap-off fill-current"

View File

@@ -1,12 +1,11 @@
<script>
import { deleted_profiles, managed_profiles } from '$lib/paraglide/messages';
import { managed_profiles } from '$lib/paraglide/messages';
</script>
<div class="drawer-side">
<label for="my-drawer" aria-label="close sidebar" class="drawer-overlay"></label>
<ul class="menu bg-base-200 text-base-content min-h-full w-80 p-4">
<ul class="menu bg-base-200 text-base-content min-h-full w-80 p-4 gap-4 pt-16">
<!-- Sidebar content here -->
<li><button class="btn btn-soft btn-primary">{managed_profiles}</button></li>
<li><button class="btn btn-soft btn-primary">{deleted_profiles()}</button></li>
<li><button class="btn btn-primary">{managed_profiles()}</button></li>
</ul>
</div>

View File

@@ -6,14 +6,10 @@
import ThemeButton from '$lib/ThemeSelect.svelte';
import Logout from '$lib/Logout.svelte';
import { page } from '$app/state';
import HamburgerIcon from '$lib/sidebar/hamburgerIcon.svelte';
</script>
<ParaglideJS {i18n}>
{@render children()}
<div class="absolute top-2 left-2 flex flex-row items-center gap-2">
<HamburgerIcon show={!page.url.pathname.includes('login')} />
</div>
<div class="absolute top-2 right-2 flex flex-row items-center gap-2">
<ThemeButton />
<Logout show={!page.url.pathname.includes('login')} />

View File

@@ -25,6 +25,7 @@
import { tailwindClassToPixels } from '$lib/tailwindSizeToPx';
import type { Layout } from '$lib/graph/model';
import SideBar from '$lib/sidebar/sideBar.svelte';
import HamburgerIcon from '$lib/sidebar/hamburgerIcon.svelte';
let { data }: { data: Layout & { id: string } } = $props();
@@ -185,12 +186,15 @@
console.log('createPerson', createPerson);
console.log('relationshipStart', relationshipStart);
};
let sideBarOpen = $state(false);
</script>
<svelte:head>
<title>{title({ page: family_tree() })}</title>
</svelte:head>
<div class="drawer">
<!-- this hidden checkbox controls the state -->
<input id="my-drawer" type="checkbox" class="drawer-toggle" onchange={()=>{sideBarOpen = !sideBarOpen}}/>
<div style="height:100vh;" class="!bg-base-200 drawer-content flex flex-col">
<SvelteFlowProvider>
<SvelteFlow
@@ -237,3 +241,6 @@
</div>
<SideBar />
</div>
<div class="absolute top-2 left-2 flex flex-row items-center gap-2">
<HamburgerIcon clicked={sideBarOpen} show={true} />
</div>

View File

@@ -29,11 +29,6 @@ export const load: PageServerLoad = async (event: RequestEvent) => {
return {};
}
let already_loaded = event.cookies.get('already_loaded') ?? null;
if (already_loaded !== null) {
return {};
}
const storedState = event.cookies.get('google_oauth_state') ?? null;
const codeVerifier = event.cookies.get('google_code_verifier') ?? null;
const code = event.url.searchParams.get('code');
@@ -50,6 +45,17 @@ export const load: PageServerLoad = async (event: RequestEvent) => {
try {
tokens = await google.validateAuthorizationCode(code, codeVerifier);
} catch (e) {
let already_loaded = event.cookies.get('already_loaded') ?? null;
if (already_loaded !== null) {
event.cookies.delete('already_loaded', {
path: '/login/google/callback',
sameSite: 'lax',
httpOnly: true,
maxAge: 0,
secure: import.meta.env.PROD
});
return {};
}
return error(400, { message: 'Failed to validate authorization code with ' + e });
}

View File

@@ -34,6 +34,7 @@
let birth_date: HTMLInputElement;
let birth_date_value: HTMLInputElement;
onMount(() => {
if (birth_date) {
import('pikaday').then(({ default: Pikaday }) => {
const picker = new Pikaday({