| @ -0,0 +1,118 @@ | |||||
| package api | |||||
| import ( | |||||
| "context" | |||||
| "git.brettb.xyz/goinv/server/internal/types" | |||||
| "github.com/go-chi/chi/v5" | |||||
| "github.com/go-chi/render" | |||||
| "net/http" | |||||
| "strconv" | |||||
| ) | |||||
| func (s *APIServer) setupCategoryRoutes() func(chi.Router) { | |||||
| return func(r chi.Router) { | |||||
| r.Get("/", makeHandler(s.getCategories)) | |||||
| r.Post("/", makeHandler(s.createCategory)) | |||||
| r.Route("/{categoryID}", func(r chi.Router) { | |||||
| r.Use(s.CategoryCtx) | |||||
| r.Get("/", makeHandler(s.getCategory)) | |||||
| r.Delete("/", makeHandler(s.deleteCategory)) | |||||
| }) | |||||
| } | |||||
| } | |||||
| func (s *APIServer) CategoryCtx(next http.Handler) http.Handler { | |||||
| return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |||||
| categoryIdStr := chi.URLParam(r, "categoryID") | |||||
| categoryId, err := strconv.ParseUint(categoryIdStr, 10, 64) | |||||
| if err != nil { | |||||
| render.Render(w, r, errNotFound) | |||||
| return | |||||
| } | |||||
| shelf, err := s.db.GetCategoryByID(categoryId) | |||||
| if err != nil { | |||||
| render.Render(w, r, errNotFound) | |||||
| return | |||||
| } | |||||
| ctx := context.WithValue(r.Context(), "category", shelf) | |||||
| next.ServeHTTP(w, r.WithContext(ctx)) | |||||
| }) | |||||
| } | |||||
| func (s *APIServer) getCategories(w http.ResponseWriter, r *http.Request) error { | |||||
| categories, err := s.db.GetCategories(0, 10) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| total, err := s.db.TotalCategories() | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| return render.Render(w, r, &types.MultipleCategoryResponse{ | |||||
| Response: &types.Response{ | |||||
| HTTPStatusCode: http.StatusOK, | |||||
| }, | |||||
| Categories: categories, | |||||
| Total: total, | |||||
| }) | |||||
| } | |||||
| func (s *APIServer) getCategory(w http.ResponseWriter, r *http.Request) error { | |||||
| ctx := r.Context() | |||||
| category, ok := ctx.Value("category").(*types.Category) | |||||
| if !ok { | |||||
| return render.Render(w, r, errUnprocessable) | |||||
| } | |||||
| return render.Render(w, r, &types.CategoryResponse{ | |||||
| Response: &types.Response{ | |||||
| HTTPStatusCode: http.StatusOK, | |||||
| }, | |||||
| Category: category, | |||||
| }) | |||||
| } | |||||
| func (s *APIServer) deleteCategory(w http.ResponseWriter, r *http.Request) error { | |||||
| ctx := r.Context() | |||||
| category, ok := ctx.Value("category").(*types.Category) | |||||
| if !ok { | |||||
| return render.Render(w, r, errUnprocessable) | |||||
| } | |||||
| if ok, _ := s.db.DeleteCategoryByID(category.ID); !ok { | |||||
| return render.Render(w, r, errUnprocessable) | |||||
| } | |||||
| return render.Render(w, r, &types.CategoryResponse{ | |||||
| Response: &types.Response{ | |||||
| HTTPStatusCode: http.StatusOK, | |||||
| }, | |||||
| Category: category, | |||||
| }) | |||||
| } | |||||
| func (s *APIServer) createCategory(w http.ResponseWriter, r *http.Request) error { | |||||
| data := &types.CreateCategoryRequest{} | |||||
| if err := render.Bind(r, data); err != nil { | |||||
| return render.Render(w, r, errBadRequest(err)) | |||||
| } | |||||
| category := &types.Category{ | |||||
| Name: data.Name, | |||||
| } | |||||
| err := s.db.CreateCategory(category) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| return render.Render(w, r, &types.CategoryResponse{ | |||||
| Response: &types.Response{ | |||||
| HTTPStatusCode: http.StatusOK, | |||||
| }, | |||||
| Category: category, | |||||
| }) | |||||
| } | |||||