11let dashboardGrid ;
2- let currentPw = sessionStorage . getItem ( 'admin_pw' ) || "" ;
2+ let currentPw = "" ;
33
44// 1. Grid initialisieren
55function initGridstack ( ) {
6- const isAdmin = sessionStorage . getItem ( 'admin_pw' ) !== null ;
7-
86 dashboardGrid = GridStack . init ( {
97 cellHeight : 110 ,
108 margin : 20 ,
119 animate : true ,
12- staticGrid : ! isAdmin , // Wenn nicht Admin, dann gesperrt (kein Drag/Resize)
10+ staticGrid : true ,
1311 disableOneColumnMode : false ,
1412 oneColumnModeDomSort : true
1513 } ) ;
1614
17- // Falls das PW schon im Speicher war (nach Refresh), UI direkt anpassen
18- if ( isAdmin ) {
19- currentPw = sessionStorage . getItem ( 'admin_pw' ) ;
20- document . getElementById ( 'unlockBtn' ) . style . display = 'none' ;
21- document . getElementById ( 'adminArea' ) . style . display = 'flex' ;
22- // Hier ggf. loadTariffs() aufrufen, falls script.js schon geladen ist
23- }
24-
2515 dashboardGrid . on ( 'change' , function ( event , items ) {
2616 saveLayout ( ) ;
2717 } ) ;
2818}
2919
30- // 3 . Layout speichern (Auth-Check + DB vs. LocalStorage )
20+ // 2 . Layout speichern (Nur in DB und nur wenn PW da ist )
3121async function saveLayout ( ) {
32- if ( ! dashboardGrid ) return ;
22+ if ( ! dashboardGrid || ! currentPw ) return ;
23+
3324 const layoutData = dashboardGrid . save ( ) ;
3425
35- // Wir schauen nach, ob ein Passwort im SessionStorage liegt
36- // (Das müsstest du in deiner unlockAdmin() Funktion dort speichern)
37- const storedPw = sessionStorage . getItem ( 'admin_pw' ) ;
38-
39- if ( storedPw ) {
40- try {
41- const response = await fetch ( '/api/layout' , {
42- method : 'POST' ,
43- headers : { 'Content-Type' : 'application/json' } ,
44- body : JSON . stringify ( {
45- layout : layoutData ,
46- pw : storedPw
47- } )
48- } ) ;
49-
50- if ( response . ok ) {
51- console . log ( "Layout in DB gespeichert." ) ;
52- return ;
53- }
54- } catch ( e ) { console . error ( "DB Save failed" , e ) ; }
55- }
56-
57- // Fallback: LocalStorage für Gäste
58- localStorage . setItem ( 'balkonkraftwerk_layout' , JSON . stringify ( layoutData ) ) ;
59- console . log ( "Layout lokal im Browser gespeichert." ) ;
26+ try {
27+ const response = await fetch ( '/api/layout' , {
28+ method : 'POST' ,
29+ headers : { 'Content-Type' : 'application/json' } ,
30+ body : JSON . stringify ( {
31+ layout : layoutData ,
32+ pw : currentPw
33+ } )
34+ } ) ;
35+
36+ if ( response . ok ) {
37+ console . log ( "Layout in DB für alle Nutzer aktualisiert." ) ;
38+ }
39+ } catch ( e ) { console . error ( "DB Save failed" , e ) ; }
6040}
6141
62- // 4 . Layout beim Starten laden
42+ // 3 . Layout beim Starten laden
6343async function loadLayout ( ) {
6444 let savedLayout = null ;
6545 try {
@@ -70,85 +50,30 @@ async function loadLayout() {
7050 }
7151 } catch ( e ) { console . error ( "DB Load failed" , e ) ; }
7252
73- if ( ! savedLayout ) {
74- const localData = localStorage . getItem ( 'balkonkraftwerk_layout' ) ;
75- if ( localData ) savedLayout = JSON . parse ( localData ) ;
76- }
77-
53+ // Wenn ein Layout auf dem Server existiert, anwenden
7854 if ( savedLayout && dashboardGrid ) {
7955 dashboardGrid . removeAll ( ) ;
8056 dashboardGrid . load ( savedLayout ) ;
81- console . log ( "Layout sauber neu geladen." ) ;
57+ console . log ( "Globales Layout erfolgreich geladen." ) ;
8258 }
83-
84-
8559}
8660
61+ // 4. Reset-Funktion für den Button im Admin-Bereich
8762async function resetDatabaseLayout ( ) {
88- if ( ! confirm ( "Möchtest du das Layout wirklich auf Standard zurücksetzen?" ) ) return ;
63+ if ( ! confirm ( "Möchtest du das Layout für ALLE Nutzer auf den Standard zurücksetzen?" ) ) return ;
8964
90- const storedPw = sessionStorage . getItem ( 'admin_pw' ) ;
91- if ( ! storedPw ) return alert ( "Bitte erst einloggen!" ) ;
65+ if ( ! currentPw ) return alert ( "Bitte erst als Admin einloggen!" ) ;
9266
93- // Wir senden ein leeres Array oder null, damit der Server es löscht/leert
94- await fetch ( '/api/layout' , {
67+ const res = await fetch ( '/api/layout' , {
9568 method : 'POST' ,
9669 headers : { 'Content-Type' : 'application/json' } ,
9770 body : JSON . stringify ( {
98- layout : [ ] , // Leeres Layout erzwingen
99- pw : storedPw
71+ layout : "RESET" , // Signalwort für das Python-Backend
72+ pw : currentPw
10073 } )
10174 } ) ;
102- location . reload ( ) ;
103- }
104-
105- document . addEventListener ( "DOMContentLoaded" , async ( ) => {
106- // --- PHASE 1: Das Gerüst aufbauen ---
107- initGridstack ( ) ;
108- await loadLayout ( ) ; // Wartet, bis Boxen aus DB oder LocalStorage da sind
109-
110- // --- PHASE 2: Startwerte für Datumsfelder setzen ---
111- const t = new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ;
112- const startInput = document . getElementById ( 'start' ) ;
113- const endInput = document . getElementById ( 'end' ) ;
114-
115- if ( startInput && endInput ) {
116- startInput . value = t ;
117- endInput . value = t ;
118- startInput . addEventListener ( 'change' , updateQuickButtonsActiveState ) ;
119- endInput . addEventListener ( 'change' , updateQuickButtonsActiveState ) ;
120- }
121-
122- // --- PHASE 3: Daten in die Boxen pumpen ---
123- // Wir prüfen bei jeder Funktion, ob sie existiert, um Fehler zu vermeiden
124- try {
125- if ( typeof fetchData === "function" ) await fetchData ( ) ;
126- if ( typeof updateWeather === "function" ) updateWeather ( ) ;
127- if ( typeof updateLive === "function" ) updateLive ( ) ;
128- if ( typeof updatePeaks === "function" ) updatePeaks ( ) ;
129- if ( typeof updateQuickButtonsActiveState === "function" ) updateQuickButtonsActiveState ( ) ;
130-
131- // ML-Funktionen
132- if ( typeof loadForecast === "function" ) loadForecast ( ) ;
133- if ( typeof loadGlobalShap === "function" ) loadGlobalShap ( ) ;
134- if ( typeof loadFeatureImportance === "function" ) loadFeatureImportance ( ) ;
135-
136- // Heatmaps
137- if ( typeof initHeatmapYears === "function" ) initHeatmapYears ( ) ;
138- if ( typeof initHourlyHeatmap === "function" ) initHourlyHeatmap ( ) ;
139-
140- } catch ( err ) {
141- console . error ( "Fehler beim initialen Daten-Load:" , err ) ;
75+
76+ if ( res . ok ) {
77+ location . reload ( ) ; // Seite neu laden, um Standard-HTML zu zeigen
14278 }
143-
144- // --- PHASE 4: Intervalle für Updates starten ---
145- setInterval ( ( ) => { if ( typeof updateLive === "function" ) updateLive ( ) ; } , 5000 ) ;
146- setInterval ( ( ) => { if ( typeof fetchData === "function" ) fetchData ( ) ; } , 60000 ) ;
147- setInterval ( ( ) => { if ( typeof updatePeaks === "function" ) updatePeaks ( ) ; } , 60000 ) ;
148- setInterval ( ( ) => { if ( typeof checkLoadingStatus === "function" ) checkLoadingStatus ( ) ; } , 500 ) ;
149-
150- // WICHTIG: Einmal kräftig schütteln, damit Charts ihre Größe im neuen Grid finden
151- setTimeout ( ( ) => {
152- window . dispatchEvent ( new Event ( 'resize' ) ) ;
153- } , 200 ) ;
154- } ) ;
79+ }
0 commit comments