From 1dfa0c9b3295fc4e97b0815a64dcc14ac03a9e8d Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 22 Aug 2025 08:35:13 +0200 Subject: [PATCH] Urlaubsmodus implementiert - Globale Checkbox zum Deaktivieren des Schedulers --- cmd/server/main.go | 4 +++ internal/database/database.go | 50 +++++++++++++++++++++++++++ internal/handlers/pc_handler.go | 52 ++++++++++++++++++++++++++++ internal/scheduler/scheduler.go | 13 ++++++- web/static/script.js | 60 +++++++++++++++++++++++++++++++++ web/templates/index.html | 16 +++++++++ 6 files changed, 194 insertions(+), 1 deletion(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index f5cc109..34d0f1a 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -79,6 +79,10 @@ func main() { r.GET("/api/logs", pcHandler.GetAllLogs) r.GET("/api/logs/pc/:id", pcHandler.GetLogsByPCID) r.GET("/api/logs/pc/:id/recent", pcHandler.GetRecentLogsByPCID) + + // Settings-API + r.GET("/api/settings/vacation-mode", pcHandler.GetVacationMode) + r.POST("/api/settings/vacation-mode", pcHandler.SetVacationMode) // Statische Dateien bereitstellen (nach den spezifischen Routen) r.Static("/static", "./web/static") diff --git a/internal/database/database.go b/internal/database/database.go index 3db3f38..73fdd4f 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -56,6 +56,27 @@ func InitDB() (*DB, error) { return nil, err } + // Settings-Tabelle erstellen + createSettingsTableSQL := ` + CREATE TABLE IF NOT EXISTS settings ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + key TEXT NOT NULL UNIQUE, + value TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP + );` + + _, err = db.Exec(createSettingsTableSQL) + if err != nil { + return nil, err + } + + // Standard-Einstellungen setzen + _, err = db.Exec("INSERT OR IGNORE INTO settings (key, value) VALUES ('vacation_mode', 'false')") + if err != nil { + return nil, err + } + // Füge IP-Spalte hinzu, falls sie nicht existiert _, err = db.Exec("ALTER TABLE pcs ADD COLUMN ip TEXT DEFAULT ''") if err != nil { @@ -267,3 +288,32 @@ func (db *DB) GetRecentLogsByPCID(pcID int) ([]models.LogEvent, error) { return logs, nil } + +// GetSetting holt eine Einstellung aus der Datenbank +func (db *DB) GetSetting(key string) (string, error) { + var value string + err := db.QueryRow("SELECT value FROM settings WHERE key = ?", key).Scan(&value) + if err != nil { + return "", err + } + return value, nil +} + +// SetSetting setzt eine Einstellung in der Datenbank +func (db *DB) SetSetting(key, value string) error { + now := time.Now() + _, err := db.Exec( + "INSERT OR REPLACE INTO settings (key, value, updated_at) VALUES (?, ?, ?)", + key, value, now, + ) + return err +} + +// IsVacationModeEnabled prüft, ob der Urlaubsmodus aktiviert ist +func (db *DB) IsVacationModeEnabled() (bool, error) { + value, err := db.GetSetting("vacation_mode") + if err != nil { + return false, err + } + return value == "true", nil +} diff --git a/internal/handlers/pc_handler.go b/internal/handlers/pc_handler.go index 167e41e..a490292 100644 --- a/internal/handlers/pc_handler.go +++ b/internal/handlers/pc_handler.go @@ -327,3 +327,55 @@ func (h *PCHandler) GetRecentLogsByPCID(c *gin.Context) { Logs: logs, }) } + +// GetVacationMode gibt den aktuellen Urlaubsmodus-Status zurück +func (h *PCHandler) GetVacationMode(c *gin.Context) { + enabled, err := h.db.IsVacationModeEnabled() + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "success": false, + "message": "Fehler beim Laden des Urlaubsmodus: " + err.Error(), + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "success": true, + "vacation_mode": enabled, + }) +} + +// SetVacationMode setzt den Urlaubsmodus +func (h *PCHandler) SetVacationMode(c *gin.Context) { + var req struct { + VacationMode bool `json:"vacation_mode" binding:"required"` + } + + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "success": false, + "message": "Ungültige Anfrage: " + err.Error(), + }) + return + } + + value := "false" + if req.VacationMode { + value = "true" + } + + err := h.db.SetSetting("vacation_mode", value) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "success": false, + "message": "Fehler beim Speichern des Urlaubsmodus: " + err.Error(), + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "success": true, + "message": "Urlaubsmodus erfolgreich aktualisiert", + "vacation_mode": req.VacationMode, + }) +} diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index 5d0abaf..0d3ae09 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -57,8 +57,19 @@ func (s *Scheduler) run() { // checkAndExecuteScheduledTasks prüft alle geplanten Aufgaben func (s *Scheduler) checkAndExecuteScheduledTasks() { - now := time.Now() + // Prüfe zuerst, ob der Urlaubsmodus aktiviert ist + vacationMode, err := s.db.IsVacationModeEnabled() + if err != nil { + log.Printf("Fehler beim Prüfen des Urlaubsmodus: %v", err) + return + } + + if vacationMode { + log.Println("Urlaubsmodus aktiviert - Autostart deaktiviert") + return + } + now := time.Now() // Alle PCs mit aktiviertem Autostart holen pcs, err := s.db.GetPCsWithAutostart() if err != nil { diff --git a/web/static/script.js b/web/static/script.js index c0eb2c7..8d062bb 100644 --- a/web/static/script.js +++ b/web/static/script.js @@ -12,6 +12,7 @@ class PCManager { init() { this.loadPCs(); + this.loadVacationMode(); this.setupEventListeners(); this.startAutoStatus(); } @@ -47,6 +48,11 @@ class PCManager { document.getElementById('refreshStatusBtn').addEventListener('click', () => { this.refreshStatus(); }); + + // Urlaubsmodus Checkbox + document.getElementById('vacationMode').addEventListener('change', (e) => { + this.setVacationMode(e.target.checked); + }); } async loadPCs() { @@ -460,6 +466,60 @@ class PCManager { content += ''; return content; } + + // Urlaubsmodus laden + async loadVacationMode() { + try { + const response = await fetch('/api/settings/vacation-mode'); + const data = await response.json(); + + if (data.success) { + const vacationModeCheckbox = document.getElementById('vacationMode'); + if (vacationModeCheckbox) { + vacationModeCheckbox.checked = data.vacation_mode; + } + } + } catch (error) { + console.error('Fehler beim Laden des Urlaubsmodus:', error); + } + } + + // Urlaubsmodus setzen + async setVacationMode(enabled) { + try { + const response = await fetch('/api/settings/vacation-mode', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + vacation_mode: enabled + }) + }); + + const data = await response.json(); + + if (data.success) { + const status = enabled ? 'aktiviert' : 'deaktiviert'; + this.showNotification('Erfolg', `Urlaubsmodus ${status}`, 'success'); + } else { + this.showNotification('Fehler', data.message, 'danger'); + // Checkbox zurücksetzen bei Fehler + const vacationModeCheckbox = document.getElementById('vacationMode'); + if (vacationModeCheckbox) { + vacationModeCheckbox.checked = !enabled; + } + } + } catch (error) { + console.error('Fehler beim Setzen des Urlaubsmodus:', error); + this.showNotification('Fehler', 'Fehler beim Setzen des Urlaubsmodus', 'danger'); + // Checkbox zurücksetzen bei Fehler + const vacationModeCheckbox = document.getElementById('vacationMode'); + if (vacationModeCheckbox) { + vacationModeCheckbox.checked = !enabled; + } + } + } } // PC Manager initialisieren, wenn die Seite geladen ist diff --git a/web/templates/index.html b/web/templates/index.html index f0aec79..2cd7b3d 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -42,6 +42,22 @@ + +
+
+
+ + + +
+
+
+