mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:21:10 +02:00
i18n(dreams): translate ListView via $_() — view tabs, insights, filters, editor, transcription badges
- View tabs (Träume/Symbole), insights ribbon, filter chips (Alle/Klarträume/Albträume/Wiederkehrend), search placeholder
- Inline editor: title placeholder, transcription status (transcribing/failed/done), content/symbols placeholders, sleep-row labels (Nacht/Ins Bett/Aufgewacht), sleep quality + star aria-label, Klartraum/Wiederkehrend toggles, Löschen/Fertig actions
- Dream-row: untitled fallback, transcribing/failed badge titles, STT-chip title
- FloatingInputBar placeholder + voice reason
- Mood labels routed through $_('dreams.moods.' + mood); MOOD_LABELS constant kept in types.ts for non-Svelte callers (SymbolDetailView)
- Context menu: edit/pin/unpin/delete via $_()
Baselines: hardcoded 1254 → 1242 (12 cleared); missing-keys baseline +1 (dreams.moods.* dynamic key).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3e41b14a31
commit
779752e907
3 changed files with 67 additions and 40 deletions
|
|
@ -18,6 +18,7 @@
|
|||
import { useItemContextMenu } from '$lib/data/item-context-menu.svelte';
|
||||
import { PencilSimple, PushPin, Trash } from '@mana/shared-icons';
|
||||
import SymbolsView from './views/SymbolsView.svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
let { navigate, goBack, params }: ViewProps = $props();
|
||||
|
||||
|
|
@ -139,7 +140,7 @@
|
|||
? [
|
||||
{
|
||||
id: 'edit',
|
||||
label: 'Bearbeiten',
|
||||
label: $_('dreams.list_view.ctx_edit'),
|
||||
icon: PencilSimple,
|
||||
action: () => {
|
||||
const target = ctxMenu.state.target;
|
||||
|
|
@ -148,7 +149,9 @@
|
|||
},
|
||||
{
|
||||
id: 'pin',
|
||||
label: ctxMenu.state.target.isPinned ? 'Lösen' : 'Pinnen',
|
||||
label: ctxMenu.state.target.isPinned
|
||||
? $_('dreams.list_view.ctx_unpin')
|
||||
: $_('dreams.list_view.ctx_pin'),
|
||||
icon: PushPin,
|
||||
action: () => {
|
||||
const target = ctxMenu.state.target;
|
||||
|
|
@ -158,7 +161,7 @@
|
|||
{ id: 'div', label: '', type: 'divider' as const },
|
||||
{
|
||||
id: 'delete',
|
||||
label: 'Löschen',
|
||||
label: $_('dreams.list_view.ctx_delete'),
|
||||
icon: Trash,
|
||||
variant: 'danger' as const,
|
||||
action: () => {
|
||||
|
|
@ -188,14 +191,14 @@
|
|||
<!-- View switcher -->
|
||||
<div class="view-tabs">
|
||||
<button class="view-tab" class:active={viewMode === 'list'} onclick={() => (viewMode = 'list')}>
|
||||
Träume
|
||||
{$_('dreams.list_view.tab_dreams')}
|
||||
</button>
|
||||
<button
|
||||
class="view-tab"
|
||||
class:active={viewMode === 'symbols'}
|
||||
onclick={() => (viewMode = 'symbols')}
|
||||
>
|
||||
Symbole
|
||||
{$_('dreams.list_view.tab_symbols')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -210,9 +213,15 @@
|
|||
<!-- Insights ribbon -->
|
||||
{#if insights.total > 0}
|
||||
<div class="insights">
|
||||
<span class="ins-stat">{insights.total} Träume</span>
|
||||
<span class="ins-stat"
|
||||
>{$_('dreams.list_view.insights_total', { values: { n: insights.total } })}</span
|
||||
>
|
||||
{#if insights.lucidCount > 0}
|
||||
<span class="ins-stat">✨ {insights.lucidCount} Klarträume</span>
|
||||
<span class="ins-stat"
|
||||
>{$_('dreams.list_view.insights_lucid', {
|
||||
values: { n: insights.lucidCount },
|
||||
})}</span
|
||||
>
|
||||
{/if}
|
||||
{#each insights.topSymbols as sym}
|
||||
<button
|
||||
|
|
@ -224,7 +233,9 @@
|
|||
</button>
|
||||
{/each}
|
||||
{#if symbolFilter}
|
||||
<button class="ins-clear" onclick={() => (symbolFilter = null)}>× Filter</button>
|
||||
<button class="ins-clear" onclick={() => (symbolFilter = null)}
|
||||
>{$_('dreams.list_view.clear_filter')}</button
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -237,28 +248,28 @@
|
|||
class:active={filterMode === 'all'}
|
||||
onclick={() => (filterMode = 'all')}
|
||||
>
|
||||
Alle
|
||||
{$_('dreams.list_view.filter_all')}
|
||||
</button>
|
||||
<button
|
||||
class="filter-tab"
|
||||
class:active={filterMode === 'lucid'}
|
||||
onclick={() => (filterMode = 'lucid')}
|
||||
>
|
||||
✨ Klarträume
|
||||
{$_('dreams.list_view.filter_lucid')}
|
||||
</button>
|
||||
<button
|
||||
class="filter-tab"
|
||||
class:active={filterMode === 'nightmare'}
|
||||
onclick={() => (filterMode = 'nightmare')}
|
||||
>
|
||||
Albträume
|
||||
{$_('dreams.list_view.filter_nightmare')}
|
||||
</button>
|
||||
<button
|
||||
class="filter-tab"
|
||||
class:active={filterMode === 'recurring'}
|
||||
onclick={() => (filterMode = 'recurring')}
|
||||
>
|
||||
Wiederkehrend
|
||||
{$_('dreams.list_view.filter_recurring')}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -268,7 +279,7 @@
|
|||
<input
|
||||
class="search-input"
|
||||
type="text"
|
||||
placeholder="Träume durchsuchen..."
|
||||
placeholder={$_('dreams.list_view.search_placeholder')}
|
||||
bind:value={searchQuery}
|
||||
/>
|
||||
{/if}
|
||||
|
|
@ -293,36 +304,40 @@
|
|||
class="ed-title"
|
||||
type="text"
|
||||
bind:value={editTitle}
|
||||
placeholder="Titel (optional)..."
|
||||
placeholder={$_('dreams.list_view.editor_title_placeholder')}
|
||||
autofocus
|
||||
/>
|
||||
{#if dream.processingStatus === 'transcribing'}
|
||||
<div class="ed-status">
|
||||
<span class="ed-status-dots">●●●</span>
|
||||
Transkribiert deine Aufnahme…
|
||||
{$_('dreams.list_view.editor_transcribing')}
|
||||
</div>
|
||||
{:else if dream.processingStatus === 'failed'}
|
||||
<div class="ed-status failed">
|
||||
Transkription fehlgeschlagen{dream.processingError
|
||||
{$_('dreams.list_view.editor_transcribe_failed')}{dream.processingError
|
||||
? `: ${dream.processingError}`
|
||||
: ''}
|
||||
</div>
|
||||
{:else if dream.transcript && dream.transcriptModel}
|
||||
<div class="ed-status muted" title="STT-Pipeline, die den Transkript erzeugt hat">
|
||||
Transkribiert via <strong>{dream.transcriptModel}</strong>
|
||||
<div
|
||||
class="ed-status muted"
|
||||
title={$_('dreams.list_view.editor_stt_pipeline_title')}
|
||||
>
|
||||
{$_('dreams.list_view.editor_transcribed_via')}
|
||||
<strong>{dream.transcriptModel}</strong>
|
||||
</div>
|
||||
{/if}
|
||||
<textarea
|
||||
class="ed-content"
|
||||
bind:value={editContent}
|
||||
placeholder="Erzähl mir den Traum..."
|
||||
placeholder={$_('dreams.list_view.editor_content_placeholder')}
|
||||
rows="5"
|
||||
></textarea>
|
||||
<input
|
||||
class="ed-symbols"
|
||||
type="text"
|
||||
bind:value={editSymbols}
|
||||
placeholder="Symbole (Komma-getrennt): Wasser, Fliegen, Tür"
|
||||
placeholder={$_('dreams.list_view.editor_symbols_placeholder')}
|
||||
/>
|
||||
|
||||
<div class="ed-row">
|
||||
|
|
@ -333,10 +348,10 @@
|
|||
class:active={editMood === mood}
|
||||
style="--mood-color: {MOOD_COLORS[mood]}"
|
||||
onclick={() => (editMood = editMood === mood ? null : mood)}
|
||||
title={MOOD_LABELS[mood]}
|
||||
title={$_('dreams.moods.' + mood)}
|
||||
>
|
||||
<span class="mood-dot"></span>
|
||||
{MOOD_LABELS[mood]}
|
||||
{$_('dreams.moods.' + mood)}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
@ -344,29 +359,31 @@
|
|||
|
||||
<div class="ed-row sleep-row">
|
||||
<label class="ed-field">
|
||||
<span class="ed-label">Nacht</span>
|
||||
<span class="ed-label">{$_('dreams.list_view.editor_label_night')}</span>
|
||||
<input type="date" bind:value={editDreamDate} class="ed-input-sm" />
|
||||
</label>
|
||||
<label class="ed-field">
|
||||
<span class="ed-label">Ins Bett</span>
|
||||
<span class="ed-label">{$_('dreams.list_view.editor_label_bedtime')}</span>
|
||||
<input type="time" bind:value={editBedtime} class="ed-input-sm" />
|
||||
</label>
|
||||
<label class="ed-field">
|
||||
<span class="ed-label">Aufgewacht</span>
|
||||
<span class="ed-label">{$_('dreams.list_view.editor_label_wake')}</span>
|
||||
<input type="time" bind:value={editWakeTime} class="ed-input-sm" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="ed-row">
|
||||
<div class="ed-field">
|
||||
<span class="ed-label">Schlafqualität</span>
|
||||
<span class="ed-label">{$_('dreams.list_view.editor_label_sleep_quality')}</span>
|
||||
<div class="stars">
|
||||
{#each [1, 2, 3, 4, 5] as q}
|
||||
<button
|
||||
class="star"
|
||||
class:filled={editSleepQuality !== null && editSleepQuality >= q}
|
||||
onclick={() => setSleepQuality(q as SleepQuality)}
|
||||
aria-label={`${q} Sterne`}
|
||||
aria-label={$_('dreams.list_view.editor_stars_aria', {
|
||||
values: { n: q },
|
||||
})}
|
||||
>
|
||||
★
|
||||
</button>
|
||||
|
|
@ -376,19 +393,22 @@
|
|||
<div class="toggles">
|
||||
<label class="lucid-toggle">
|
||||
<input type="checkbox" bind:checked={editIsLucid} />
|
||||
✨ Klartraum
|
||||
{$_('dreams.list_view.editor_lucid_toggle')}
|
||||
</label>
|
||||
<label class="lucid-toggle">
|
||||
<input type="checkbox" bind:checked={editIsRecurring} />
|
||||
↻ Wiederkehrend
|
||||
{$_('dreams.list_view.editor_recurring_toggle')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ed-actions">
|
||||
<button class="ed-btn danger" onclick={() => handleDelete(dream.id)}>Löschen</button
|
||||
<button class="ed-btn danger" onclick={() => handleDelete(dream.id)}
|
||||
>{$_('dreams.list_view.editor_action_delete')}</button
|
||||
>
|
||||
<button class="ed-btn primary" onclick={saveEdit}
|
||||
>{$_('dreams.list_view.editor_action_done')}</button
|
||||
>
|
||||
<button class="ed-btn primary" onclick={saveEdit}>Fertig</button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
|
|
@ -414,11 +434,18 @@
|
|||
|
||||
<div class="dream-content">
|
||||
<div class="dream-top">
|
||||
<span class="dream-title">{dream.title || 'Traum ohne Titel'}</span>
|
||||
<span class="dream-title">{dream.title || $_('dreams.list_view.untitled')}</span>
|
||||
{#if dream.processingStatus === 'transcribing'}
|
||||
<span class="badge transcribing" title="Wird transkribiert…">●●●</span>
|
||||
<span
|
||||
class="badge transcribing"
|
||||
title={$_('dreams.list_view.badge_transcribing_title')}>●●●</span
|
||||
>
|
||||
{:else if dream.processingStatus === 'failed'}
|
||||
<span class="badge failed" title={dream.processingError ?? 'Fehler'}>!</span>
|
||||
<span
|
||||
class="badge failed"
|
||||
title={dream.processingError ?? $_('dreams.list_view.badge_failed_title')}
|
||||
>!</span
|
||||
>
|
||||
{/if}
|
||||
{#if dream.isLucid}<span class="badge lucid">✨</span>{/if}
|
||||
{#if dream.isRecurring}<span class="badge">↻</span>{/if}
|
||||
|
|
@ -432,7 +459,7 @@
|
|||
<span>{formatDreamDate(dream.dreamDate)}</span>
|
||||
{#if dream.transcriptModel}
|
||||
<span class="dot">·</span>
|
||||
<span class="stt-chip" title="STT-Pipeline">
|
||||
<span class="stt-chip" title={$_('dreams.list_view.stt_chip_title')}>
|
||||
🎤 {dream.transcriptModel}
|
||||
</span>
|
||||
{/if}
|
||||
|
|
@ -461,21 +488,21 @@
|
|||
{/each}
|
||||
|
||||
{#if filtered.length === 0 && dreams.length > 0}
|
||||
<p class="empty">Keine Treffer</p>
|
||||
<p class="empty">{$_('dreams.list_view.empty_no_match')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if dreams.length === 0}
|
||||
<p class="empty">Erzähl deinen ersten Traum.</p>
|
||||
<p class="empty">{$_('dreams.list_view.empty_no_dreams')}</p>
|
||||
{/if}
|
||||
|
||||
<FloatingInputBar
|
||||
bind:value={newTitle}
|
||||
placeholder="Was hast du geträumt?"
|
||||
placeholder={$_('dreams.list_view.input_placeholder')}
|
||||
onSubmit={handleQuickCreate}
|
||||
voice
|
||||
voiceFeature="dreams-voice-capture"
|
||||
voiceReason="Sprach-Aufnahmen werden verschlüsselt in deinem persönlichen Tagebuch gespeichert. Dafür brauchst du ein Mana-Konto."
|
||||
voiceReason={$_('dreams.list_view.voice_reason')}
|
||||
onVoiceComplete={handleVoiceComplete}
|
||||
/>
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,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/ListView.svelte": 12,
|
||||
"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,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
"apps/mana/apps/web/src/lib/modules/ai-agents/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/ai-missions/ListView.svelte": 2,
|
||||
"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/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