diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-23 21:35:59 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-23 21:35:59 +0200 |
| commit | 08fdd6964fd9ef29356420b035e2d186546f674a (patch) | |
| tree | 812565b5ca57405a5b36b2d7edfab983f6f079d4 /web/categories.go | |
| parent | 2d8503cafb9f63ca4cb63f041281987f9a63f16a (diff) | |
Add hardcore ride categorisation with bike and ride types
Diffstat (limited to 'web/categories.go')
| -rw-r--r-- | web/categories.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/web/categories.go b/web/categories.go new file mode 100644 index 0000000..4077092 --- /dev/null +++ b/web/categories.go @@ -0,0 +1,89 @@ +package web + +import ( + "log/slog" + "net/http" + "strconv" + + "github.com/martinlehoux/biking_home/ride" +) + +func (s *Server) handleUpdateRideCategories(w http.ResponseWriter, r *http.Request) { + id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) + if err != nil || id <= 0 { + http.NotFound(w, r) + return + } + item, found, err := ride.GetByID(s.db, id) + if err != nil { + slog.Error("Failed to load ride for category update", "ride_id", id, "error", err) + http.Error(w, "failed to load ride", http.StatusInternalServerError) + return + } + if !found { + http.NotFound(w, r) + return + } + _ = item + if err := r.ParseForm(); err != nil { + http.Error(w, "invalid form", http.StatusBadRequest) + return + } + bikeType := ride.BikeType(r.FormValue("bike_type")) + rideType := ride.RideType(r.FormValue("ride_type")) + if !ride.IsValidBikeType(string(bikeType)) { + http.Error(w, "invalid bike_type", http.StatusBadRequest) + return + } + if !ride.IsValidRideType(string(rideType)) { + http.Error(w, "invalid ride_type", http.StatusBadRequest) + return + } + if err := ride.UpdateCategories(s.db, id, bikeType, rideType); err != nil { + slog.Error("Failed to update ride categories", "ride_id", id, "error", err) + http.Error(w, "failed to update categories", http.StatusInternalServerError) + return + } + slog.Info("Updated ride categories", "ride_id", id, "bike_type", bikeType, "ride_type", rideType) + http.Redirect(w, r, rideDetailURL(id)+"?categories=updated", http.StatusSeeOther) +} + +func rideCategoriesUpdateURL(id int64) string { + return rideDetailURL(id) + "/categories" +} + +var bikeTypeOptions = []ride.BikeType{ride.BikeTypeRoad, ride.BikeTypeMTB} +var rideTypeOptions = []ride.RideType{ride.RideTypeTraining, ride.RideTypeIndoor, ride.RideTypeRace, ride.RideTypeTransport} + +var bikeTypeLabels = map[ride.BikeType]string{ + ride.BikeTypeRoad: "Road", + ride.BikeTypeMTB: "MTB", +} + +var rideTypeLabels = map[ride.RideType]string{ + ride.RideTypeTraining: "Training", + ride.RideTypeIndoor: "Indoor", + ride.RideTypeRace: "Race", + ride.RideTypeTransport: "Transport", +} + +func formatBikeType(value ride.BikeType) string { + if label, ok := bikeTypeLabels[value]; ok { + return label + } + return string(value) +} + +func formatRideType(value ride.RideType) string { + if label, ok := rideTypeLabels[value]; ok { + return label + } + return string(value) +} + +func formatCategoryOrEmpty(value string) string { + if value == "" { + return "—" + } + return value +} |
