package api import ( "context" "net/http" "strconv" "git.brettb.xyz/goinv/server/internal/types" "github.com/go-chi/chi/v5" "github.com/go-chi/render" ) func (s *APIServer) setupShelfRoutes() func(chi.Router) { return func(r chi.Router) { r.Get("/", makeHandler(s.getShelves)) r.Post("/", makeHandler(s.createShelf)) r.Route("/{shelfId}", func(r chi.Router) { r.Use(s.ShelfCtx) r.Get("/", makeHandler(s.getShelf)) r.Delete("/", makeHandler(s.deleteShelf)) r.Put("/", makeHandler(s.updateShelf)) r.Get("/count", makeHandler(s.getShelfAssetCount)) }) } } func (s *APIServer) ShelfCtx(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { shelfIdStr := chi.URLParam(r, "shelfId") shelfId, err := strconv.ParseUint(shelfIdStr, 10, 64) if err != nil { render.Render(w, r, errNotFound) return } shelf, err := s.db.GetShelfByID(shelfId) if err != nil { render.Render(w, r, errNotFound) return } ctx := context.WithValue(r.Context(), "shelf", shelf) next.ServeHTTP(w, r.WithContext(ctx)) }) } func (s *APIServer) getShelves(w http.ResponseWriter, r *http.Request) error { shelves, err := s.db.GetShelves(0, 10) if err != nil { return err } total, err := s.db.TotalShelves() if err != nil { return err } return render.Render(w, r, &types.MultipleShelfResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, ShelfLocations: shelves, Total: total, }) } func (s *APIServer) getShelf(w http.ResponseWriter, r *http.Request) error { ctx := r.Context() shelf, ok := ctx.Value("shelf").(*types.ShelfLocation) if !ok { return render.Render(w, r, errUnprocessable) } return render.Render(w, r, &types.ShelfResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, ShelfLocation: shelf, }) } func (s *APIServer) deleteShelf(w http.ResponseWriter, r *http.Request) error { ctx := r.Context() shelf, ok := ctx.Value("shelf").(*types.ShelfLocation) if !ok { return render.Render(w, r, errUnprocessable) } if ok, _ := s.db.DeleteShelfByID(shelf.ID); !ok { return render.Render(w, r, errUnprocessable) } return render.Render(w, r, &types.ShelfResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, ShelfLocation: shelf, }) } func (s *APIServer) createShelf(w http.ResponseWriter, r *http.Request) error { data := &types.CreateShelfRequest{} if err := render.Bind(r, data); err != nil { return render.Render(w, r, errBadRequest(err)) } shelf := &types.ShelfLocation{ Name: data.Name, RoomNumber: data.RoomNumber, Description: data.Description, BuildingID: *data.BuildingID, } err := s.db.CreateShelfLocation(shelf) if err != nil { return err } return render.Render(w, r, &types.ShelfResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, ShelfLocation: shelf, }) } func (s *APIServer) getShelfAssetCount(w http.ResponseWriter, r *http.Request) error { ctx := r.Context() shelf, ok := ctx.Value("shelf").(*types.ShelfLocation) if !ok { return render.Render(w, r, errUnprocessable) } count, err := s.db.AssetCountInLocation(shelf.ID) if err != nil { return err } return render.Render(w, r, &types.CountResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, Count: count, }) } func (s *APIServer) updateShelf(w http.ResponseWriter, r *http.Request) error { ctx := r.Context() eShelf, ok := ctx.Value("shelf").(*types.ShelfLocation) if !ok { return render.Render(w, r, errUnprocessable) } data := &types.CreateShelfRequest{} if err := render.Bind(r, data); err != nil { return render.Render(w, r, errBadRequest(err)) } shelf := &types.ShelfLocation{ ID: eShelf.ID, Name: data.Name, BuildingID: *data.BuildingID, RoomNumber: data.RoomNumber, } err := s.db.UpdateShelfLocation(eShelf.ID, shelf) if err != nil { return err } return render.Render(w, r, &types.ShelfResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, ShelfLocation: shelf, }) }