Files
comicverse/router/projects.go

133 lines
3.0 KiB
Go

package router
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/http"
"code.capytal.cc/capytal/comicverse/service"
"code.capytal.cc/capytal/comicverse/templates"
"code.capytal.cc/loreddev/smalltrip/problem"
"code.capytal.cc/loreddev/x/tinyssert"
"github.com/google/uuid"
)
type projectController struct {
projectSvc *service.Project
templates templates.ITemplate
assert tinyssert.Assertions
}
func newProjectController(
projectService *service.Project,
templates templates.ITemplate,
assertions tinyssert.Assertions,
) *projectController {
return &projectController{
projectSvc: projectService,
templates: templates,
assert: assertions,
}
}
func (ctrl projectController) dashboard(w http.ResponseWriter, r *http.Request) {
userCtx := NewUserContext(r.Context())
userID, ok := userCtx.GetUserID()
if !ok {
userCtx.Unathorize(w, r)
return
}
projects, err := ctrl.projectSvc.GetUserProjects(userID)
if err != nil {
problem.NewInternalServerError(err).ServeHTTP(w, r)
return
}
ps := make([]struct {
ID string
Title string
}, len(projects))
for i, project := range projects {
ps[i] = struct {
ID string
Title string
}{
ID: base64.URLEncoding.EncodeToString([]byte(project.ID.String())),
Title: project.Title,
}
}
err = ctrl.templates.ExecuteTemplate(w, "dashboard", ps)
if err != nil {
problem.NewInternalServerError(err).ServeHTTP(w, r)
}
}
func (ctrl projectController) getProject(w http.ResponseWriter, r *http.Request) {
// TODO: Handle private projects
shortProjectID := r.PathValue("projectID")
id, err := base64.URLEncoding.DecodeString(shortProjectID)
if err != nil {
problem.NewBadRequest(fmt.Sprintf("Incorrectly encoded project ID: %s", err.Error())).ServeHTTP(w, r)
return
}
projectID, err := uuid.ParseBytes(id)
if err != nil {
problem.NewBadRequest("Project ID is not a valid UUID").ServeHTTP(w, r)
return
}
project, err := ctrl.projectSvc.GetProject(projectID)
if errors.Is(err, service.ErrNotFound) {
problem.NewNotFound().ServeHTTP(w, r)
return
} else if err != nil {
problem.NewInternalServerError(err).ServeHTTP(w, r)
return
}
// TODO: Return project template
b, err := json.Marshal(project)
w.Header().Add("Content-Type", "application/json")
if _, err := w.Write(b); err != nil {
problem.NewInternalServerError(err).ServeHTTP(w, r)
return
}
}
func (ctrl projectController) createProject(w http.ResponseWriter, r *http.Request) {
userCtx := NewUserContext(r.Context())
userID, ok := userCtx.GetUserID()
if !ok {
userCtx.Unathorize(w, r)
return
}
title := r.FormValue("title")
if title == "" {
problem.NewBadRequest(`Missing "title" parameter`).ServeHTTP(w, r)
return
}
project, err := ctrl.projectSvc.Create(title, userID)
if err != nil {
problem.NewInternalServerError(err).ServeHTTP(w, r)
return
}
path := fmt.Sprintf("/p/%s/", base64.URLEncoding.EncodeToString([]byte(project.ID.String())))
http.Redirect(w, r, path, http.StatusSeeOther)
}