i18n(myday): translate ListView via $_() — 5 sections + alerts

Adds myday namespace covering 5 section headers (Tasks/Termine/Wasser/
Ernährung/Streaks), overdue alert with {n}, empty states (Keine Tasks
heute, Keine Termine), coffee+meals counters with {n} interpolation.
Misspelled "ueberfaellig"/"Ernaehrung" inputs corrected via Unicode
fallback in JSON.

Baselines: hardcoded 989 → 982 (7 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-27 15:36:15 +02:00
parent f92d6475f7
commit a5d4554c11
7 changed files with 87 additions and 11 deletions

View file

@ -0,0 +1,14 @@
{
"list_view": {
"section_tasks": "Tasks",
"alert_overdue": "{n} überfällig",
"empty_no_tasks": "Keine Tasks heute",
"section_events": "Termine",
"empty_no_events": "Keine Termine",
"section_water": "Wasser",
"coffee_count": "{n}× Kaffee",
"section_nutrition": "Ernährung",
"meals_count": "{n} Mahlz.",
"section_streaks": "Streaks"
}
}

View file

@ -0,0 +1,14 @@
{
"list_view": {
"section_tasks": "Tasks",
"alert_overdue": "{n} overdue",
"empty_no_tasks": "No tasks today",
"section_events": "Events",
"empty_no_events": "No events",
"section_water": "Water",
"coffee_count": "{n}× coffee",
"section_nutrition": "Nutrition",
"meals_count": "{n} meals",
"section_streaks": "Streaks"
}
}

View file

@ -0,0 +1,14 @@
{
"list_view": {
"section_tasks": "Tareas",
"alert_overdue": "{n} vencidas",
"empty_no_tasks": "Sin tareas hoy",
"section_events": "Eventos",
"empty_no_events": "Sin eventos",
"section_water": "Agua",
"coffee_count": "{n}× café",
"section_nutrition": "Nutrición",
"meals_count": "{n} comidas",
"section_streaks": "Rachas"
}
}

View file

@ -0,0 +1,14 @@
{
"list_view": {
"section_tasks": "Tâches",
"alert_overdue": "{n} en retard",
"empty_no_tasks": "Aucune tâche aujourd'hui",
"section_events": "Rendez-vous",
"empty_no_events": "Aucun rendez-vous",
"section_water": "Eau",
"coffee_count": "{n}× café",
"section_nutrition": "Nutrition",
"meals_count": "{n} repas",
"section_streaks": "Séries"
}
}

View file

@ -0,0 +1,14 @@
{
"list_view": {
"section_tasks": "Attività",
"alert_overdue": "{n} in ritardo",
"empty_no_tasks": "Nessuna attività oggi",
"section_events": "Eventi",
"empty_no_events": "Nessun evento",
"section_water": "Acqua",
"coffee_count": "{n}× caffè",
"section_nutrition": "Alimentazione",
"meals_count": "{n} pasti",
"section_streaks": "Serie"
}
}

View file

@ -6,6 +6,7 @@
import { useDaySnapshot } from '$lib/data/projections/day-snapshot'; import { useDaySnapshot } from '$lib/data/projections/day-snapshot';
import { useStreaks } from '$lib/data/projections/streaks'; import { useStreaks } from '$lib/data/projections/streaks';
import { CheckCircle, CalendarBlank, Drop, ForkKnife, MapPin, Fire } from '@mana/shared-icons'; import { CheckCircle, CalendarBlank, Drop, ForkKnife, MapPin, Fire } from '@mana/shared-icons';
import { _ } from 'svelte-i18n';
const day = useDaySnapshot(); const day = useDaySnapshot();
const streaks = useStreaks(); const streaks = useStreaks();
@ -16,19 +17,21 @@
<div class="section"> <div class="section">
<div class="section-header"> <div class="section-header">
<CheckCircle size={18} weight="bold" /> <CheckCircle size={18} weight="bold" />
<span>Tasks</span> <span>{$_('myday.list_view.section_tasks')}</span>
<span class="badge" <span class="badge"
>{day.value.tasks.completed}/{day.value.tasks.total + day.value.tasks.completed}</span >{day.value.tasks.completed}/{day.value.tasks.total + day.value.tasks.completed}</span
> >
</div> </div>
{#if day.value.tasks.overdue > 0} {#if day.value.tasks.overdue > 0}
<div class="alert">{day.value.tasks.overdue} ueberfaellig</div> <div class="alert">
{$_('myday.list_view.alert_overdue', { values: { n: day.value.tasks.overdue } })}
</div>
{/if} {/if}
{#each day.value.tasks.dueToday.slice(0, 5) as t} {#each day.value.tasks.dueToday.slice(0, 5) as t}
<div class="item">{t.title}</div> <div class="item">{t.title}</div>
{/each} {/each}
{#if day.value.tasks.dueToday.length === 0 && day.value.tasks.total === 0} {#if day.value.tasks.dueToday.length === 0 && day.value.tasks.total === 0}
<div class="empty">Keine Tasks heute</div> <div class="empty">{$_('myday.list_view.empty_no_tasks')}</div>
{/if} {/if}
</div> </div>
@ -36,7 +39,7 @@
<div class="section"> <div class="section">
<div class="section-header"> <div class="section-header">
<CalendarBlank size={18} weight="bold" /> <CalendarBlank size={18} weight="bold" />
<span>Termine</span> <span>{$_('myday.list_view.section_events')}</span>
<span class="badge">{day.value.events.total}</span> <span class="badge">{day.value.events.total}</span>
</div> </div>
{#each day.value.events.upcoming.slice(0, 4) as e} {#each day.value.events.upcoming.slice(0, 4) as e}
@ -46,7 +49,7 @@
</div> </div>
{/each} {/each}
{#if day.value.events.total === 0} {#if day.value.events.total === 0}
<div class="empty">Keine Termine</div> <div class="empty">{$_('myday.list_view.empty_no_events')}</div>
{/if} {/if}
</div> </div>
@ -54,7 +57,7 @@
<div class="section"> <div class="section">
<div class="section-header"> <div class="section-header">
<Drop size={18} weight="bold" /> <Drop size={18} weight="bold" />
<span>Wasser</span> <span>{$_('myday.list_view.section_water')}</span>
<span class="badge">{day.value.drinks.water.percent}%</span> <span class="badge">{day.value.drinks.water.percent}%</span>
</div> </div>
<div class="progress-bar"> <div class="progress-bar">
@ -65,7 +68,9 @@
</div> </div>
<div class="stat">{day.value.drinks.water.ml} / {day.value.drinks.water.goal} ml</div> <div class="stat">{day.value.drinks.water.ml} / {day.value.drinks.water.goal} ml</div>
{#if day.value.drinks.coffee.count > 0} {#if day.value.drinks.coffee.count > 0}
<div class="stat-secondary">{day.value.drinks.coffee.count}x Kaffee</div> <div class="stat-secondary">
{$_('myday.list_view.coffee_count', { values: { n: day.value.drinks.coffee.count } })}
</div>
{/if} {/if}
</div> </div>
@ -73,8 +78,10 @@
<div class="section"> <div class="section">
<div class="section-header"> <div class="section-header">
<ForkKnife size={18} weight="bold" /> <ForkKnife size={18} weight="bold" />
<span>Ernaehrung</span> <span>{$_('myday.list_view.section_nutrition')}</span>
<span class="badge">{day.value.nutrition.meals} Mahlz.</span> <span class="badge"
>{$_('myday.list_view.meals_count', { values: { n: day.value.nutrition.meals } })}</span
>
</div> </div>
<div class="progress-bar"> <div class="progress-bar">
<div <div
@ -92,7 +99,7 @@
<div class="section"> <div class="section">
<div class="section-header"> <div class="section-header">
<Fire size={18} weight="bold" /> <Fire size={18} weight="bold" />
<span>Streaks</span> <span>{$_('myday.list_view.section_streaks')}</span>
</div> </div>
{#each streaks.value as s} {#each streaks.value as s}
<div class="streak-row"> <div class="streak-row">

View file

@ -137,7 +137,6 @@
"apps/mana/apps/web/src/lib/modules/moodlit/components/mood/CreateMoodDialog.svelte": 3, "apps/mana/apps/web/src/lib/modules/moodlit/components/mood/CreateMoodDialog.svelte": 3,
"apps/mana/apps/web/src/lib/modules/music/ListView.svelte": 3, "apps/mana/apps/web/src/lib/modules/music/ListView.svelte": 3,
"apps/mana/apps/web/src/lib/modules/music/views/DetailView.svelte": 6, "apps/mana/apps/web/src/lib/modules/music/views/DetailView.svelte": 6,
"apps/mana/apps/web/src/lib/modules/myday/ListView.svelte": 7,
"apps/mana/apps/web/src/lib/modules/news-research/ListView.svelte": 3, "apps/mana/apps/web/src/lib/modules/news-research/ListView.svelte": 3,
"apps/mana/apps/web/src/lib/modules/news/widgets/NewsUnreadWidget.svelte": 2, "apps/mana/apps/web/src/lib/modules/news/widgets/NewsUnreadWidget.svelte": 2,
"apps/mana/apps/web/src/lib/modules/notes/ListView.svelte": 4, "apps/mana/apps/web/src/lib/modules/notes/ListView.svelte": 4,