Files
familienarchiv/frontend/src/routes/persons/[id]/PersonRelationshipsCard.svelte
2026-04-28 19:32:17 +02:00

76 lines
2.5 KiB
Svelte

<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
import { chipLabel, otherName, inferredRelationshipLabel } from '$lib/relationshipLabels';
import type { components } from '$lib/generated/api';
type RelationshipDTO = components['schemas']['RelationshipDTO'];
type InferredRelationshipWithPersonDTO = components['schemas']['InferredRelationshipWithPersonDTO'];
interface Props {
personId: string;
relationships: RelationshipDTO[];
inferredRelationships: InferredRelationshipWithPersonDTO[];
}
let { personId, relationships, inferredRelationships }: Props = $props();
const directOtherIds = $derived(new Set(relationships.map((rel) => otherId(rel))));
const topDerived = $derived(
inferredRelationships.filter((d) => !directOtherIds.has(d.person.id)).slice(0, 5)
);
function otherId(rel: RelationshipDTO): string {
return rel.personId === personId ? rel.relatedPersonId : rel.personId;
}
</script>
<div class="rounded-sm border border-line bg-surface p-6 shadow-sm">
<h2 class="mb-5 text-xs font-bold tracking-widest text-ink-3 uppercase">
{m.person_relationships_heading()}
</h2>
{#if relationships.length === 0 && topDerived.length === 0}
<p class="font-serif text-sm text-ink-2 italic">{m.person_relationships_empty()}</p>
{:else}
{#if relationships.length > 0}
<ul class="mb-4 space-y-2">
{#each relationships as rel (rel.id)}
<li class="flex items-center gap-2">
<span
class="inline-flex shrink-0 items-center rounded-full border border-accent/40 bg-accent/15 px-2 py-0.5 font-sans text-xs font-bold tracking-widest text-ink uppercase"
>
{chipLabel(rel, personId)}
</span>
<a
href="/persons/{otherId(rel)}"
class="min-w-0 flex-1 truncate font-serif text-sm text-ink hover:underline"
>
{otherName(rel, personId)}
</a>
</li>
{/each}
</ul>
{/if}
{#if topDerived.length > 0}
<ul class="space-y-2">
{#each topDerived as derived (derived.person.id)}
<li class="flex items-center gap-2">
<span
class="inline-flex shrink-0 items-center rounded-full border border-line bg-muted/50 px-2 py-0.5 font-sans text-xs font-bold tracking-widest text-ink-2 uppercase"
>
{inferredRelationshipLabel(derived.label)}
</span>
<a
href="/persons/{derived.person.id}"
class="min-w-0 flex-1 truncate font-serif text-sm text-ink-2 hover:underline"
>
{derived.person.displayName}
</a>
</li>
{/each}
</ul>
{/if}
{/if}
</div>