diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-07 19:10:30 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-07 19:10:30 +0200 |
| commit | 7aa64b0917130fcc1dc9f3da30d8f825136fe541 (patch) | |
| tree | 361fb90e0b68a6356c7c7b9667b3f09400680287 /web/server.go | |
| parent | 5b74dc4321e63f251190a975b151875b64656c56 (diff) | |
feat: Add ride table sorting
Diffstat (limited to 'web/server.go')
| -rw-r--r-- | web/server.go | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/web/server.go b/web/server.go index 10cf30e..c7b585e 100644 --- a/web/server.go +++ b/web/server.go @@ -11,6 +11,7 @@ import ( "net/url" "os" "path/filepath" + "sort" "strconv" "strings" "sync" @@ -53,12 +54,25 @@ func (s *Server) ListenAndServe(addr string) error { } func (s *Server) handleRides(w http.ResponseWriter, r *http.Request) { - items, err := rides.List(s.db) + rideSort := parseRideSort(r.URL.Query()) + items, err := s.listRides(rideSort) if err != nil { http.Error(w, "failed to load rides", http.StatusInternalServerError) return } - kcore.RenderPage(r.Context(), RidesPage(buildRideViews(items)), w) + views := buildRideViews(items) + if _, databaseColumn := rideSort.databaseColumn(); !databaseColumn { + sortRideViews(views, rideSort) + } + kcore.RenderPage(r.Context(), RidesPage(views, rideSortHeaders(rideSort)), w) +} + +func (s *Server) listRides(rideSort RideSort) ([]rides.Ride, error) { + column, found := rideSort.databaseColumn() + if !found { + return rides.List(s.db) + } + return rides.ListSorted(s.db, column, rideSort.Descending) } const minimumDisplayedDistanceM = 10_000 @@ -78,12 +92,40 @@ func buildRideViews(items []rides.Ride) []RideView { score := parsed.DifficultyScore() view.Cotacol = formatCotacol(score) view.CotacolPer100Km = formatCotacolPer100Km(score, item.DistanceM) + view.cotacolScore = score + view.cotacolPer100Km = score * 100 / (item.DistanceM / 1000) + view.cotacolReady = true } views = append(views, view) } return views } +func sortRideViews(items []RideView, rideSort RideSort) { + sort.SliceStable(items, func(i, j int) bool { + left, right := items[i], items[j] + if !left.cotacolReady || !right.cotacolReady { + if left.cotacolReady != right.cotacolReady { + return left.cotacolReady + } + return false + } + var leftValue, rightValue float64 + switch rideSort.Column { + case rideSortCotacol: + leftValue, rightValue = left.cotacolScore, right.cotacolScore + case rideSortCotacolKm: + leftValue, rightValue = left.cotacolPer100Km, right.cotacolPer100Km + default: + return false + } + if rideSort.Descending { + return leftValue > rightValue + } + return leftValue < rightValue + }) +} + func (s *Server) handleSyncForm(w http.ResponseWriter, r *http.Request) { data := SyncPageData{ From: queryOrDefault(r, "from", time.Now().AddDate(0, 0, -30).Format(dateFormat)), |