mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:01:09 +02:00
i18n(stretch): wire components to namespace — 34 strings cleared
Patches ListView, AssessmentWizard, ReminderManager, RoutineCreator,
SessionHistory, SessionPlayer, plus the /stretch route page title.
Locale JSONs landed in 421663ba3.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
421663ba3d
commit
722fe74ced
8 changed files with 164 additions and 76 deletions
|
|
@ -3,6 +3,7 @@
|
|||
Streak, quick-start routines, assessment recommendation, recent sessions.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { formatDate } from '$lib/i18n/format';
|
||||
import {
|
||||
useAllStretchExercises,
|
||||
|
|
@ -99,17 +100,17 @@
|
|||
<button
|
||||
class="tab"
|
||||
class:active={activeTab === 'dashboard'}
|
||||
onclick={() => (activeTab = 'dashboard')}>Dashboard</button
|
||||
onclick={() => (activeTab = 'dashboard')}>{$_('stretch.list_view.tab_dashboard')}</button
|
||||
>
|
||||
<button
|
||||
class="tab"
|
||||
class:active={activeTab === 'routines'}
|
||||
onclick={() => (activeTab = 'routines')}>Routinen</button
|
||||
onclick={() => (activeTab = 'routines')}>{$_('stretch.list_view.tab_routines')}</button
|
||||
>
|
||||
<button
|
||||
class="tab"
|
||||
class:active={activeTab === 'exercises'}
|
||||
onclick={() => (activeTab = 'exercises')}>Übungen</button
|
||||
onclick={() => (activeTab = 'exercises')}>{$_('stretch.list_view.tab_exercises')}</button
|
||||
>
|
||||
</div>
|
||||
|
||||
|
|
@ -118,15 +119,15 @@
|
|||
<div class="stats-row">
|
||||
<div class="stat-card">
|
||||
<span class="stat-value">{streak}</span>
|
||||
<span class="stat-label">Tage Streak</span>
|
||||
<span class="stat-label">{$_('stretch.list_view.stat_streak')}</span>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<span class="stat-value">{todayMinutes}</span>
|
||||
<span class="stat-label">Min heute</span>
|
||||
<span class="stat-label">{$_('stretch.list_view.stat_today')}</span>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<span class="stat-value">{weekCount}</span>
|
||||
<span class="stat-label">Diese Woche</span>
|
||||
<span class="stat-label">{$_('stretch.list_view.stat_week')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -145,13 +146,17 @@
|
|||
<!-- Quick Start -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<span class="section-title">Schnellstart</span>
|
||||
<span class="section-title">{$_('stretch.list_view.section_quickstart')}</span>
|
||||
</div>
|
||||
<div class="routine-grid">
|
||||
{#each pinnedRoutines as routine (routine.id)}
|
||||
<button class="routine-card" onclick={() => startRoutine(routine.id)}>
|
||||
<span class="routine-name">{routine.name}</span>
|
||||
<span class="routine-meta">{routine.estimatedDurationMin} Min</span>
|
||||
<span class="routine-meta"
|
||||
>{$_('stretch.list_view.routine_minutes', {
|
||||
values: { count: routine.estimatedDurationMin },
|
||||
})}</span
|
||||
>
|
||||
<span class="routine-type"
|
||||
>{ROUTINE_TYPE_LABELS[routine.routineType]?.de ?? routine.routineType}</span
|
||||
>
|
||||
|
|
@ -165,26 +170,42 @@
|
|||
<div class="recommendation">
|
||||
<div class="rec-header">
|
||||
{#if weakAreas.length > 0}
|
||||
<span class="rec-title">Empfohlen für dich</span>
|
||||
<span class="rec-title">{$_('stretch.list_view.rec_title_for_you')}</span>
|
||||
<span class="rec-detail">
|
||||
Schwachstellen: {weakAreas.map((r) => BODY_REGION_LABELS[r]?.de ?? r).join(', ')}
|
||||
{$_('stretch.list_view.rec_weak_areas', {
|
||||
values: {
|
||||
areas: weakAreas.map((r) => BODY_REGION_LABELS[r]?.de ?? r).join(', '),
|
||||
},
|
||||
})}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="rec-title">Vorschlag</span>
|
||||
<span class="rec-title">{$_('stretch.list_view.rec_title_suggestion')}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<button class="rec-btn" onclick={() => startRoutine(recommended.id)}>
|
||||
{recommended.name} starten ({recommended.estimatedDurationMin} Min)
|
||||
{$_('stretch.list_view.rec_btn_start', {
|
||||
values: {
|
||||
name: recommended.name,
|
||||
minutes: recommended.estimatedDurationMin,
|
||||
},
|
||||
})}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Assessment CTA -->
|
||||
<button class="action-btn" onclick={() => (showAssessment = true)}>
|
||||
{latestAssessment ? 'Bestandsaufnahme wiederholen' : 'Erste Bestandsaufnahme starten'}
|
||||
{latestAssessment
|
||||
? $_('stretch.list_view.assessment_btn_repeat')
|
||||
: $_('stretch.list_view.assessment_btn_first')}
|
||||
{#if latestAssessment}
|
||||
<span class="action-meta"
|
||||
>Letzte: {relativeDays(latestAssessment.assessedAt)} — Score: {latestAssessment.overallScore}%</span
|
||||
>{$_('stretch.list_view.assessment_meta', {
|
||||
values: {
|
||||
when: relativeDays(latestAssessment.assessedAt),
|
||||
score: latestAssessment.overallScore,
|
||||
},
|
||||
})}</span
|
||||
>
|
||||
{/if}
|
||||
</button>
|
||||
|
|
@ -193,13 +214,19 @@
|
|||
{#if todaySessions.length > 0}
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<span class="section-title">Heute</span>
|
||||
<button class="link-btn" onclick={() => (showHistory = true)}>Alle</button>
|
||||
<span class="section-title">{$_('stretch.list_view.section_today')}</span>
|
||||
<button class="link-btn" onclick={() => (showHistory = true)}
|
||||
>{$_('stretch.list_view.section_all_link')}</button
|
||||
>
|
||||
</div>
|
||||
{#each todaySessions.slice(0, 3) as session (session.id)}
|
||||
<div class="session-row">
|
||||
<span class="session-name">{session.routineName}</span>
|
||||
<span class="session-duration">{Math.round(session.totalDurationSec / 60)} Min</span>
|
||||
<span class="session-duration"
|
||||
>{$_('stretch.list_view.routine_minutes', {
|
||||
values: { count: Math.round(session.totalDurationSec / 60) },
|
||||
})}</span
|
||||
>
|
||||
<span class="session-time">{session.startedAt.split('T')[1]?.slice(0, 5)}</span>
|
||||
</div>
|
||||
{/each}
|
||||
|
|
@ -208,8 +235,12 @@
|
|||
|
||||
<!-- Quick Actions -->
|
||||
<div class="quick-actions">
|
||||
<button class="action-link" onclick={() => (showReminders = true)}>Erinnerungen</button>
|
||||
<button class="action-link" onclick={() => (showHistory = true)}>Verlauf</button>
|
||||
<button class="action-link" onclick={() => (showReminders = true)}
|
||||
>{$_('stretch.list_view.action_reminders')}</button
|
||||
>
|
||||
<button class="action-link" onclick={() => (showHistory = true)}
|
||||
>{$_('stretch.list_view.action_history')}</button
|
||||
>
|
||||
</div>
|
||||
{:else if activeTab === 'routines'}
|
||||
<!-- All Routines -->
|
||||
|
|
@ -221,13 +252,17 @@
|
|||
<span class="rli-desc">{routine.description}</span>
|
||||
</div>
|
||||
<div class="rli-right">
|
||||
<span class="rli-duration">{routine.estimatedDurationMin} Min</span>
|
||||
<span class="rli-duration"
|
||||
>{$_('stretch.list_view.routine_minutes', {
|
||||
values: { count: routine.estimatedDurationMin },
|
||||
})}</span
|
||||
>
|
||||
<span class="rli-type">{ROUTINE_TYPE_LABELS[routine.routineType]?.de ?? ''}</span>
|
||||
</div>
|
||||
</button>
|
||||
{/each}
|
||||
<button class="add-routine-btn" onclick={() => (showCreateRoutine = true)}>
|
||||
+ Eigene Routine erstellen
|
||||
{$_('stretch.list_view.action_create_routine')}
|
||||
</button>
|
||||
</div>
|
||||
{:else if activeTab === 'exercises'}
|
||||
|
|
@ -243,7 +278,9 @@
|
|||
<span class="ex-region">{BODY_REGION_LABELS[ex.bodyRegion]?.de ?? ex.bodyRegion}</span
|
||||
>
|
||||
<span class="ex-duration"
|
||||
>{ex.defaultDurationSec}s{ex.bilateral ? ' /Seite' : ''}</span
|
||||
>{ex.defaultDurationSec}s{ex.bilateral
|
||||
? $_('stretch.list_view.side_suffix')
|
||||
: ''}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
6 tests with score selection, pain region marking, and result summary.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { _ } from 'svelte-i18n';
|
||||
import {
|
||||
ASSESSMENT_TESTS,
|
||||
BODY_REGION_LABELS,
|
||||
|
|
@ -106,7 +107,11 @@
|
|||
{currentStep === 0 && !showResults ? '×' : '←'}
|
||||
</button>
|
||||
<span class="step-label">
|
||||
{showResults ? 'Ergebnis' : `Schritt ${currentStep + 1} von ${totalSteps}`}
|
||||
{showResults
|
||||
? $_('stretch.assessment.result_label')
|
||||
: $_('stretch.assessment.step_label', {
|
||||
values: { current: currentStep + 1, total: totalSteps },
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
|
@ -120,7 +125,7 @@
|
|||
<div class="results-screen">
|
||||
<div class="score-circle">
|
||||
<span class="score-value">{overallScore()}%</span>
|
||||
<span class="score-label">Beweglichkeit</span>
|
||||
<span class="score-label">{$_('stretch.assessment.score_label')}</span>
|
||||
</div>
|
||||
|
||||
<div class="results-grid">
|
||||
|
|
@ -143,7 +148,7 @@
|
|||
|
||||
{#if weakAreas().length > 0}
|
||||
<div class="weak-notice">
|
||||
<span class="weak-title">Verbesserungsbedarf:</span>
|
||||
<span class="weak-title">{$_('stretch.assessment.weak_title')}</span>
|
||||
<span class="weak-areas">
|
||||
{weakAreas()
|
||||
.map((r) => BODY_REGION_LABELS[r]?.de ?? r)
|
||||
|
|
@ -154,7 +159,7 @@
|
|||
|
||||
<!-- Pain Regions (optional) -->
|
||||
<div class="pain-section">
|
||||
<span class="pain-title">Schmerzbereiche (optional)</span>
|
||||
<span class="pain-title">{$_('stretch.assessment.pain_title')}</span>
|
||||
<div class="pain-add-row">
|
||||
<select class="pain-select" bind:value={painRegion}>
|
||||
{#each BODY_REGIONS.filter((r) => r !== 'full_body') as region}
|
||||
|
|
@ -173,7 +178,9 @@
|
|||
{/each}
|
||||
</div>
|
||||
|
||||
<button class="save-btn" onclick={saveAndFinish}>Speichern</button>
|
||||
<button class="save-btn" onclick={saveAndFinish}
|
||||
>{$_('stretch.assessment.action_save')}</button
|
||||
>
|
||||
</div>
|
||||
{:else if currentTest}
|
||||
<!-- Test Step -->
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
ReminderManager — Configure stretch reminders (time, days, linked routine).
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { untrack } from 'svelte';
|
||||
import type { StretchReminder, StretchRoutine } from '../types';
|
||||
import { stretchStore } from '../stores/stretch.svelte';
|
||||
|
||||
|
|
@ -14,12 +16,20 @@
|
|||
let { reminders, routines, onClose }: Props = $props();
|
||||
|
||||
let showCreate = $state(false);
|
||||
let newName = $state('Dehn-Erinnerung');
|
||||
let newName = $state(untrack(() => $_('stretch.reminders.default_name')));
|
||||
let newTime = $state('09:00');
|
||||
let newDays = $state<number[]>([1, 2, 3, 4, 5]); // Mon–Fri
|
||||
let newRoutineId = $state<string | null>(null);
|
||||
|
||||
const DAY_LABELS = ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'];
|
||||
const DAY_LABELS = $derived([
|
||||
$_('stretch.reminders.day_short_0'),
|
||||
$_('stretch.reminders.day_short_1'),
|
||||
$_('stretch.reminders.day_short_2'),
|
||||
$_('stretch.reminders.day_short_3'),
|
||||
$_('stretch.reminders.day_short_4'),
|
||||
$_('stretch.reminders.day_short_5'),
|
||||
$_('stretch.reminders.day_short_6'),
|
||||
]);
|
||||
|
||||
function toggleDay(day: number) {
|
||||
if (newDays.includes(day)) {
|
||||
|
|
@ -38,7 +48,7 @@
|
|||
days: newDays,
|
||||
});
|
||||
showCreate = false;
|
||||
newName = 'Dehn-Erinnerung';
|
||||
newName = $_('stretch.reminders.default_name');
|
||||
newTime = '09:00';
|
||||
newDays = [1, 2, 3, 4, 5];
|
||||
newRoutineId = null;
|
||||
|
|
@ -56,7 +66,7 @@
|
|||
<div class="reminder-overlay">
|
||||
<div class="reminder-header">
|
||||
<button class="back-btn" onclick={onClose}>←</button>
|
||||
<span class="header-title">Erinnerungen</span>
|
||||
<span class="header-title">{$_('stretch.reminders.header_title')}</span>
|
||||
</div>
|
||||
|
||||
<div class="reminder-body">
|
||||
|
|
@ -85,13 +95,20 @@
|
|||
<span class="rem-routine">{linked.name}</span>
|
||||
{/if}
|
||||
{/if}
|
||||
<button class="rem-delete" onclick={() => deleteReminder(reminder.id)}>Löschen</button>
|
||||
<button class="rem-delete" onclick={() => deleteReminder(reminder.id)}
|
||||
>{$_('stretch.reminders.action_delete')}</button
|
||||
>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
{#if showCreate}
|
||||
<div class="create-form">
|
||||
<input class="form-input" type="text" placeholder="Name..." bind:value={newName} />
|
||||
<input
|
||||
class="form-input"
|
||||
type="text"
|
||||
placeholder={$_('stretch.reminders.placeholder_name')}
|
||||
bind:value={newName}
|
||||
/>
|
||||
<input class="form-input time-input" type="time" bind:value={newTime} />
|
||||
<div class="days-row">
|
||||
{#each [0, 1, 2, 3, 4, 5, 6] as day}
|
||||
|
|
@ -103,24 +120,28 @@
|
|||
{/each}
|
||||
</div>
|
||||
<select class="form-select" bind:value={newRoutineId}>
|
||||
<option value={null}>Keine Routine verknüpft</option>
|
||||
<option value={null}>{$_('stretch.reminders.select_no_routine')}</option>
|
||||
{#each routines as routine}
|
||||
<option value={routine.id}>{routine.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<div class="form-actions">
|
||||
<button class="btn-cancel" onclick={() => (showCreate = false)}>Abbrechen</button>
|
||||
<button class="btn-cancel" onclick={() => (showCreate = false)}
|
||||
>{$_('stretch.reminders.action_cancel')}</button
|
||||
>
|
||||
<button class="btn-save" onclick={handleCreate} disabled={newDays.length === 0}>
|
||||
Erstellen
|
||||
{$_('stretch.reminders.action_create')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<button class="add-btn" onclick={() => (showCreate = true)}> + Neue Erinnerung </button>
|
||||
<button class="add-btn" onclick={() => (showCreate = true)}>
|
||||
{$_('stretch.reminders.action_new')}
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if reminders.length === 0 && !showCreate}
|
||||
<p class="empty-text">Noch keine Erinnerungen eingerichtet.</p>
|
||||
<p class="empty-text">{$_('stretch.reminders.empty')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
RoutineCreator — Build a custom stretch routine from the exercise library.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { _ } from 'svelte-i18n';
|
||||
import type { StretchExercise, RoutineExercise, BodyRegion } from '../types';
|
||||
import { BODY_REGION_LABELS } from '../types';
|
||||
import { stretchStore } from '../stores/stretch.svelte';
|
||||
|
|
@ -87,13 +88,13 @@
|
|||
<div class="creator-overlay">
|
||||
<div class="creator-header">
|
||||
<button class="back-btn" onclick={onCancel}>×</button>
|
||||
<span class="header-title">Neue Routine</span>
|
||||
<span class="header-title">{$_('stretch.creator.header_title')}</span>
|
||||
<button
|
||||
class="save-btn"
|
||||
onclick={handleSave}
|
||||
disabled={!name.trim() || selectedExercises.length === 0}
|
||||
>
|
||||
Speichern
|
||||
{$_('stretch.creator.action_save')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -104,14 +105,14 @@
|
|||
<input
|
||||
class="name-input"
|
||||
type="text"
|
||||
placeholder="Name der Routine..."
|
||||
placeholder={$_('stretch.creator.placeholder_name')}
|
||||
bind:value={name}
|
||||
autofocus
|
||||
/>
|
||||
<input
|
||||
class="desc-input"
|
||||
type="text"
|
||||
placeholder="Beschreibung (optional)..."
|
||||
placeholder={$_('stretch.creator.placeholder_description')}
|
||||
bind:value={description}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -120,7 +121,9 @@
|
|||
{#if selectedExercises.length > 0}
|
||||
<div class="selected-section">
|
||||
<span class="section-label">
|
||||
{selectedExercises.length} Übungen · ~{estimatedMin} Min
|
||||
{$_('stretch.creator.selected_summary', {
|
||||
values: { count: selectedExercises.length, minutes: estimatedMin },
|
||||
})}
|
||||
</span>
|
||||
{#each selectedExercises as slot, i (slot.exerciseId)}
|
||||
{@const ex = exercises.find((e) => e.id === slot.exerciseId)}
|
||||
|
|
@ -143,13 +146,13 @@
|
|||
|
||||
<!-- Exercise Picker -->
|
||||
<div class="picker-section">
|
||||
<span class="section-label">Übung hinzufügen</span>
|
||||
<span class="section-label">{$_('stretch.creator.section_picker')}</span>
|
||||
<!-- Region Filter -->
|
||||
<div class="filter-row">
|
||||
<button
|
||||
class="filter-chip"
|
||||
class:active={filterRegion === 'all'}
|
||||
onclick={() => (filterRegion = 'all')}>Alle</button
|
||||
onclick={() => (filterRegion = 'all')}>{$_('stretch.creator.filter_all')}</button
|
||||
>
|
||||
{#each ['neck', 'shoulders', 'upper_back', 'lower_back', 'hips', 'hamstrings', 'quads', 'full_body'] as region}
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
SessionHistory — Past stretch sessions with calendar heatmap and stats.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { _ } from 'svelte-i18n';
|
||||
import type { StretchSession, StretchRoutine } from '../types';
|
||||
import {
|
||||
getSessionsPerDay,
|
||||
|
|
@ -36,7 +37,7 @@
|
|||
<div class="history-overlay">
|
||||
<div class="history-header">
|
||||
<button class="back-btn" onclick={onClose}>←</button>
|
||||
<span class="header-title">Verlauf</span>
|
||||
<span class="header-title">{$_('stretch.history.header_title')}</span>
|
||||
</div>
|
||||
|
||||
<div class="history-body">
|
||||
|
|
@ -44,21 +45,21 @@
|
|||
<div class="stats-row">
|
||||
<div class="stat">
|
||||
<span class="stat-val">{totalSessions}</span>
|
||||
<span class="stat-lbl">Sessions</span>
|
||||
<span class="stat-lbl">{$_('stretch.history.stat_sessions')}</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-val">{totalMinutes}</span>
|
||||
<span class="stat-lbl">Minuten</span>
|
||||
<span class="stat-lbl">{$_('stretch.history.stat_minutes')}</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-val">{streak}</span>
|
||||
<span class="stat-lbl">Streak</span>
|
||||
<span class="stat-lbl">{$_('stretch.history.stat_streak')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 30-Day Heatmap -->
|
||||
<div class="heatmap-section">
|
||||
<span class="section-label">Letzte 30 Tage</span>
|
||||
<span class="section-label">{$_('stretch.history.section_30_days')}</span>
|
||||
<div class="heatmap-grid">
|
||||
{#each last30 as day}
|
||||
<div
|
||||
|
|
@ -75,7 +76,7 @@
|
|||
<!-- Body Region Balance -->
|
||||
{#if regionBalance.length > 0}
|
||||
<div class="balance-section">
|
||||
<span class="section-label">Körperregion-Balance</span>
|
||||
<span class="section-label">{$_('stretch.history.section_balance')}</span>
|
||||
{#each regionBalance.slice(0, 6) as rb}
|
||||
{@const maxCount = regionBalance[0]?.count ?? 1}
|
||||
<div class="balance-row">
|
||||
|
|
@ -91,14 +92,19 @@
|
|||
|
||||
<!-- Session List -->
|
||||
<div class="session-list">
|
||||
<span class="section-label">Alle Sessions</span>
|
||||
<span class="section-label">{$_('stretch.history.section_all_sessions')}</span>
|
||||
{#each sessions.slice(0, 50) as session (session.id)}
|
||||
<div class="session-item">
|
||||
<div class="si-left">
|
||||
<span class="si-name">{session.routineName}</span>
|
||||
<span class="si-meta">
|
||||
{Math.round(session.totalDurationSec / 60)} Min ·
|
||||
{session.completedExercises}/{session.totalExercises} Übungen
|
||||
{$_('stretch.history.session_meta', {
|
||||
values: {
|
||||
minutes: Math.round(session.totalDurationSec / 60),
|
||||
completed: session.completedExercises,
|
||||
total: session.totalExercises,
|
||||
},
|
||||
})}
|
||||
{#if session.mood}
|
||||
· {['😫', '😕', '😐', '😊', '🤩'][session.mood - 1]}
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
Fullscreen overlay with exercise instructions, countdown, side-switch, skip/pause.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { _ } from 'svelte-i18n';
|
||||
import type { StretchRoutine, StretchExercise, RoutineExercise } from '../types';
|
||||
import { BODY_REGION_LABELS } from '../types';
|
||||
import { stretchStore } from '../stores/stretch.svelte';
|
||||
|
|
@ -214,9 +215,13 @@
|
|||
<h2 class="ready-title">{routine.name}</h2>
|
||||
<p class="ready-desc">{routine.description}</p>
|
||||
<p class="ready-meta">
|
||||
{totalSlots} Übungen · ~{routine.estimatedDurationMin} Min
|
||||
{$_('stretch.player.ready_meta', {
|
||||
values: { count: totalSlots, minutes: routine.estimatedDurationMin },
|
||||
})}
|
||||
</p>
|
||||
<button class="start-btn" onclick={startSession}> Starten </button>
|
||||
<button class="start-btn" onclick={startSession}>
|
||||
{$_('stretch.player.action_start')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{:else if phase === 'finished'}
|
||||
|
|
@ -224,16 +229,23 @@
|
|||
<div class="finish-screen">
|
||||
<div class="finish-content">
|
||||
<div class="finish-check">✓</div>
|
||||
<h2 class="finish-title">Geschafft!</h2>
|
||||
<h2 class="finish-title">{$_('stretch.player.finish_title')}</h2>
|
||||
<p class="finish-stats">
|
||||
{completedCount} von {totalSlots} Übungen ·
|
||||
{Math.round((Date.now() - sessionStartTime) / 60000)} Min
|
||||
{$_('stretch.player.finish_stats', {
|
||||
values: {
|
||||
completed: completedCount,
|
||||
total: totalSlots,
|
||||
minutes: Math.round((Date.now() - sessionStartTime) / 60000),
|
||||
},
|
||||
})}
|
||||
</p>
|
||||
{#if skippedIds.length > 0}
|
||||
<p class="finish-skipped">{skippedIds.length} übersprungen</p>
|
||||
<p class="finish-skipped">
|
||||
{$_('stretch.player.finish_skipped', { values: { count: skippedIds.length } })}
|
||||
</p>
|
||||
{/if}
|
||||
<div class="mood-section">
|
||||
<p class="mood-label">Wie fühlst du dich?</p>
|
||||
<p class="mood-label">{$_('stretch.player.mood_label')}</p>
|
||||
<div class="mood-row">
|
||||
{#each [1, 2, 3, 4, 5] as val}
|
||||
<button
|
||||
|
|
@ -246,7 +258,9 @@
|
|||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<button class="done-btn" onclick={handleFinishWithMood}>Fertig</button>
|
||||
<button class="done-btn" onclick={handleFinishWithMood}
|
||||
>{$_('stretch.player.action_done')}</button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
|
|
@ -256,7 +270,7 @@
|
|||
<button class="close-btn" onclick={handleCancel}>×</button>
|
||||
<span class="exercise-counter">{currentIndex + 1} / {totalSlots}</span>
|
||||
{#if isPaused}
|
||||
<span class="pause-badge">Pause</span>
|
||||
<span class="pause-badge">{$_('stretch.player.pause_badge')}</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
|
@ -264,7 +278,10 @@
|
|||
{#if currentExercise}
|
||||
<h2 class="exercise-name">{currentExercise.name}</h2>
|
||||
{#if currentSide}
|
||||
<span class="side-badge">{currentSide === 'left' ? 'Linke Seite' : 'Rechte Seite'}</span
|
||||
<span class="side-badge"
|
||||
>{currentSide === 'left'
|
||||
? $_('stretch.player.side_left')
|
||||
: $_('stretch.player.side_right')}</span
|
||||
>
|
||||
{/if}
|
||||
<span class="exercise-region"
|
||||
|
|
@ -274,9 +291,9 @@
|
|||
{/if}
|
||||
|
||||
{#if phase === 'side_switch'}
|
||||
<div class="side-switch-notice">Seitenwechsel...</div>
|
||||
<div class="side-switch-notice">{$_('stretch.player.side_switch_notice')}</div>
|
||||
{:else if phase === 'rest'}
|
||||
<div class="rest-notice">Pause</div>
|
||||
<div class="rest-notice">{$_('stretch.player.rest_notice')}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
|
@ -291,12 +308,14 @@
|
|||
<!-- Controls -->
|
||||
<div class="controls">
|
||||
<button class="ctrl-btn" onclick={previousExercise} disabled={currentIndex <= 0}>
|
||||
◀ Zurück
|
||||
{$_('stretch.player.action_back')}
|
||||
</button>
|
||||
<button class="ctrl-btn pause-btn" onclick={togglePause}>
|
||||
{isPaused ? '▶ Weiter' : '❚❚ Pause'}
|
||||
{isPaused ? $_('stretch.player.action_resume') : $_('stretch.player.action_pause')}
|
||||
</button>
|
||||
<button class="ctrl-btn" onclick={skipExercise}>
|
||||
{$_('stretch.player.action_next')}
|
||||
</button>
|
||||
<button class="ctrl-btn" onclick={skipExercise}> Weiter ▶ </button>
|
||||
</div>
|
||||
|
||||
<!-- Overall Progress -->
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { _ } from 'svelte-i18n';
|
||||
import ListView from '$lib/modules/stretch/ListView.svelte';
|
||||
import { RoutePage } from '$lib/components/shell';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Stretch - Mana</title>
|
||||
<title>{$_('stretch.route.title')} - Mana</title>
|
||||
</svelte:head>
|
||||
|
||||
<RoutePage appId="stretch">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue