Sicherheit-Feinschliff, Nächster-Service-Sortierfehler behoben, Fahrzeugstatus umbenannt

- Türschlösser auf ein Sensor reduziert (Fahrertür genügt, Zentralverriegelung
  schließt alle Türen gemeinsam) - Kofferraum-/Motorhauben-Schloss entfernt.
- "Sicherheit" heißt im Panel jetzt "Fahrzeugstatus", wie in der companion-app.
- naechsterTermin() (Panel): sortierte null als Epoch 1970 und ließ dadurch
  einen datenlosen Termin (Hauptuntersuchung ohne Eintrag/Erstzulassung) immer
  vor einem echten, berechneten Termin (Ölwechsel) gewinnen - Ursache dafür,
  dass Übersicht nach dem Leeren des Servicebuchs nichts mehr zeigte.
- "Licht ausgeschaltet" statt "Kein Licht" (Formulierung zurückgenommen).
- Große Bildschirme: Unterseiten (Standort, Service, ...) zeigten ihren Titel
  in 26px statt der sonst überall genutzten 17px - wirkte neben dem
  durchgängig leichten Fließtext wie Fettschrift, obwohl font-weight nirgends
  wechselt. Jetzt dieselbe Standardgröße wie im Telefon-Layout.

Details und Verifikation in AGENTS.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-24 17:00:33 +02:00
parent 5a048488ea
commit 7276d06a18
9 changed files with 143 additions and 41 deletions
@@ -1177,7 +1177,16 @@ function teaser() {
<svg class="chev" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg></button>` : ""}</div>`;
}
function naechsterTermin() { return termine().slice().sort((a, b) => a.ziel - b.ziel)[0]; }
// Kandidaten ohne ziel (kein Servicebucheintrag, keine Fahrzeugmeldung, bei
// der Hauptuntersuchung auch keine verwertbare Erstzulassung) müssen VOR dem
// Sortieren raus: (a,b) => a.ziel - b.ziel zwingt null auf 0 (Epoch 1970) und
// liess einen datenlosen Termin dadurch immer als "naechster" gewinnen -
// selbst gegen einen anderen Termin mit echtem, berechnetem Datum. null nur
// dann zurückgeben, wenn wirklich kein einziger Termin ein ziel hat.
function naechsterTermin() {
const mitZiel = termine().filter((t) => t.ziel !== null);
return mitZiel.length ? mitZiel.slice().sort((a, b) => a.ziel - b.ziel)[0] : null;
}
// CI-Icon je Serviceart statt eines Wort-Zusatzes ("bis zum Ölwechsel" o.ä.) -
// nur Ölwechsel/Inspektion haben eines, die Hauptuntersuchung nicht. Verwendet
@@ -1510,9 +1519,6 @@ function vSicherheit() {
const fensterDach = sicherheitsGruppe("fenster_dach");
const licht = sicherheitsGruppe("licht");
const sammelText = g === null ? "Zustand nicht vollständig bekannt" : g ? "Fahrzeug ist sicher abgestellt" : "Bitte prüfen";
// Jede Zeile nennt beim Nutzer-Zustand ("ok") genau die Formulierung, die
// der Nutzer vorgegeben hat - beim Licht ist das "Kein Licht", nicht
// "Licht ausgeschaltet" (das beschreibt nur die Prüfung, nicht den Wert).
const zeile = (label, ok, labelBad, labelWarn, route) => {
const text = ok === null ? labelWarn : ok ? label : labelBad;
const klickbar = !!route;
@@ -1534,7 +1540,7 @@ function vSicherheit() {
${zeile("Fahrzeug verriegelt", verriegelt.ok, "Fahrzeug nicht verriegelt", "Verriegelung unbekannt")}
${zeile("Türen und Klappen geschlossen", tuerenKlappen.ok, "Türen oder Klappen offen", "Türen/Klappen unbekannt", "tuerenklappen")}
${zeile("Fenster und Dach geschlossen", fensterDach.ok, "Fenster oder Dach offen", "Fenster/Dach unbekannt")}
${zeile("Kein Licht", licht.ok, "Licht eingeschaltet", "Licht unbekannt")}
${zeile("Licht ausgeschaltet", licht.ok, "Licht eingeschaltet", "Licht unbekannt")}
</div>`;
}
@@ -3866,7 +3872,7 @@ function render() {
else if (route.name === "reifen") { head = ["Fahrzeug", "Reifen"]; v.innerHTML = vReifen(); }
else if (route.name === "einst") { head = ["App", "Einstellungen"]; v.innerHTML = vEinst(); }
else if (route.name === "ident") { head = ["Fahrzeug", "Identität und Technik"]; v.innerHTML = vIdent(); }
else if (route.name === "sicherheit") { head = ["Fahrzeug", "Sicherheit"]; v.innerHTML = vSicherheit(); }
else if (route.name === "sicherheit") { head = ["Fahrzeug", "Fahrzeugstatus"]; v.innerHTML = vSicherheit(); }
else if (route.name === "tuerenklappen") { head = ["Fahrzeug", "Türen und Klappen"]; v.innerHTML = vTuerenKlappen(); }
else if (route.name === "vers") { head = ["Fahrzeug", "Versicherung/Steuer"]; v.innerHTML = vVers(); }
else if (route.name === "beitrag") { head = ["Versicherung", "Beitrag anpassen"]; v.innerHTML = vBeitrag(); }