diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-11 12:38:45 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-11 12:38:45 +0200 |
| commit | d4e4616ba49f3a18a52e3197e1c77639a93b0330 (patch) | |
| tree | 50e9cc2b39f72ef8a2e61bff57fbc1239d55d4f0 /web/server.go | |
| parent | 31ce2a1d5ff5746249cd4de96762f5740aff907a (diff) | |
feat: Add ride detail map
Diffstat (limited to 'web/server.go')
| -rw-r--r-- | web/server.go | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/web/server.go b/web/server.go index 845c31c..cc3ad2e 100644 --- a/web/server.go +++ b/web/server.go @@ -41,6 +41,7 @@ func NewServer(db *sql.DB, configPath string) *Server { func (s *Server) Handler() http.Handler { mux := http.NewServeMux() mux.HandleFunc("GET /", s.handleRides) + mux.HandleFunc("GET /rides/{id}", s.handleRide) mux.HandleFunc("GET /sync", s.handleSyncForm) mux.HandleFunc("POST /sync", s.handleSync) mux.HandleFunc("GET /strava/login", s.handleStravaLogin) @@ -64,6 +65,35 @@ func (s *Server) handleRides(w http.ResponseWriter, r *http.Request) { kcore.RenderPage(r.Context(), RidesPage(views, rideSortHeaders(rideSort)), w) } +func (s *Server) handleRide(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 := rides.GetByID(s.db, id) + if err != nil { + slog.Error("Failed to load ride", "ride_id", id, "error", err) + http.Error(w, "failed to load ride", http.StatusInternalServerError) + return + } + if !found { + http.NotFound(w, r) + return + } + parsed, err := ride.ParseFile(ride.GPXRideParser{}, item.GPXPath) + if err != nil { + slog.Error("Failed to load ride route", "ride_id", id, "file", item.GPXPath, "error", err) + kcore.RenderPage(r.Context(), RideDetailPage(RideDetailView{ + RideView: buildRideView(item), + RouteError: "The recorded route is unavailable.", + }), w) + return + } + slog.Info("Loaded ride detail", "ride_id", id) + kcore.RenderPage(r.Context(), RideDetailPage(buildRideDetailView(item, parsed)), w) +} + func (s *Server) listRides(rideSort RideSort) ([]rides.Ride, error) { column, found := rideSort.databaseColumn() if !found { @@ -80,17 +110,21 @@ func buildRideViews(items []rides.Ride) []RideView { if item.DistanceM < minimumDisplayedDistanceM { continue } - view := RideView{Ride: item, Cotacol: "-", CotacolPer100Km: "-"} - score, ready := item.CotacolScore() - if ready && item.CotacolAlgorithmVersion() == ride.CotacolAlgorithmVersion && item.DistanceM > 0 { - view.Cotacol = formatCotacol(score) - view.CotacolPer100Km = formatCotacolPer100Km(score, item.DistanceM) - } - views = append(views, view) + views = append(views, buildRideView(item)) } return views } +func buildRideView(item rides.Ride) RideView { + view := RideView{Ride: item, Cotacol: "-", CotacolPer100Km: "-"} + score, ready := item.CotacolScore() + if ready && item.CotacolAlgorithmVersion() == ride.CotacolAlgorithmVersion && item.DistanceM > 0 { + view.Cotacol = formatCotacol(score) + view.CotacolPer100Km = formatCotacolPer100Km(score, item.DistanceM) + } + return view +} + func (s *Server) handleSyncForm(w http.ResponseWriter, r *http.Request) { data := SyncPageData{ From: queryOrDefault(r, "from", time.Now().AddDate(0, 0, -30).Format(dateFormat)), |