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
58 lines
1.3 KiB
Go
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)
|
|
}
|