refactor(ui): rename route /korrespondenz → /briefwechsel

Update all internal links (AppNav, CoCorrespondentsList, goto) to the
new URL. No redirect needed — no production URLs exist yet.

Refs: #179

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-06 19:22:22 +02:00
parent a863f8baad
commit a9228d156f
13 changed files with 6 additions and 6 deletions

View File

@@ -0,0 +1,129 @@
<script lang="ts">
import PersonTypeahead from '$lib/components/PersonTypeahead.svelte';
import CorrespondentSuggestionsDropdown from './CorrespondentSuggestionsDropdown.svelte';
interface Props {
senderId?: string;
receiverId?: string;
initialSenderName?: string;
initialReceiverName?: string;
onapplyFilters: () => void;
onswapPersons: () => void;
}
let {
senderId = $bindable(''),
receiverId = $bindable(''),
initialSenderName = '',
initialReceiverName = '',
onapplyFilters,
onswapPersons
}: Props = $props();
interface Correspondent {
id: string;
firstName: string;
lastName: string;
}
let swapVisible = $derived(!!(senderId && receiverId));
let showSuggestions = $state(false);
let correspondents = $state<Correspondent[]>([]);
let loadingCorrespondents = $state(false);
async function handleCorrespondentFocused() {
if (!senderId) return;
showSuggestions = true;
loadingCorrespondents = true;
try {
const res = await fetch(`/api/persons/${senderId}/correspondents`);
correspondents = res.ok ? await res.json() : [];
} catch {
correspondents = [];
} finally {
loadingCorrespondents = false;
}
}
function handleSuggestionSelect(id: string) {
receiverId = id;
showSuggestions = false;
onapplyFilters();
}
</script>
<div class="flex items-end gap-[9px] border-b border-line bg-surface px-4 py-[9px] sm:px-[18px]">
<!-- Person A -->
<div class="min-w-0 flex-1">
<PersonTypeahead
name="senderId"
label="Person"
bind:value={senderId}
initialName={initialSenderName}
compact={true}
restrictToCorrespondentsOf={receiverId || undefined}
onchange={() => onapplyFilters()}
/>
</div>
<!-- Swap button -->
<button
data-testid="conv-swap-btn"
type="button"
aria-label="Personen tauschen"
onclick={onswapPersons}
class="flex h-9 w-9 shrink-0 items-center justify-center rounded border border-line bg-surface text-ink-3 transition-colors hover:border-primary hover:text-primary"
class:opacity-0={!swapVisible}
class:pointer-events-none={!swapVisible}
tabindex={swapVisible ? 0 : -1}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M7 16V4m0 0L3 8m4-4l4 4" />
<path d="M17 8v12m0 0l4-4m-4 4l-4-4" />
</svg>
</button>
<!-- Korrespondent field -->
<div
class="relative min-w-0 flex-1"
class:[&_input]:border-dashed={!receiverId}
class:[&_input]:border-solid={!!receiverId}
class:[&_input]:bg-canvas={!receiverId}
>
<PersonTypeahead
name="receiverId"
label={receiverId ? 'Korrespondent' : 'Korrespondent — optional'}
bind:value={receiverId}
initialName={initialReceiverName}
compact={true}
placeholder="Alle Korrespondenten"
restrictToCorrespondentsOf={senderId || undefined}
onchange={() => {
showSuggestions = false;
onapplyFilters();
}}
onfocused={handleCorrespondentFocused}
/>
{#if showSuggestions && senderId && !receiverId}
<CorrespondentSuggestionsDropdown
correspondents={correspondents}
loading={loadingCorrespondents}
senderName=""
onselect={handleSuggestionSelect}
onclose={() => (showSuggestions = false)}
/>
{/if}
</div>
</div>