mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:41:09 +02:00
i18n(dreams): translate SymbolDetailView via $_() — header, merge dialog, sections, dream list
- Back button (← Symbole), Gespeichert hint, Zusammenführen…/Löschen actions
- Merge panel: label with {name} interpolation, "– Symbol wählen –" placeholder, OK/Abbrechen
- Empty: "Symbol nicht gefunden."
- Editable header: name placeholder, "Traum"/"Träume" via count_singular/plural
- Color picker: aria with {color} interpolation
- 4 section labels (Meine Bedeutung / Stimmungs-Verteilung / Häufig zusammen mit / Träume mit diesem Symbol) + meaning placeholder
- Mood label routed via $_('dreams.moods.' + mood) with valid-mood guard; "Unbekannt" fallback via symbol_detail.mood_unknown
- Co-occurring chip title with {name} interpolation
- Confirms: delete + merge with {name}/{source}/{target} interpolation
- Dream-ref title fallback via dreams.list_view.untitled
- MOOD_LABELS import dropped (constant kept in types.ts for non-Svelte callers)
Baselines: hardcoded 1074 → 1066 (8 cleared); missing-keys baseline +0 (dreams.moods.* dynamic key already baselined).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2491649767
commit
258edaa07d
3 changed files with 42 additions and 25 deletions
|
|
@ -12,7 +12,8 @@
|
|||
useAllDreamSymbols,
|
||||
} from '../queries';
|
||||
import { dreamsStore } from '../stores/dreams.svelte';
|
||||
import { MOOD_COLORS, MOOD_LABELS, type Dream, type DreamMood } from '../types';
|
||||
import { MOOD_COLORS, type Dream, type DreamMood } from '../types';
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
let {
|
||||
symbolId,
|
||||
|
|
@ -107,7 +108,7 @@
|
|||
async function handleDelete() {
|
||||
if (!symbol) return;
|
||||
const ok = confirm(
|
||||
`Symbol "${symbol.name}" wirklich löschen? Es wird aus allen Träumen entfernt.`
|
||||
$_('dreams.symbol_detail.confirm_delete', { values: { name: symbol.name } })
|
||||
);
|
||||
if (!ok) return;
|
||||
await dreamsStore.deleteSymbol(symbol.id);
|
||||
|
|
@ -119,7 +120,9 @@
|
|||
const target = symbols.find((s) => s.id === mergeTargetId);
|
||||
if (!target) return;
|
||||
const ok = confirm(
|
||||
`"${symbol.name}" in "${target.name}" zusammenführen? Alle Träume werden umgeschrieben.`
|
||||
$_('dreams.symbol_detail.confirm_merge', {
|
||||
values: { source: symbol.name, target: target.name },
|
||||
})
|
||||
);
|
||||
if (!ok) return;
|
||||
await dreamsStore.mergeSymbols(symbol.id, mergeTargetId);
|
||||
|
|
@ -139,45 +142,54 @@
|
|||
}
|
||||
|
||||
function moodLabel(mood: string): string {
|
||||
if (mood in MOOD_LABELS) return MOOD_LABELS[mood as DreamMood];
|
||||
return 'Unbekannt';
|
||||
const valid: DreamMood[] = ['angenehm', 'neutral', 'unangenehm', 'albtraum'];
|
||||
if (valid.includes(mood as DreamMood)) return $_('dreams.moods.' + mood);
|
||||
return $_('dreams.symbol_detail.mood_unknown');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="detail-view">
|
||||
<div class="header">
|
||||
<button class="back-btn" onclick={onBack}>← Symbole</button>
|
||||
<button class="back-btn" onclick={onBack}>{$_('dreams.symbol_detail.back')}</button>
|
||||
<div class="header-actions">
|
||||
{#if savedHint}
|
||||
<span class="saved-hint">Gespeichert</span>
|
||||
<span class="saved-hint">{$_('dreams.symbol_detail.saved')}</span>
|
||||
{/if}
|
||||
{#if symbol && mergeCandidates.length > 0}
|
||||
<button class="meta-btn" onclick={() => (mergeOpen = !mergeOpen)}>Zusammenführen…</button>
|
||||
<button class="meta-btn" onclick={() => (mergeOpen = !mergeOpen)}
|
||||
>{$_('dreams.symbol_detail.action_merge')}</button
|
||||
>
|
||||
{/if}
|
||||
{#if symbol}
|
||||
<button class="del-btn" onclick={handleDelete}>Löschen</button>
|
||||
<button class="del-btn" onclick={handleDelete}
|
||||
>{$_('dreams.symbol_detail.action_delete')}</button
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if mergeOpen && symbol}
|
||||
<div class="merge-panel">
|
||||
<span class="merge-label">"{symbol.name}" zusammenführen mit:</span>
|
||||
<span class="merge-label"
|
||||
>{$_('dreams.symbol_detail.merge_label', { values: { name: symbol.name } })}</span
|
||||
>
|
||||
<select class="merge-select" bind:value={mergeTargetId}>
|
||||
<option value="">– Symbol wählen –</option>
|
||||
<option value="">{$_('dreams.symbol_detail.merge_select_default')}</option>
|
||||
{#each mergeCandidates as c}
|
||||
<option value={c.id}>{c.name} ({c.count})</option>
|
||||
{/each}
|
||||
</select>
|
||||
<button class="merge-confirm" disabled={!mergeTargetId} onclick={handleMerge}>OK</button>
|
||||
<button class="merge-confirm" disabled={!mergeTargetId} onclick={handleMerge}
|
||||
>{$_('dreams.symbol_detail.merge_confirm')}</button
|
||||
>
|
||||
<button class="merge-cancel" onclick={() => ((mergeOpen = false), (mergeTargetId = ''))}
|
||||
>Abbrechen</button
|
||||
>{$_('dreams.symbol_detail.merge_cancel')}</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !symbol}
|
||||
<p class="empty">Symbol nicht gefunden.</p>
|
||||
<p class="empty">{$_('dreams.symbol_detail.empty_not_found')}</p>
|
||||
{:else}
|
||||
<!-- Editable header -->
|
||||
<div class="sym-header">
|
||||
|
|
@ -185,10 +197,15 @@
|
|||
class="name-input"
|
||||
type="text"
|
||||
bind:value={editName}
|
||||
placeholder="Symbolname"
|
||||
placeholder={$_('dreams.symbol_detail.name_placeholder')}
|
||||
style="color: {editColor}"
|
||||
/>
|
||||
<span class="count-badge">{symbol.count} {symbol.count === 1 ? 'Traum' : 'Träume'}</span>
|
||||
<span class="count-badge"
|
||||
>{symbol.count}
|
||||
{symbol.count === 1
|
||||
? $_('dreams.symbol_detail.count_singular')
|
||||
: $_('dreams.symbol_detail.count_plural')}</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Color picker -->
|
||||
|
|
@ -199,18 +216,18 @@
|
|||
class:active={editColor === color}
|
||||
style="background: {color}"
|
||||
onclick={() => (editColor = color)}
|
||||
aria-label={`Farbe ${color}`}
|
||||
aria-label={$_('dreams.symbol_detail.color_aria', { values: { color } })}
|
||||
></button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Meaning -->
|
||||
<div class="section">
|
||||
<span class="section-label">Meine Bedeutung</span>
|
||||
<span class="section-label">{$_('dreams.symbol_detail.label_meaning')}</span>
|
||||
<textarea
|
||||
class="meaning-input"
|
||||
bind:value={editMeaning}
|
||||
placeholder="Was bedeutet dieses Symbol für dich? (optional)"
|
||||
placeholder={$_('dreams.symbol_detail.meaning_placeholder')}
|
||||
rows="3"
|
||||
></textarea>
|
||||
</div>
|
||||
|
|
@ -218,7 +235,7 @@
|
|||
<!-- Mood distribution -->
|
||||
{#if moodDist.length > 0}
|
||||
<div class="section">
|
||||
<span class="section-label">Stimmungs-Verteilung</span>
|
||||
<span class="section-label">{$_('dreams.symbol_detail.label_mood_dist')}</span>
|
||||
<div class="bars">
|
||||
{#each moodDist as m}
|
||||
<div class="bar-row">
|
||||
|
|
@ -239,13 +256,13 @@
|
|||
<!-- Co-occurring -->
|
||||
{#if cooccurring.length > 0}
|
||||
<div class="section">
|
||||
<span class="section-label">Häufig zusammen mit</span>
|
||||
<span class="section-label">{$_('dreams.symbol_detail.label_cooccurring')}</span>
|
||||
<div class="cooc-row">
|
||||
{#each cooccurring as c}
|
||||
<button
|
||||
class="cooc-chip"
|
||||
onclick={() => navigateToCooccurring(c.name)}
|
||||
title={`Zu "${c.name}" wechseln`}
|
||||
title={$_('dreams.symbol_detail.cooccurring_title', { values: { name: c.name } })}
|
||||
>
|
||||
{c.name} <span class="cooc-count">{c.count}</span>
|
||||
</button>
|
||||
|
|
@ -257,7 +274,7 @@
|
|||
<!-- Dream list -->
|
||||
{#if dreamsWithSymbol.length > 0}
|
||||
<div class="section">
|
||||
<span class="section-label">Träume mit diesem Symbol</span>
|
||||
<span class="section-label">{$_('dreams.symbol_detail.label_dream_list')}</span>
|
||||
<div class="dream-refs">
|
||||
{#each dreamsWithSymbol as d (d.id)}
|
||||
<button class="dream-ref" onclick={() => onOpenDream?.(d)} disabled={!onOpenDream}>
|
||||
|
|
@ -267,7 +284,7 @@
|
|||
<span class="ref-dot empty"></span>
|
||||
{/if}
|
||||
<div class="ref-content">
|
||||
<span class="ref-title">{d.title || 'Traum ohne Titel'}</span>
|
||||
<span class="ref-title">{d.title || $_('dreams.list_view.untitled')}</span>
|
||||
<span class="ref-date">{formatDreamDate(d.dreamDate)}</span>
|
||||
</div>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@
|
|||
"apps/mana/apps/web/src/lib/modules/core/widgets/RecentContactsWidget.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/TasksTodayWidget.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/UpcomingEventsWidget.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/dreams/views/SymbolDetailView.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/drink/ListView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/finance/ListView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/goals/ListView.svelte": 1,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"apps/mana/apps/web/src/lib/modules/broadcast/views/DetailView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/credits/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/dreams/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/dreams/views/SymbolDetailView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/firsts/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/components/StatusBadge.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/constants.ts": 1,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue