Latest Updates done, before integrating

This commit is contained in:
2026-04-12 10:13:53 +02:00
parent db46fcf0c6
commit 5354e34055
19 changed files with 820 additions and 41 deletions

View File

@@ -64,10 +64,12 @@ type Store struct {
wwBoostDisabled *monitor.Mode
tripMgr *trip.Manager
carOptions []CarOption
csrfToken string
hasAuth bool
}
// NewStore creates a new status store.
func NewStore(dryRun bool, wwConfigured bool, strategic config.StrategicConfig, carCharging config.CarChargingConfig, mode *monitor.Mode, wwBoostDisabled *monitor.Mode, tm *trip.Manager, cars []CarOption) *Store {
func NewStore(dryRun bool, wwConfigured bool, strategic config.StrategicConfig, carCharging config.CarChargingConfig, mode *monitor.Mode, wwBoostDisabled *monitor.Mode, tm *trip.Manager, cars []CarOption, csrfToken string, hasAuth bool) *Store {
consumers := make(map[engine.Consumer]*consumerRecord, len(consumerOrder))
for _, c := range consumerOrder {
consumers[c] = &consumerRecord{}
@@ -82,6 +84,8 @@ func NewStore(dryRun bool, wwConfigured bool, strategic config.StrategicConfig,
wwBoostDisabled: wwBoostDisabled,
tripMgr: tm,
carOptions: cars,
csrfToken: csrfToken,
hasAuth: hasAuth,
}
}
@@ -195,6 +199,8 @@ type pageData struct {
Consumers []consumerView
Trip tripView
CarOptions []CarOption
CSRFToken string
HasAuth bool // true when login is required — shows logout button
}
// SyncConsumerStates updates active flags for all consumers directly from the
@@ -289,6 +295,8 @@ func (s *Store) Handler() http.HandlerFunc {
IsExporting: s.state.GridPowerW < 0,
AbsGridW: abs(s.state.GridPowerW),
HasPhaseData: hasPhase,
CSRFToken: s.csrfToken,
HasAuth: s.hasAuth,
}
if hasPhase {
for _, ph := range []struct {
@@ -782,9 +790,13 @@ h1 { font-size: 1.4rem; font-weight: 700; color: #14532d; }
{{end}}
{{if not .MonitorOnly}}
<form method="post" action="/monitor">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<button type="submit" class="monitor-toggle-btn">⏸ Monitor</button>
</form>
{{end}}
{{if .HasAuth}}
<a href="/logout" style="font-size:.8rem;color:#94a3b8;text-decoration:none;padding:.3rem .6rem;border:1px solid #e2e8f0;border-radius:.4rem">Abmelden</a>
{{end}}
</div>
</header>
@@ -792,6 +804,7 @@ h1 { font-size: 1.4rem; font-weight: 700; color: #14532d; }
<div class="banner monitor">
<span>⏸ Monitor-Only — Keine Schaltvorgänge</span>
<form method="post" action="/monitor">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<button type="submit" class="resume-btn">▶ Automatik</button>
</form>
</div>
@@ -907,6 +920,7 @@ h1 { font-size: 1.4rem; font-weight: 700; color: #14532d; }
{{end}}
{{if .CanOverride}}
<form method="post" action="/override" style="display:flex;align-items:center;gap:0.4rem;flex-shrink:0">
<input type="hidden" name="csrf_token" value="{{$.CSRFToken}}">
<input type="hidden" name="consumer" value="{{.ConsumerKey}}">
{{if .Active}}
<input type="hidden" name="state" value="off">
@@ -928,10 +942,12 @@ h1 { font-size: 1.4rem; font-weight: 700; color: #14532d; }
<div style="display:flex;flex-direction:column;gap:0.3rem;flex-shrink:0">
{{if not .Unconfigured}}
<form method="post" action="/ww/reset">
<input type="hidden" name="csrf_token" value="{{$.CSRFToken}}">
<button type="submit" class="override-btn turn-off" style="width:100%" title="WW-Solltemperatur auf Basiswert zurücksetzen, Boost für heute sperren">🌡️ Zurücksetzen</button>
</form>
{{end}}
<form method="post" action="/ww/boost">
<input type="hidden" name="csrf_token" value="{{$.CSRFToken}}">
{{if .WWBoostDisabled}}
<button type="submit" class="override-btn turn-on" style="width:100%" title="WW Boost durch PV-Überschuss wieder erlauben">✅ Boost ein</button>
{{else}}
@@ -948,6 +964,7 @@ h1 { font-size: 1.4rem; font-weight: 700; color: #14532d; }
<div class="trip-header">
<span class="trip-title">🚗 Fahrt geplant</span>
<form method="post" action="/trip/cancel">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<button type="submit" class="trip-cancel">Abbrechen</button>
</form>
</div>
@@ -966,6 +983,7 @@ h1 { font-size: 1.4rem; font-weight: 700; color: #14532d; }
<div class="trip-form-card">
<div class="section-title">🚗 Fahrtziel planen</div>
<form method="post" action="/trip" class="trip-form">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<div class="trip-row">
<select name="wallbox" class="trip-select">
<option value="wallbox_a">Wallbox A</option>