250 lines
5.2 KiB
Go
250 lines
5.2 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"github.com/gin-gonic/gin"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
)
|
|
|
|
type ViewModel struct {
|
|
Users []User
|
|
CurrentUser int
|
|
Allowances []Allowance
|
|
Tasks []Task
|
|
History []History
|
|
Error string
|
|
}
|
|
|
|
func loadWebEndpoints(router *gin.Engine) {
|
|
router.LoadHTMLFiles("web.gohtml")
|
|
router.GET("/", renderIndex)
|
|
router.GET("/login", renderLogin)
|
|
router.POST("/createTask", renderCreateTask)
|
|
router.GET("/completeTask", renderCompleteTask)
|
|
router.POST("/createAllowance", renderCreateAllowance)
|
|
router.GET("/completeAllowance", renderCompleteAllowance)
|
|
}
|
|
|
|
func redirectToPage(c *gin.Context, page string) {
|
|
redirectToPageStatus(c, page, http.StatusSeeOther)
|
|
}
|
|
|
|
func redirectToPageStatus(c *gin.Context, page string, status int) {
|
|
scheme := c.Request.URL.Scheme
|
|
target := scheme + domain + page
|
|
c.Redirect(status, target)
|
|
}
|
|
|
|
func renderLogin(c *gin.Context) {
|
|
if c.Query("user") != "" {
|
|
log.Println("Set cookie for user:", c.Query("user"))
|
|
c.SetCookie("user", c.Query("user"), 3600, "", "", false, true)
|
|
}
|
|
redirectToPage(c, "/")
|
|
}
|
|
|
|
func renderIndex(c *gin.Context) {
|
|
currentUser := getCurrentUser(c)
|
|
if currentUser == nil {
|
|
return
|
|
}
|
|
renderWithUser(c, *currentUser)
|
|
}
|
|
|
|
func renderCreateTask(c *gin.Context) {
|
|
currentUser := getCurrentUser(c)
|
|
if currentUser == nil {
|
|
return
|
|
}
|
|
|
|
name := c.PostForm("name")
|
|
rewardStr := c.PostForm("reward")
|
|
reward, err := strconv.ParseFloat(rewardStr, 64)
|
|
if err != nil {
|
|
renderError(c, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
if name == "" || reward <= 0 {
|
|
renderError(c, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
request := &CreateTaskRequest{
|
|
Name: name,
|
|
Reward: reward,
|
|
}
|
|
|
|
schedule := c.PostForm("schedule")
|
|
if schedule != "" {
|
|
request.Schedule = &schedule
|
|
}
|
|
|
|
_, err = db.CreateTask(request)
|
|
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
redirectToPageStatus(c, "/", http.StatusFound)
|
|
}
|
|
|
|
func renderCompleteTask(c *gin.Context) {
|
|
taskIDStr := c.Query("task")
|
|
taskID, err := strconv.Atoi(taskIDStr)
|
|
if err != nil {
|
|
renderError(c, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
err = db.CompleteTask(taskID)
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
redirectToPageStatus(c, "/", http.StatusFound)
|
|
}
|
|
|
|
func renderCreateAllowance(c *gin.Context) {
|
|
currentUser := getCurrentUser(c)
|
|
if currentUser == nil {
|
|
return
|
|
}
|
|
|
|
name := c.PostForm("name")
|
|
targetStr := c.PostForm("target")
|
|
target, err := strconv.ParseFloat(targetStr, 64)
|
|
if err != nil {
|
|
renderError(c, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
weightStr := c.PostForm("weight")
|
|
weight, err := strconv.ParseFloat(weightStr, 64)
|
|
if err != nil {
|
|
renderError(c, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
if name == "" || target <= 0 || weight <= 0 {
|
|
renderError(c, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
_, err = db.CreateAllowance(*currentUser, &CreateAllowanceRequest{
|
|
Name: name,
|
|
Target: target,
|
|
Weight: weight,
|
|
})
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
redirectToPageStatus(c, "/", http.StatusFound)
|
|
}
|
|
|
|
func renderCompleteAllowance(c *gin.Context) {
|
|
currentUser := getCurrentUser(c)
|
|
if currentUser == nil {
|
|
return
|
|
}
|
|
|
|
allowanceIDStr := c.Query("allowance")
|
|
allowanceID, err := strconv.Atoi(allowanceIDStr)
|
|
if err != nil {
|
|
renderError(c, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
err = db.CompleteAllowance(*currentUser, allowanceID)
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
redirectToPageStatus(c, "/", http.StatusFound)
|
|
}
|
|
|
|
func getCurrentUser(c *gin.Context) *int {
|
|
currentUserStr, err := c.Cookie("user")
|
|
log.Println("Cookie string:", currentUserStr)
|
|
if errors.Is(err, http.ErrNoCookie) {
|
|
renderNoUser(c)
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
unsetUserCookie(c)
|
|
return nil
|
|
}
|
|
currentUser, err := strconv.Atoi(currentUserStr)
|
|
if err != nil {
|
|
unsetUserCookie(c)
|
|
return nil
|
|
}
|
|
userExists, err := db.UserExists(currentUser)
|
|
if !userExists || err != nil {
|
|
unsetUserCookie(c)
|
|
return nil
|
|
}
|
|
return ¤tUser
|
|
}
|
|
|
|
func unsetUserCookie(c *gin.Context) {
|
|
c.SetCookie("user", "", -1, "/", "localhost", false, true)
|
|
redirectToPageStatus(c, "/", http.StatusFound)
|
|
}
|
|
|
|
func renderNoUser(c *gin.Context) {
|
|
users, err := db.GetUsers()
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
c.HTML(http.StatusOK, "web.gohtml", ViewModel{
|
|
Users: users,
|
|
})
|
|
}
|
|
|
|
func renderWithUser(c *gin.Context, currentUser int) {
|
|
users, err := db.GetUsers()
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
allowances, err := db.GetUserAllowances(currentUser)
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
tasks, err := db.GetTasks()
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
history, err := db.GetHistory(currentUser)
|
|
if err != nil {
|
|
renderError(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
c.HTML(http.StatusOK, "web.gohtml", ViewModel{
|
|
Users: users,
|
|
CurrentUser: currentUser,
|
|
Allowances: allowances,
|
|
Tasks: tasks,
|
|
History: history,
|
|
})
|
|
}
|
|
|
|
func renderError(c *gin.Context, statusCode int, err error) {
|
|
c.HTML(statusCode, "web.gohtml", ViewModel{
|
|
Error: err.Error(),
|
|
})
|
|
}
|