readysite / hosting / controllers / settings.go
2.2 KB
settings.go
package controllers

import (
	"html"
	"net/http"
	"strings"

	"github.com/readysite/readysite/hosting/internal/access"
	"github.com/readysite/readysite/hosting/models"
	"github.com/readysite/readysite/pkg/application"
)

// Settings returns the settings controller.
func Settings() (string, *SettingsController) {
	return "settings", &SettingsController{}
}

// SettingsController handles account settings.
type SettingsController struct {
	application.BaseController
}

// Setup registers routes.
func (c *SettingsController) Setup(app *application.App) {
	c.BaseController.Setup(app)
	http.Handle("GET /settings", app.Serve("settings.html", RequireAuth))
	http.Handle("POST /settings", app.Method(c, "UpdateProfile", RequireAuth))
}

// Handle returns a request-scoped controller instance.
func (c SettingsController) Handle(r *http.Request) application.Controller {
	c.Request = r
	return &c
}

// CurrentUser returns the authenticated user.
func (c *SettingsController) CurrentUser() *models.User {
	return access.GetUserFromJWT(c.Request)
}

// UserSites returns the current user's non-deleted sites.
func (c *SettingsController) UserSites() []*models.Site {
	user := access.GetUserFromJWT(c.Request)
	if user == nil {
		return nil
	}
	sites, err := models.Sites.Search("WHERE UserID = ? AND Status != 'deleted' ORDER BY CreatedAt DESC", user.ID)
	if err != nil {
		return nil
	}
	return sites
}

// UpdateProfile handles the HTMX form submission to update user name.
func (c *SettingsController) UpdateProfile(w http.ResponseWriter, r *http.Request) {
	user := access.GetUserFromJWT(r)
	if user == nil {
		w.Header().Set("Content-Type", "text/html")
		w.Write([]byte(`<div class="text-red-400 text-sm">Not authenticated</div>`))
		return
	}

	name := strings.TrimSpace(r.FormValue("name"))
	if len(name) > 100 {
		name = name[:100]
	}

	user.Name = name
	if err := models.Users.Update(user); err != nil {
		w.Header().Set("Content-Type", "text/html")
		w.Write([]byte(`<div class="text-red-400 text-sm">Failed to save settings. Please try again.</div>`))
		return
	}

	w.Header().Set("Content-Type", "text/html")
	w.Write([]byte(`<div class="text-emerald-400 text-sm">` + html.EscapeString("Settings saved successfully.") + `</div>`))
}
← Back