Files
HeatGuard/internal/cli/web.go
vikingowl 1c9db02334 feat: add web UI with full CRUD setup page
Add server-side rendered setup UI accessible via `heatwave web`.
The dashboard is now re-rendered per request and includes a nav bar
linking to the new /setup page. Setup provides full CRUD for profiles,
rooms, devices, occupants, AC units (with room assignment), scenario
toggles, and forecast fetching — all via POST/redirect/GET forms.

- Add ShowNav field to DashboardData for conditional nav bar
- Extract fetchForecastForProfile() for reuse by web handler
- Create setup.html.tmpl with Tailwind-styled entity sections
- Create web_handlers.go with 15 route handlers and flash cookies
- Switch web.go from pre-rendered to per-request dashboard rendering
- Graceful dashboard fallback when no forecast data exists
2026-02-09 10:39:00 +01:00

58 lines
1.3 KiB
Go

package cli
import (
"fmt"
"net"
"net/http"
"time"
"github.com/spf13/cobra"
)
var (
webPort int
webDate string
webOpen bool
)
func init() {
webCmd := &cobra.Command{
Use: "web",
Short: "Start local web server with the heat dashboard",
Long: "Generates the heat report and serves it via a local HTTP server. Shortcut for 'heatwave report serve'.",
RunE: func(cmd *cobra.Command, args []string) error {
dateStr := webDate
if dateStr == "" {
dateStr = time.Now().Format("2006-01-02")
}
return runWebServer(dateStr, webPort, webOpen)
},
}
webCmd.Flags().IntVar(&webPort, "port", 8080, "HTTP port to serve on")
webCmd.Flags().StringVar(&webDate, "date", "", "date (YYYY-MM-DD, default: today)")
webCmd.Flags().BoolVar(&webOpen, "open", true, "open browser automatically")
rootCmd.AddCommand(webCmd)
}
// runWebServer starts the web server with dashboard + setup UI.
func runWebServer(dateStr string, port int, open bool) error {
mux := http.NewServeMux()
registerSetupRoutes(mux, dateStr)
addr := fmt.Sprintf(":%d", port)
ln, err := net.Listen("tcp", addr)
if err != nil {
return fmt.Errorf("listen %s: %w", addr, err)
}
url := fmt.Sprintf("http://localhost:%d", port)
fmt.Printf("Serving heat dashboard at %s (Ctrl+C to stop)\n", url)
if open {
openBrowser(url)
}
return http.Serve(ln, mux)
}