Split- och depåstatistik är implementerad

This commit is contained in:
larssand
2026-08-25 20:00:55 +02:00
parent 8ea8b3a84e
commit abf887dccd
16 changed files with 564 additions and 46 deletions

View File

@@ -14,6 +14,7 @@ export function renderTrainingView(deps) {
normalizeTrainingState,
syncTrainingLedger,
buildDriverTrainingStats,
buildDriverTimingChannelStats,
buildDriverActivePracticeStats,
buildTrainingRecommendation,
getTrainingGoalProgress,
@@ -57,6 +58,7 @@ export function renderTrainingView(deps) {
const selectedDriver = selectedProfile.representative;
const profileReferences = getDriverProfileReferences(state, selectedProfileId);
const stats = buildDriverTrainingStats(state, selectedProfileId, selectedClassId);
const channelStats = buildDriverTimingChannelStats(state, selectedProfileId, selectedClassId);
const activePractice = buildDriverActivePracticeStats(state, selectedProfileId, Date.now(), selectedClassId);
const recommendation = buildTrainingRecommendation(stats);
const nextMilestone = getNextTrainingMilestone(stats);
@@ -294,7 +296,31 @@ export function renderTrainingView(deps) {
${trainingInsight(t("training.best_three"), stats.bestThreeConsecutive ? `3/${formatRaceClock(stats.bestThreeConsecutive.totalMs)}` : "-")}
${trainingInsight(t("training.best_five"), stats.bestFiveMinuteResult ? `${stats.bestFiveMinuteResult.lapCount}/${formatRaceClock(stats.bestFiveMinuteResult.totalMs)}` : "-")}
${trainingInsight(t("training.five_avg_pace"), stats.bestFiveMinuteResult ? formatLap(stats.bestFiveMinuteResult.averageLapMs) : "-")}
${trainingInsight(t("training.split_passings"), String(channelStats.splitCount))}
${trainingInsight(t("training.best_split"), channelStats.splitCount ? formatLap(channelStats.bestSplitMs) : "-")}
${trainingInsight(t("training.average_split"), channelStats.splitCount ? formatLap(channelStats.averageSplitMs) : "-")}
${trainingInsight(t("training.pit_stops"), String(channelStats.pitStopCount))}
${trainingInsight(t("training.total_pit_time"), channelStats.pitStopCount ? formatRaceClock(channelStats.totalPitMs) : "-")}
${trainingInsight(t("training.average_pit_stop"), channelStats.pitStopCount ? formatLap(channelStats.averagePitStopMs) : "-")}
${trainingInsight(t("training.best_pit_stop"), channelStats.pitStopCount ? formatLap(channelStats.bestPitStopMs) : "-")}
</section>
${channelStats.recentPitStops.length ? `
<div class="training-section-title"><h3>${escapeHtml(t("training.recent_pit_stops"))}</h3></div>
<div class="table-wrap training-history-wrap">
<table class="training-history-table">
<thead><tr><th>${escapeHtml(t("training.date"))}</th><th>${escapeHtml(t("table.event"))}</th><th>${escapeHtml(t("table.session"))}</th><th>${escapeHtml(t("table.car"))}</th><th>${escapeHtml(t("table.duration"))}</th></tr></thead>
<tbody>${channelStats.recentPitStops.map((stop) => `
<tr>
<td>${escapeHtml(new Date(stop.enteredAt).toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" }))}</td>
<td>${escapeHtml(stop.eventName || "-")}</td>
<td>${escapeHtml(stop.sessionName || "-")}</td>
<td>${escapeHtml(stop.carName || "-")}</td>
<td>${formatLap(stop.pitStopMs)}</td>
</tr>
`).join("")}</tbody>
</table>
</div>
` : ""}
<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>` : ""}