package apis import ( "errors" "fmt" "net/http" "strconv" "github.com/gin-gonic/gin" . "planner/core" ) func createPlan(c *gin.Context) { u := extractUser(db, c) if u == nil { return } var plan_req struct { Name string `json:"name" form:"name"` } c.Bind(&plan_req) var plan Plan = Plan{ Name: plan_req.Name, Owner: u.Username, Members: []Member{ { UserID: u.Username, Type: "user", Status: "ready", JoinCode: "owner", }, }, } result := db.Create(&plan) if result.Error != nil { c.JSON(http.StatusInternalServerError, result.Error) } else { c.JSON(http.StatusOK, plan_req) } } func listPlans(c *gin.Context) { u := extractUser(db, c) if u == nil { return } plans, err := u.GetPlans(db) if err == nil { c.JSON(http.StatusOK, plans) } else { c.String(http.StatusInternalServerError, err.Error()) } } func getPlan(c *gin.Context) { user := extractUser(db, c) if user == nil { return } var params struct { Id uint `uri:"id"` } bind_result := c.BindUri(¶ms) if bind_result != nil { return } plan, err := GetPlan(db, *user, params.Id) if err == nil { c.JSON(http.StatusOK, plan) } else if errors.Is(err, ErrNotMember) { c.Status(http.StatusForbidden) } else if errors.Is(err, ErrNotFound) { c.Status(http.StatusNotFound) } else { c.String(http.StatusInternalServerError, err.Error()) } } func listPlanMembers(c *gin.Context) { user := extractUser(db, c) if user == nil { return } plan_id, err := strconv.Atoi(c.Param("id")) if err != nil { c.Status(http.StatusBadRequest) return } plan, err := GetPlan(db, *user, uint(plan_id)) members, err := plan.GetAllUsers(db) if err == nil { c.JSON(http.StatusOK, members) } else if errors.Is(err, ErrNotMember) { c.Status(http.StatusForbidden) } else if errors.Is(err, ErrNotFound) { c.Status(http.StatusNotFound) } else { c.String(http.StatusInternalServerError, err.Error()) } } func addPlanMember(c *gin.Context) { user := extractUser(db, c) if user == nil { return } plan_id, err := strconv.Atoi(c.Param("id")) if err != nil { c.Status(http.StatusBadRequest) return } plan, err := GetPlan(db, *user, uint(plan_id)) var new_member Member if err := c.ShouldBind(&new_member); err != nil { c.String(http.StatusInternalServerError, err.Error()) return } err = plan.AddMember(db, &new_member) if err == nil { c.JSON(http.StatusOK, new_member) } else if errors.Is(err, ErrNotMember) { c.Status(http.StatusForbidden) } else if errors.Is(err, ErrNotFound) { c.Status(http.StatusNotFound) } else { c.String(http.StatusInternalServerError, err.Error()) } } func joinPlan(c *gin.Context) { user := extractUser(db, c) if user == nil { return } plan_id, err := strconv.Atoi(c.Param("id")) if err != nil { c.Status(http.StatusBadRequest) return } plan, err := GetPlan(db, *user, uint(plan_id)) if err != nil { c.Status(http.StatusInternalServerError) return } member, err := plan.GetMember(db, user) var query struct { JoinCode string `fdb:"code"` } if c.ShouldBindQuery(&query) != nil || query.JoinCode == "" { c.Status(http.StatusBadRequest) return } if member.Status != "pending" { c.String(http.StatusConflict, "User is not pending") return } if member.JoinCode == query.JoinCode { member.Status = "ready" err := db.Model(&member).Update("status", member.Status).Error if err != nil { c.String(http.StatusInternalServerError, err.Error()) return } } else { c.String(http.StatusConflict, "Invalid join code") return } c.Status(http.StatusOK) } func createPlanPoll(c *gin.Context) { user := extractUser(db, c) if user == nil { return } var params struct { Id uint `uri:"id"` } bind_result := c.BindUri(¶ms) if bind_result != nil { return } plan, err := GetPlan(db, *user, params.Id) if errors.Is(err, ErrNotFound) { c.Status(http.StatusNotFound) return } else if errors.Is(err, ErrNotMember) { c.Status(http.StatusForbidden) return } else if err != nil { c.String(http.StatusInternalServerError, err.Error()) return } var poll_opts struct { Options string `json:"options"` } bind_result = c.Bind(&poll_opts) if bind_result != nil { fmt.Println(bind_result) return } poll := Poll{ PlanID: plan.ID, Options: poll_opts.Options, } db.Create(&poll) c.JSON(http.StatusCreated, poll) } func listPlanPolls(c *gin.Context) { user := extractUser(db, c) if user == nil { return } var params struct { Id uint `uri:"id"` } bind_result := c.BindUri(¶ms) if bind_result != nil { c.Status(http.StatusBadRequest) return } var polls []Poll db.Where("plan_id = ?", params.Id).Find(&polls) c.JSON(http.StatusOK, polls) } func bindPlanAPIs(r *gin.Engine) { r.POST("/plans", createPlan) r.GET("/plans", listPlans) r.GET("/plans/:id", getPlan) r.GET("/plans/:id/members", listPlanMembers) r.POST("/plans/:id/members", addPlanMember) r.GET("/plans/:id/join", joinPlan) r.POST("/plans/:id/polls", createPlanPoll) r.GET("/plans/:id/polls", listPlanPolls) }