package webui import ( "context" "fmt" "html" "io" "strings" "time" "github.com/a-h/templ" "satoru/internal/store" ) type RuntimeCheck struct { Name string Installed bool Details string } type WorkflowStage struct { Title string Description string } type DashboardData struct { Now time.Time User store.User Sites []store.Site RuntimeChecks []RuntimeCheck WorkflowStages []WorkflowStage FlashMessage string } func Dashboard(data DashboardData) templ.Component { return templ.ComponentFunc(func(_ context.Context, w io.Writer) error { role := "Operator" if data.User.IsAdmin { role = "Admin" } var checks strings.Builder for _, c := range data.RuntimeChecks { status := "missing" if c.Installed { status = "installed" } checks.WriteString(fmt.Sprintf(`
  • %s%s
  • `, status, html.EscapeString(c.Name), html.EscapeString(c.Details))) } var flows strings.Builder for _, s := range data.WorkflowStages { flows.WriteString(fmt.Sprintf(`
  • %s

    %s

  • `, html.EscapeString(s.Title), html.EscapeString(s.Description))) } var sites strings.Builder if len(data.Sites) == 0 { sites.WriteString(`

    No sites added yet. Add your first Linux SSH site below.

    `) } for _, site := range data.Sites { last := "Never run" if site.LastRunAt.Valid { last = site.LastRunAt.Time.Local().Format(time.RFC1123) } runStatus := "pending" if site.LastRunStatus.Valid { runStatus = site.LastRunStatus.String } runOutput := "(no output yet)" if site.LastRunOutput.Valid && strings.TrimSpace(site.LastRunOutput.String) != "" { runOutput = site.LastRunOutput.String } sites.WriteString(fmt.Sprintf(`

    %s@%s

    Path: %s

    Last run: %s

    Status: %s

    %s
    `, html.EscapeString(site.SSHUser), html.EscapeString(site.Host), site.ID, html.EscapeString(site.RemotePath), html.EscapeString(last), html.EscapeString(runStatus), html.EscapeString(runStatus), html.EscapeString(runOutput), )) } flash := "" if data.FlashMessage != "" { flash = fmt.Sprintf(`

    %s

    `, html.EscapeString(formatFlash(data.FlashMessage))) } _, err := io.WriteString(w, fmt.Sprintf(` Satoru Dashboard

    Satoru

    Managed Sites Overview

    Signed in as %s (%s).

    Change password
    %s

    Host Runtime Status

    Planned Workflow

      %s

    Add Site

    Managed Sites

    %s
    `, html.EscapeString(data.User.Username), html.EscapeString(role), flash, checks.String(), flows.String(), sites.String(), )) return err }) } func formatFlash(code string) string { switch code { case "site-added": return "Site added." case "site-ran": return "Run completed." case "site-invalid": return "All site fields are required." case "password-updated": return "Password updated." default: return code } }