refactor(persons): extract PersonCard, PersonMergePanel, CoCorrespondentsList, PersonDocumentList
Some checks failed
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
Some checks failed
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
Split the 610-line person detail page into four focused co-located components:
- PersonCard: view/edit card with inline form (owns editMode)
- PersonMergePanel: merge target typeahead + two-step confirm (state reset via {#key})
- CoCorrespondentsList: frequency-ranked correspondent chips linking to conversations
- PersonDocumentList: reusable sorted/paginated document list (used for sent + received)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
83
frontend/src/routes/persons/[id]/PersonMergePanel.svelte
Normal file
83
frontend/src/routes/persons/[id]/PersonMergePanel.svelte
Normal file
@@ -0,0 +1,83 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
import PersonTypeahead from '$lib/components/PersonTypeahead.svelte';
|
||||
import { m } from '$lib/paraglide/messages.js';
|
||||
|
||||
let {
|
||||
person,
|
||||
form
|
||||
}: {
|
||||
person: { firstName: string; lastName: string };
|
||||
form?: { mergeError?: string } | null;
|
||||
} = $props();
|
||||
|
||||
let mergeTargetId = $state('');
|
||||
let showMergeConfirm = $state(false);
|
||||
</script>
|
||||
|
||||
<div class="mb-10 overflow-hidden rounded-sm border border-line bg-surface shadow-sm">
|
||||
<div class="p-6 md:p-8">
|
||||
<h2 class="mb-1 font-serif text-lg text-ink">{m.person_merge_heading()}</h2>
|
||||
<p class="mb-5 font-sans text-sm text-ink-2">
|
||||
{m.person_merge_description()}
|
||||
</p>
|
||||
|
||||
{#if form?.mergeError}
|
||||
<p class="mb-4 rounded border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600">
|
||||
{form.mergeError}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<form method="POST" action="?/merge" use:enhance>
|
||||
<input type="hidden" name="targetPersonId" bind:value={mergeTargetId} />
|
||||
|
||||
<div class="flex flex-col items-end gap-3 sm:flex-row">
|
||||
<div class="flex-1">
|
||||
<PersonTypeahead
|
||||
name="_targetPersonDisplay"
|
||||
label={m.person_merge_target_label()}
|
||||
value={mergeTargetId}
|
||||
onchange={(value) => {
|
||||
mergeTargetId = value;
|
||||
showMergeConfirm = false;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if !showMergeConfirm}
|
||||
<button
|
||||
type="button"
|
||||
disabled={!mergeTargetId}
|
||||
onclick={() => (showMergeConfirm = true)}
|
||||
class="rounded border border-red-300 px-4 py-2 text-sm font-bold tracking-widest text-red-600 uppercase transition-colors hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-40"
|
||||
>
|
||||
{m.person_btn_merge()}
|
||||
</button>
|
||||
{:else}
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
type="submit"
|
||||
class="rounded bg-red-600 px-4 py-2 text-sm font-bold tracking-widest text-white uppercase transition-colors hover:bg-red-700"
|
||||
>
|
||||
{m.person_btn_merge_confirm()}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (showMergeConfirm = false)}
|
||||
class="rounded border border-line px-4 py-2 text-sm font-bold tracking-widest text-ink-2 uppercase transition-colors hover:bg-muted"
|
||||
>
|
||||
{m.btn_cancel()}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if showMergeConfirm}
|
||||
<p class="mt-3 rounded border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
|
||||
{m.person_merge_warning()} <strong>{person.firstName} {person.lastName}</strong>
|
||||
{m.person_merge_will_be_deleted()}
|
||||
</p>
|
||||
{/if}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user