diff --git a/router/projects.go b/router/projects.go index fd6741e..efb8882 100644 --- a/router/projects.go +++ b/router/projects.go @@ -15,18 +15,34 @@ func (router *router) projects(w http.ResponseWriter, r *http.Request) { router.assert.NotNil(w) router.assert.NotNil(r) - id := r.PathValue("id") - if id != "" { - router.getProject(w, r) - return - } + switch getMethod(r) { + case http.MethodGet, http.MethodHead: + if id := r.PathValue("id"); id != "" { + router.getProject(w, r) + } else { + router.listProjects(w, r) + } - if r.Method == http.MethodGet { - router.listProjects(w, r) - return - } + case http.MethodPost: + router.createProject(w, r) - router.createProject(w, r) + case http.MethodDelete: + if id := r.PathValue("id"); id != "" { + router.deleteProject(w, r) + } else { + exception. + BadRequest(errors.New(`missing "id" path value`)). + ServeHTTP(w, r) + } + + default: + exception.MethodNotAllowed([]string{ + http.MethodHead, + http.MethodGet, + http.MethodPost, + http.MethodDelete, + }).ServeHTTP(w, r) + } } func (router *router) createProject(w http.ResponseWriter, r *http.Request) { @@ -34,7 +50,7 @@ func (router *router) createProject(w http.ResponseWriter, r *http.Request) { router.assert.NotNil(r) router.assert.NotNil(router.service) - if r.Method != http.MethodPost { + if getMethod(r) != http.MethodPost { exception. MethodNotAllowed([]string{http.MethodPost}). ServeHTTP(w, r) @@ -58,7 +74,7 @@ func (router *router) getProject(w http.ResponseWriter, r *http.Request) { router.assert.NotNil(router.service) router.assert.NotNil(router.templates) - if r.Method != http.MethodGet && r.Method != http.MethodHead { + if getMethod(r) != http.MethodGet && getMethod(r) != http.MethodHead { exception. MethodNotAllowed([]string{http.MethodGet, http.MethodHead}). ServeHTTP(w, r) @@ -97,6 +113,13 @@ func (router *router) listProjects(w http.ResponseWriter, r *http.Request) { router.assert.NotNil(router.service) router.assert.NotNil(router.templates) + if getMethod(r) != http.MethodGet && getMethod(r) != http.MethodHead { + exception. + MethodNotAllowed([]string{http.MethodGet, http.MethodHead}). + ServeHTTP(w, r) + return + } + ps, err := router.service.ListProjects() if err != nil { exception.InternalServerError(err).ServeHTTP(w, r) @@ -117,3 +140,42 @@ func (router *router) listProjects(w http.ResponseWriter, r *http.Request) { return } } + +func (router *router) deleteProject(w http.ResponseWriter, r *http.Request) { + router.assert.NotNil(w) + router.assert.NotNil(r) + router.assert.NotNil(router.service) + router.assert.NotNil(router.templates) + + if getMethod(r) != http.MethodDelete { + exception. + MethodNotAllowed([]string{http.MethodDelete}). + ServeHTTP(w, r) + return + } + + id := r.PathValue("id") + if id == "" { + exception. + BadRequest(fmt.Errorf(`a valid path value of "id" must be provided`)). + ServeHTTP(w, r) + return + } + + err := router.service.DeleteProject(id) + if err != nil { + exception.InternalServerError(err).ServeHTTP(w, r) + return + } + + err = router.templates.ExecuteTemplate(w, "partials-status", map[string]any{ + "StatusCode": http.StatusOK, + "Message": fmt.Sprintf("Project %q successfully deleted", id), + "Redirect": "/dashboard/", + "RedirectMessage": "Go back to dashboard", + }) + if err != nil { + exception.InternalServerError(err).ServeHTTP(w, r) + return + } +} diff --git a/router/router.go b/router/router.go index ab82f5b..e484b9a 100644 --- a/router/router.go +++ b/router/router.go @@ -5,6 +5,7 @@ import ( "io/fs" "log/slog" "net/http" + "strings" "forge.capytal.company/capytalcode/project-comicverse/service" "forge.capytal.company/capytalcode/project-comicverse/templates" @@ -117,3 +118,16 @@ func (router *router) dashboard(w http.ResponseWriter, r *http.Request) { exception.InternalServerError(err).ServeHTTP(w, r) } } + +func getMethod(r *http.Request) string { + if r.Method == http.MethodGet || r.Method == http.MethodHead { + return r.Method + } + + m := r.FormValue("x-method") + if m == "" { + return r.Method + } + + return strings.ToUpper(m) +} diff --git a/templates/dashboard.html b/templates/dashboard.html index bebc74d..54787f0 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -2,7 +2,7 @@ {{template "layout-page-start" (args "Title" "Dashboard")}}
{{if and (ne . nil) (ne (len .) 0)}} -
+

Projects

@@ -11,13 +11,19 @@
-
+
{{range .}} - +
Image

{{.Title}}

{{.ID}}

+
+ + +
{{end}} diff --git a/templates/partials/status.html b/templates/partials/status.html new file mode 100644 index 0000000..a81654d --- /dev/null +++ b/templates/partials/status.html @@ -0,0 +1,17 @@ +{{define "partials-status"}} +{{template "layout-page-start" (args "Title" .Title)}} +
+ +
+{{template "layout-page-end"}} +{{end}} diff --git a/templates/templates.go b/templates/templates.go index 3a80243..8f1217f 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -12,7 +12,7 @@ import ( ) var ( - patterns = []string{"*.html", "layouts/*.html"} + patterns = []string{"*.html", "layouts/*.html", "partials/*.html"} functions = template.FuncMap{ "args": func(pairs ...any) (map[string]any, error) { if len(pairs)%2 != 0 { @@ -35,7 +35,7 @@ var ( } ) -//go:embed *.html layouts/*.html +//go:embed *.html layouts/*.html partials/*.html var embedded embed.FS var temps = template.Must(template.New("templates").Funcs(functions).ParseFS(embedded, patterns...))