diff --git a/cmds/server.go b/cmds/server.go index 40c2690..6b2e71b 100644 --- a/cmds/server.go +++ b/cmds/server.go @@ -112,6 +112,7 @@ Starting weiro without any arguments will start the server. ph := handlers.PostsHandler{PostService: svcs.Posts} uh := handlers.UploadsHandler{UploadsService: svcs.Uploads} ssh := handlers.SiteSettingsHandler{SiteService: svcs.Sites} + ch := handlers.CategoriesHandler{CategoryService: svcs.Categories} app.Get("/login", lh.Login) app.Post("/login", lh.DoLogin) @@ -141,6 +142,13 @@ Starting weiro without any arguments will start the server. siteGroup.Get("/settings", ssh.General) siteGroup.Post("/settings", ssh.UpdateGeneral) + siteGroup.Get("/categories", ch.Index) + siteGroup.Get("/categories/new", ch.New) + siteGroup.Get("/categories/:categoryID", ch.Edit) + siteGroup.Post("/categories", ch.Create) + siteGroup.Post("/categories/:categoryID", ch.Update) + siteGroup.Post("/categories/:categoryID/delete", ch.Delete) + app.Get("/", middleware.OptionalUser(svcs.Auth), ih.Index) app.Get("/first-run", ih.FirstRun) app.Post("/first-run", ih.FirstRunSubmit) diff --git a/handlers/categories.go b/handlers/categories.go new file mode 100644 index 0000000..ec5e9ca --- /dev/null +++ b/handlers/categories.go @@ -0,0 +1,101 @@ +package handlers + +import ( + "fmt" + "strconv" + + "github.com/gofiber/fiber/v3" + "lmika.dev/lmika/weiro/models" + "lmika.dev/lmika/weiro/services/categories" +) + +type CategoriesHandler struct { + CategoryService *categories.Service +} + +func (ch CategoriesHandler) Index(c fiber.Ctx) error { + cats, err := ch.CategoryService.ListCategoriesWithCounts(c.Context()) + if err != nil { + return err + } + + return c.Render("categories/index", fiber.Map{ + "categories": cats, + }) +} + +func (ch CategoriesHandler) New(c fiber.Ctx) error { + cat := models.Category{ + GUID: models.NewNanoID(), + } + return c.Render("categories/edit", fiber.Map{ + "category": cat, + "isNew": true, + }) +} + +func (ch CategoriesHandler) Edit(c fiber.Ctx) error { + catID, err := strconv.ParseInt(c.Params("categoryID"), 10, 64) + if err != nil { + return fiber.ErrBadRequest + } + + cat, err := ch.CategoryService.GetCategory(c.Context(), catID) + if err != nil { + return err + } + + return c.Render("categories/edit", fiber.Map{ + "category": cat, + "isNew": false, + }) +} + +func (ch CategoriesHandler) Create(c fiber.Ctx) error { + var req categories.CreateCategoryParams + if err := c.Bind().Body(&req); err != nil { + return err + } + + _, err := ch.CategoryService.CreateCategory(c.Context(), req) + if err != nil { + return err + } + + site := models.MustGetSite(c.Context()) + return c.Redirect().To(fmt.Sprintf("/sites/%v/categories", site.ID)) +} + +func (ch CategoriesHandler) Update(c fiber.Ctx) error { + catID, err := strconv.ParseInt(c.Params("categoryID"), 10, 64) + if err != nil { + return fiber.ErrBadRequest + } + + var req categories.CreateCategoryParams + if err := c.Bind().Body(&req); err != nil { + return err + } + + _, err = ch.CategoryService.UpdateCategory(c.Context(), catID, req) + if err != nil { + return err + } + + site := models.MustGetSite(c.Context()) + return c.Redirect().To(fmt.Sprintf("/sites/%v/categories", site.ID)) +} + +func (ch CategoriesHandler) Delete(c fiber.Ctx) error { + catID, err := strconv.ParseInt(c.Params("categoryID"), 10, 64) + if err != nil { + return fiber.ErrBadRequest + } + + if err := ch.CategoryService.DeleteCategory(c.Context(), catID); err != nil { + return err + } + + site := models.MustGetSite(c.Context()) + return c.Redirect().To(fmt.Sprintf("/sites/%v/categories", site.ID)) +} diff --git a/services/services.go b/services/services.go index 606e932..beb6727 100644 --- a/services/services.go +++ b/services/services.go @@ -7,6 +7,7 @@ import ( "lmika.dev/lmika/weiro/providers/db" "lmika.dev/lmika/weiro/providers/uploadfiles" "lmika.dev/lmika/weiro/services/auth" + "lmika.dev/lmika/weiro/services/categories" "lmika.dev/lmika/weiro/services/posts" "lmika.dev/lmika/weiro/services/publisher" "lmika.dev/lmika/weiro/services/sites" @@ -21,6 +22,7 @@ type Services struct { Posts *posts.Service Sites *sites.Service Uploads *uploads.Service + Categories *categories.Service } func New(cfg config.Config) (*Services, error) { @@ -37,6 +39,7 @@ func New(cfg config.Config) (*Services, error) { postService := posts.New(dbp, publisherQueue) siteService := sites.New(dbp) uploadService := uploads.New(dbp, ufp, filepath.Join(cfg.ScratchDir, "uploads", "pending")) + categoriesService := categories.New(dbp, publisherQueue) return &Services{ DB: dbp, @@ -46,6 +49,7 @@ func New(cfg config.Config) (*Services, error) { Posts: postService, Sites: siteService, Uploads: uploadService, + Categories: categoriesService, }, nil } diff --git a/views/_common/nav.html b/views/_common/nav.html index 87801d2..e8bce30 100644 --- a/views/_common/nav.html +++ b/views/_common/nav.html @@ -10,6 +10,9 @@ + diff --git a/views/categories/edit.html b/views/categories/edit.html new file mode 100644 index 0000000..c838778 --- /dev/null +++ b/views/categories/edit.html @@ -0,0 +1,47 @@ +
+
+

{{ if .isNew }}New Category{{ else }}Edit Category{{ end }}

+
+ + {{ if .isNew }} +
+ {{ else }} + + {{ end }} + +
+ +
+ +
+
+
+ +
+ +
Auto-generated from name if left blank.
+
+
+
+ +
+ +
Markdown supported. Displayed on the category archive page.
+
+
+
+
+
+ + {{ if not .isNew }} + + {{ end }} +
+
+
+ + {{ if not .isNew }} + + {{ end }} +
diff --git a/views/categories/index.html b/views/categories/index.html new file mode 100644 index 0000000..f768977 --- /dev/null +++ b/views/categories/index.html @@ -0,0 +1,35 @@ +
+
+

Categories

+
+ New Category +
+
+ + + + + + + + + + + + {{ range .categories }} + + + + + + + {{ else }} + + + + {{ end }} + +
NameSlugPosts
{{ .Name }}{{ .Slug }}{{ .PostCount }} + Edit +
No categories yet.
+