förenklat träningsdelen

This commit is contained in:
larssand
2026-08-24 17:16:07 +02:00
parent 4a74785791
commit 40d0c3fa90
8 changed files with 243 additions and 94 deletions

View File

@@ -132,7 +132,7 @@ export function renderTrainingView(deps) {
${trainingStat(t("training.consistency"), stats.recentLapCount ? `${stats.consistencySpreadPct.toFixed(1)}%` : "-", t("training.last_30_laps"))}
</div>
<div class="training-insight-grid">
<div class="training-focus-grid">
<section class="training-milestone-card">
<div>
<span class="training-kicker">${escapeHtml(t("training.next_level"))}</span>
@@ -142,15 +142,6 @@ export function renderTrainingView(deps) {
<strong>${nextMilestone.currentLaps} / ${nextMilestone.targetLaps}</strong>
<div class="training-progress"><span style="width:${nextMilestone.percent.toFixed(2)}%"></span></div>
</section>
<section class="training-insights">
${trainingInsight(t("training.average_lap"), formatLap(stats.averageLapMs))}
${trainingInsight(t("training.recent_average"), formatLap(stats.recentAverageMs))}
${trainingInsight(t("training.controlled_streak"), t("training.lap_count", { laps: stats.controlledLapStreak }))}
${trainingInsight(t("training.last_activity"), lastActivity)}
</section>
</div>
<div class="training-layout">
<section class="panel training-plan">
<div class="panel-header"><h3>${escapeHtml(t("training.recommendation"))}</h3><span class="badge">20 min</span></div>
<div class="panel-body">
@@ -163,79 +154,100 @@ export function renderTrainingView(deps) {
</div>
</div>
</section>
<section class="panel">
<div class="panel-header"><h3>${escapeHtml(t("training.new_goal"))}</h3></div>
<div class="panel-body">
<form id="training-goal-form" class="form-grid training-goal-form">
<label>${escapeHtml(t("training.target_laps"))}<input type="number" name="targetLaps" min="1" step="1" value="500" required /></label>
<div class="training-presets" aria-label="${escapeHtml(t("training.quick_targets"))}">
${[500, 1000, 1500].map((value) => `<button type="button" class="btn btn-mini training-preset" data-laps="${value}">${value}</button>`).join("")}
</div>
<label>${escapeHtml(t("training.goal_name"))}<input name="title" placeholder="${escapeHtml(t("training.goal_name_placeholder"))}" /></label>
<label>${escapeHtml(t("training.reward"))}<input name="reward" placeholder="${escapeHtml(t("training.reward_placeholder"))}" /></label>
<button class="btn btn-primary" type="submit">${escapeHtml(t("training.add_goal"))}</button>
</form>
</div>
</section>
</div>
<section class="panel mt-16 training-share-panel">
<div class="panel-header">
<h3>${escapeHtml(t("training.public_profile"))}</h3>
<span class="badge ${profileShare ? "badge-online" : "badge-offline"}">${escapeHtml(t(profileShare ? "training.public_profile_active" : "training.public_profile_off"))}</span>
</div>
<div class="panel-body training-share-body">
<div>
<p>${escapeHtml(t("training.public_profile_help"))}</p>
<p class="hint">${escapeHtml(t("training.public_profile_private"))}</p>
${goals.length ? `
<section class="panel mt-16">
<div class="panel-header"><h3>${escapeHtml(t("training.goals"))}</h3><span class="badge">${goals.length}</span></div>
<div class="panel-body training-goals">${goalMarkup}</div>
</section>
` : ""}
<div class="training-secondary">
<details class="training-disclosure">
<summary>
<span><strong>${escapeHtml(t("training.manage_goals_sharing"))}</strong><small>${escapeHtml(t("training.manage_goals_sharing_hint"))}</small></span>
<span class="training-disclosure-arrow">+</span>
</summary>
<div class="training-disclosure-body">
<div class="training-layout">
<section class="training-simple-section">
<h3>${escapeHtml(t("training.new_goal"))}</h3>
<form id="training-goal-form" class="form-grid training-goal-form">
<label>${escapeHtml(t("training.target_laps"))}<input type="number" name="targetLaps" min="1" step="1" value="500" required /></label>
<div class="training-presets" aria-label="${escapeHtml(t("training.quick_targets"))}">
${[500, 1000, 1500].map((value) => `<button type="button" class="btn btn-mini training-preset" data-laps="${value}">${value}</button>`).join("")}
</div>
<label>${escapeHtml(t("training.goal_name"))}<input name="title" placeholder="${escapeHtml(t("training.goal_name_placeholder"))}" /></label>
<label>${escapeHtml(t("training.reward"))}<input name="reward" placeholder="${escapeHtml(t("training.reward_placeholder"))}" /></label>
<button class="btn btn-primary" type="submit">${escapeHtml(t("training.add_goal"))}</button>
</form>
</section>
<section class="training-simple-section training-share-panel">
<div class="training-simple-head">
<h3>${escapeHtml(t("training.public_profile"))}</h3>
<span class="badge ${profileShare ? "badge-online" : "badge-offline"}">${escapeHtml(t(profileShare ? "training.public_profile_active" : "training.public_profile_off"))}</span>
</div>
<div class="training-share-compact">
<p>${escapeHtml(t("training.public_profile_help"))}</p>
${profileShare ? `
<label class="training-share-url">
<span>${escapeHtml(t("training.public_profile_link"))}</span>
<input id="trainingPublicProfileUrl" value="${escapeHtml(publicProfileUrl)}" readonly />
</label>
<div class="actions">
<button class="btn btn-primary" id="trainingPublicProfileCopy" type="button">${escapeHtml(t("training.copy_link"))}</button>
<button class="btn" id="trainingPublicProfileOpen" type="button">${escapeHtml(t("training.open_profile"))}</button>
<button class="btn" id="trainingPublicProfileRotate" type="button">${escapeHtml(t("training.replace_link"))}</button>
<button class="btn btn-danger" id="trainingPublicProfileDisable" type="button">${escapeHtml(t("training.disable_profile"))}</button>
</div>
` : `
<button class="btn btn-primary" id="trainingPublicProfileEnable" type="button">${escapeHtml(t("training.enable_profile"))}</button>
`}
</div>
</section>
</div>
</div>
${profileShare ? `
<label class="training-share-url">
<span>${escapeHtml(t("training.public_profile_link"))}</span>
<input id="trainingPublicProfileUrl" value="${escapeHtml(publicProfileUrl)}" readonly />
</label>
<div class="actions">
<button class="btn btn-primary" id="trainingPublicProfileCopy" type="button">${escapeHtml(t("training.copy_link"))}</button>
<button class="btn" id="trainingPublicProfileOpen" type="button">${escapeHtml(t("training.open_profile"))}</button>
<button class="btn" id="trainingPublicProfileRotate" type="button">${escapeHtml(t("training.replace_link"))}</button>
<button class="btn btn-danger" id="trainingPublicProfileDisable" type="button">${escapeHtml(t("training.disable_profile"))}</button>
</details>
<details class="training-disclosure">
<summary>
<span><strong>${escapeHtml(t("training.detailed_stats"))}</strong><small>${escapeHtml(t("training.detailed_stats_hint"))}</small></span>
<span class="training-disclosure-arrow">+</span>
</summary>
<div class="training-disclosure-body">
<section class="training-insights">
${trainingInsight(t("training.average_lap"), formatLap(stats.averageLapMs))}
${trainingInsight(t("training.recent_average"), formatLap(stats.recentAverageMs))}
${trainingInsight(t("training.controlled_streak"), t("training.lap_count", { laps: stats.controlledLapStreak }))}
${trainingInsight(t("training.last_activity"), lastActivity)}
</section>
<div class="training-section-title">
<h3>${escapeHtml(t("training.history"))}</h3>
${stats.personalBestGainMs ? `<span class="badge success">${escapeHtml(t("training.pb_improvement", { lap: formatLap(stats.personalBestGainMs) }))}</span>` : ""}
</div>
` : `
<div class="actions">
<button class="btn btn-primary" id="trainingPublicProfileEnable" type="button">${escapeHtml(t("training.enable_profile"))}</button>
<div class="table-wrap training-history-wrap">
<table class="training-history-table">
<thead><tr><th>${escapeHtml(t("training.date"))}</th><th>${escapeHtml(t("training.laps"))}</th><th>${escapeHtml(t("training.best_lap"))}</th><th>${escapeHtml(t("training.average_lap"))}</th></tr></thead>
<tbody>${dailyRows}</tbody>
</table>
</div>
`}
</div>
</section>
</div>
</details>
<section class="panel mt-16">
<div class="panel-header">
<h3>${escapeHtml(t("training.history"))}</h3>
${stats.personalBestGainMs ? `<span class="badge success">${escapeHtml(t("training.pb_improvement", { lap: formatLap(stats.personalBestGainMs) }))}</span>` : ""}
</div>
<div class="panel-body table-wrap training-history-wrap">
<table class="training-history-table">
<thead><tr><th>${escapeHtml(t("training.date"))}</th><th>${escapeHtml(t("training.laps"))}</th><th>${escapeHtml(t("training.best_lap"))}</th><th>${escapeHtml(t("training.average_lap"))}</th></tr></thead>
<tbody>${dailyRows}</tbody>
</table>
</div>
</section>
<section class="panel mt-16">
<div class="panel-header"><h3>${escapeHtml(t("training.club_progress"))}</h3><span class="badge">${drivers.length}</span></div>
<div class="panel-body table-wrap training-history-wrap">
<table class="training-history-table training-club-table">
<thead><tr><th>#</th><th>${escapeHtml(t("training.driver"))}</th><th>${escapeHtml(t("training.laps"))}</th><th>${escapeHtml(t("training.training_days"))}</th><th>${escapeHtml(t("training.best_lap"))}</th><th>${escapeHtml(t("training.next_target"))}</th></tr></thead>
<tbody>${clubRows}</tbody>
</table>
</div>
</section>
<section class="panel mt-16">
<div class="panel-header"><h3>${escapeHtml(t("training.goals"))}</h3><span class="badge">${goals.length}</span></div>
<div class="panel-body training-goals">${goalMarkup}</div>
</section>
<details class="training-disclosure">
<summary>
<span><strong>${escapeHtml(t("training.club_progress"))}</strong><small>${escapeHtml(t("training.club_progress_hint"))}</small></span>
<span class="training-disclosure-arrow">+</span>
</summary>
<div class="training-disclosure-body table-wrap training-history-wrap">
<table class="training-history-table training-club-table">
<thead><tr><th>#</th><th>${escapeHtml(t("training.driver"))}</th><th>${escapeHtml(t("training.laps"))}</th><th>${escapeHtml(t("training.training_days"))}</th><th>${escapeHtml(t("training.best_lap"))}</th><th>${escapeHtml(t("training.next_target"))}</th></tr></thead>
<tbody>${clubRows}</tbody>
</table>
</div>
</details>
</div>
`;
document.getElementById("training-driver")?.addEventListener("change", (event) => {