export function renderRaceFormatField(labelKey, hintKey, controlHtml, options = {}, { t }) { const extraClass = options.checkbox ? " field-card-checkbox" : ""; return ` `; } export function renderRaceFormatContextCard(titleKey, hintKey, { t }) { return `
${t(titleKey)} ${t(hintKey)}
`; } export function getRaceSummaryItems(event, sessions, raceDrivers, selectedPreset, { t, getStartModeLabel }) { const cfg = event.raceConfig || {}; const participantCount = cfg.participantsConfigured ? (cfg.driverIds || []).length : raceDrivers.length; const practiceCount = sessions.filter((session) => ["practice", "free_practice", "open_practice"].includes(session.type)).length; const qualCount = sessions.filter((session) => session.type === "qualification").length; const finalCount = sessions.filter((session) => session.type === "final").length; const teamCount = sessions.filter((session) => session.type === "team_race").length; const scoringLabel = cfg.qualifyingScoring === "best" ? t("events.qualifying_scoring_best") : t("events.qualifying_scoring_points"); const lapWindow = `${((cfg.minLapMs || 0) / 1000).toFixed(1)}s / ${((cfg.maxLapMs || 0) / 1000).toFixed(1)}s`; const isEndurancePreset = selectedPreset?.id === "endurance"; if (isEndurancePreset) { return [ { label: t("events.race_summary_preset"), value: selectedPreset?.label || t("events.preset_custom") }, { label: t("events.race_summary_focus"), value: `${t("events.team_race")} · ${getStartModeLabel("mass")}` }, { label: t("events.race_summary_participants"), value: String(participantCount || 0) }, { label: t("events.race_summary_created_sessions"), value: `P ${practiceCount} · T ${teamCount}` }, { label: t("events.race_summary_generation"), value: `${teamCount ? t("events.team_race") : t("events.wizard_use_team_race")} · ${cfg.finalDurationMin || 0} min` }, { label: t("events.race_summary_validation"), value: lapWindow }, { label: t("events.race_summary_follow_up"), value: `${cfg.followUpSec || 0}s` }, ]; } return [ { label: t("events.race_summary_preset"), value: selectedPreset?.label || t("events.preset_custom") }, { label: t("events.race_summary_participants"), value: String(participantCount || 0) }, { label: t("events.race_summary_created_sessions"), value: `P ${practiceCount} · Q ${qualCount} · F ${finalCount} · T ${teamCount}` }, { label: t("events.race_summary_qualifying"), value: `${cfg.qualifyingRounds || 0} x ${cfg.qualDurationMin || 0} min · ${cfg.carsPerHeat || 0}/heat · ${scoringLabel}` }, { label: t("events.race_summary_finals"), value: `${cfg.carsPerFinal || 0}/main · ${cfg.finalLegs || 0} leg · ${getStartModeLabel(cfg.finalStartMode || "position")}` }, { label: t("events.race_summary_generation"), value: `${cfg.finalsSource === "practice" ? t("events.finals_from_practice") : t("events.finals_from_qualifying")} · bump ${cfg.bumpCount || 0}` }, { label: t("events.race_summary_validation"), value: lapWindow }, { label: t("events.race_summary_follow_up"), value: `${cfg.followUpSec || 0}s` }, ]; } export function getRaceSummaryWarnings(event, sessions, raceDrivers, raceTeams, selectedPreset, { t }) { const cfg = event.raceConfig || {}; const participantCount = cfg.participantsConfigured ? (cfg.driverIds || []).length : raceDrivers.length; const warnings = []; const isEndurancePreset = selectedPreset?.id === "endurance"; const hasQualifying = sessions.some((session) => session.type === "qualification"); const hasFinals = sessions.some((session) => session.type === "final"); const hasAnySession = sessions.length > 0; if (participantCount <= 0) warnings.push({ message: t("events.summary_warning_no_participants"), target: "manage-setup-participants" }); if (!hasAnySession) warnings.push({ message: t("events.summary_warning_no_sessions"), target: "manage-session-plan" }); if (!isEndurancePreset && !hasQualifying) warnings.push({ message: t("events.summary_warning_no_qualifying"), target: "manage-generation" }); if (!isEndurancePreset && !hasFinals) warnings.push({ message: t("events.summary_warning_no_finals"), target: "manage-generation" }); if (isEndurancePreset && raceTeams.length <= 0) warnings.push({ message: t("events.summary_warning_no_teams"), target: "manage-setup-teams" }); const minLapMs = Math.max(0, Number(cfg.minLapMs || 0) || 0); const maxLapMs = Math.max(0, Number(cfg.maxLapMs || 0) || 0); if (maxLapMs > 0 && maxLapMs <= minLapMs) warnings.push({ message: t("events.summary_warning_invalid_lap_window"), target: "manage-format" }); return warnings; } export function renderManageStatusBadge(status, { t }) { return `${t(`events.status_${status}`)}`; } export function renderRaceWizardSteps({ t, raceWizardStep, escapeHtml }) { const steps = [t("events.wizard_step_1"), t("events.wizard_step_2"), t("events.wizard_step_3"), t("events.wizard_step_4")]; return steps .map( (label, index) => `
${index + 1} ${escapeHtml(label)}
` ) .join(""); } export function renderRaceWizardContent(draft, classOptions, wizardDrivers, preset, { t, escapeHtml, raceWizardStep, getRaceFormatPresets, getClassName, getRaceWizardSessionPlan }) { if (raceWizardStep === 1) { return `
`; } if (raceWizardStep === 2) { return `
${wizardDrivers.length ? `
${wizardDrivers .map( (driver) => ` ` ) .join("")}
` : `

${t("events.wizard_no_class_drivers")}

`} `; } if (raceWizardStep === 3) { const isEndurance = preset.id === "endurance"; return `
${!isEndurance ? ` ` : ` `}

${t("events.wizard_finals_note")}

`; } const selectedClassName = getClassName(draft.classId); const selectedDrivers = draft.driverIds.length ? draft.driverIds.length : wizardDrivers.length; return `
${t("events.wizard_summary_title")} ${escapeHtml(draft.name || "-")}
${t("table.class")} ${escapeHtml(selectedClassName || "-")}
${t("events.race_summary_preset")} ${escapeHtml(preset?.label || t("events.preset_custom"))}
${t("events.race_summary_participants")} ${selectedDrivers}
${t("events.wizard_summary_sessions")} ${escapeHtml(getRaceWizardSessionPlan(draft).join(" • ") || "-")}
`; } export function renderRaceStandingsTable(rows, emptyLabel, { t, renderTable, escapeHtml }) { if (!rows.length) { return `

${emptyLabel}

`; } return renderTable( [t("table.pos"), t("table.driver"), t("table.score")], rows.map( (row) => ` ${row.rank} ${escapeHtml(row.driverName || t("common.unknown_driver"))}
${escapeHtml(row.score || "-")}
${row.scoreNote ? `
${escapeHtml(row.scoreNote)}
` : ""} ` ) ); }