summaryrefslogtreecommitdiff
path: root/web/server.go
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2026-08-07 19:10:30 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2026-08-07 19:10:30 +0200
commit7aa64b0917130fcc1dc9f3da30d8f825136fe541 (patch)
tree361fb90e0b68a6356c7c7b9667b3f09400680287 /web/server.go
parent5b74dc4321e63f251190a975b151875b64656c56 (diff)
feat: Add ride table sorting
Diffstat (limited to 'web/server.go')
-rw-r--r--web/server.go46
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)),