package main import ( "errors" "github.com/gin-gonic/gin" "net/http" "strconv" ) type ViewModel struct { Users []User CurrentUser int Allowances []Allowance Tasks []Task History []History } func loadWebEndpoints(router *gin.Engine) { router.LoadHTMLFiles("web.gohtml") router.GET("/", renderIndex) router.GET("/login", renderLogin) router.POST("/createTask", renderCreateTask) } func renderLogin(c *gin.Context) { if c.Query("user") != "" { c.SetCookie("user", c.Query("user"), 3600, "/", "localhost", false, true) } c.Redirect(http.StatusFound, "/") } func renderIndex(c *gin.Context) { currentUserStr, err := c.Cookie("user") if errors.Is(err, http.ErrNoCookie) { renderNoUser(c) return } if err != nil { unsetUserCookie(c) return } currentUser, err := strconv.Atoi(currentUserStr) if err != nil { unsetUserCookie(c) return } userExists, err := db.UserExists(currentUser) if !userExists || err != nil { unsetUserCookie(c) return } renderWithUser(c, currentUser) } func renderCreateTask(c *gin.Context) { currentUserStr, err := c.Cookie("user") if errors.Is(err, http.ErrNoCookie) { c.HTML(http.StatusBadRequest, "error.gohtml", gin.H{ "error": "User not logged in", }) return } if err != nil { unsetUserCookie(c) return } currentUser, err := strconv.Atoi(currentUserStr) if err != nil { unsetUserCookie(c) return } userExists, err := db.UserExists(currentUser) if !userExists || err != nil { unsetUserCookie(c) return } name := c.PostForm("name") rewardStr := c.PostForm("reward") reward, err := strconv.Atoi(rewardStr) if err != nil { c.HTML(http.StatusBadRequest, "error.gohtml", gin.H{ "error": "Invalid reward value", }) return } if name == "" || reward <= 0 { c.HTML(http.StatusBadRequest, "error.gohtml", gin.H{ "error": "Name and reward must be provided", }) return } _, err = db.CreateTask(&CreateTaskRequest{ Name: name, Reward: reward, }) if err != nil { c.HTML(http.StatusInternalServerError, "error.gohtml", gin.H{ "error": err.Error(), }) return } c.Redirect(http.StatusFound, "/") } func unsetUserCookie(c *gin.Context) { c.SetCookie("user", "", -1, "/", "localhost", false, true) c.Redirect(http.StatusFound, "/") } func renderNoUser(c *gin.Context) { users, err := db.GetUsers() if err != nil { c.HTML(http.StatusInternalServerError, "error.gohtml", gin.H{ "error": err.Error(), }) return } c.HTML(http.StatusOK, "web.gohtml", ViewModel{ Users: users, }) } func renderWithUser(c *gin.Context, currentUser int) { users, err := db.GetUsers() if err != nil { c.HTML(http.StatusInternalServerError, "error.gohtml", gin.H{ "error": err.Error(), }) return } allowances, err := db.GetUserAllowances(currentUser) if err != nil { c.HTML(http.StatusInternalServerError, "error.gohtml", gin.H{ "error": err.Error(), }) return } tasks, err := db.GetTasks() if err != nil { c.HTML(http.StatusInternalServerError, "error.gohtml", gin.H{ "error": err.Error(), }) return } history, err := db.GetHistory(currentUser) if err != nil { c.HTML(http.StatusInternalServerError, "error.gohtml", gin.H{ "error": err.Error(), }) return } c.HTML(http.StatusOK, "web.gohtml", ViewModel{ Users: users, CurrentUser: currentUser, Allowances: allowances, Tasks: tasks, History: history, }) }