diff options
Diffstat (limited to 'web')
| -rw-r--r-- | web/categories.go | 21 | ||||
| -rw-r--r-- | web/ride-filters_test.go | 94 | ||||
| -rw-r--r-- | web/server_test.go | 242 | ||||
| -rw-r--r-- | web/sync.go | 8 | ||||
| -rw-r--r-- | web/templates.templ | 6 |
5 files changed, 198 insertions, 173 deletions
diff --git a/web/categories.go b/web/categories.go index 74d871c..6ef8c10 100644 --- a/web/categories.go +++ b/web/categories.go @@ -74,3 +74,24 @@ func formatCategoryOrEmpty(value string) string { } return value } + +func formatRideCategories(r ride.StoredRide) string { + bikeLabel, hasBike := bikeTypeLabels[r.BikeType] + rideLabel, hasRide := rideTypeLabels[r.RideType] + switch { + case hasBike && hasRide: + return bikeLabel + " · " + rideLabel + case hasBike: + return bikeLabel + case hasRide: + return rideLabel + default: + if r.BikeType != "" { + return string(r.BikeType) + } + if r.RideType != "" { + return string(r.RideType) + } + return "—" + } +} diff --git a/web/ride-filters_test.go b/web/ride-filters_test.go index b7abcf4..5075925 100644 --- a/web/ride-filters_test.go +++ b/web/ride-filters_test.go @@ -169,33 +169,33 @@ func TestFilterRidesByRideType(t *testing.T) { func TestFilterRidesByCotacolExcludesUnavailableScores(t *testing.T) { _, db := newWebTestServer(t) current := ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", - GPXPath: testGPXPath(t, "current-cotacol.gpx"), - Name: "Current score", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", + GPXPath: testGPXPath(t, "current-cotacol.gpx"), + Name: "Current score", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, } stale := ride.StoredRide{ - ExternalID: "strava:6ba7b810-9dad-41d1-80b4-00c04fd430c8", - GPXPath: testGPXPath(t, "stale-cotacol.gpx"), - Name: "Stale score", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:6ba7b810-9dad-41d1-80b4-00c04fd430c8", + GPXPath: testGPXPath(t, "stale-cotacol.gpx"), + Name: "Stale score", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, } unavailable := ride.StoredRide{ - ExternalID: "strava:7ba7b810-9dad-41d1-80b4-00c04fd430c8", - Name: "No score", - Type: "VirtualRide", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 3, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:7ba7b810-9dad-41d1-80b4-00c04fd430c8", + Name: "No score", + ExternalSportType: "VirtualRide", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 3, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, } require.NoError(t, ride.Save(db, current)) require.NoError(t, ride.Save(db, stale)) @@ -248,14 +248,14 @@ func TestHandlerHidesTransportRidesByDefault(t *testing.T) { server, db := newWebTestServer(t) save := func(externalID, name string, rideType ride.RideType) { require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: externalID, - GPXPath: testGPXPath(t, externalID+".gpx"), - Name: name, - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: rideType, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: externalID, + GPXPath: testGPXPath(t, externalID+".gpx"), + Name: name, + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: rideType, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, })) } save("strava:550e8400-e29b-41d4-a716-446655440000", "Training Ride", ride.RideTypeTraining) @@ -297,14 +297,14 @@ func TestHandlerFiltersRidesBeforeRenderingSortedResults(t *testing.T) { server, db := newWebTestServer(t) save := func(externalID, name, path string, distance float64) { require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: externalID, - GPXPath: testGPXPath(t, path), - Name: name, - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: distance, + ExternalID: externalID, + GPXPath: testGPXPath(t, path), + Name: name, + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: distance, })) } save("strava:550e8400-e29b-41d4-a716-446655440000", "Long Ride", "long-filtered.gpx", 40_000) @@ -324,14 +324,14 @@ func TestHandlerFiltersRidesBeforeRenderingSortedResults(t *testing.T) { func TestHandlerRendersFilteredEmptyState(t *testing.T) { server, db := newWebTestServer(t) require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:8ba7b810-9dad-41d1-80b4-00c04fd430c8", - GPXPath: testGPXPath(t, "empty-filter.gpx"), - Name: "Short Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:8ba7b810-9dad-41d1-80b4-00c04fd430c8", + GPXPath: testGPXPath(t, "empty-filter.gpx"), + Name: "Short Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, })) request := httptest.NewRequest(http.MethodGet, "/?distance_min=300&distance_max=300", nil) diff --git a/web/server_test.go b/web/server_test.go index d75628d..2e9a332 100644 --- a/web/server_test.go +++ b/web/server_test.go @@ -89,24 +89,24 @@ const officialClimbTrackGPX = `<?xml version="1.0"?><gpx xmlns="http://www.topog func TestHandlerRendersRidesPage(t *testing.T) { server, db := newWebTestServer(t) require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:1234", - GPXPath: testGPXPath(t, "long.gpx"), - Name: "Long Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:1234", + GPXPath: testGPXPath(t, "long.gpx"), + Name: "Long Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, })) require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:5678", - GPXPath: testGPXPath(t, "short.gpx"), - Name: "Short Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), - DistanceM: 9_999, + ExternalID: "strava:5678", + GPXPath: testGPXPath(t, "short.gpx"), + Name: "Short Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), + DistanceM: 9_999, })) req := httptest.NewRequest(http.MethodGet, "/", nil) response := httptest.NewRecorder() @@ -126,14 +126,14 @@ func TestHandlerRendersRidesPage(t *testing.T) { func TestHandlerRendersRideDetailWithEmbeddedRoute(t *testing.T) { server, db := newWebTestServer(t) require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", - GPXPath: testGPXPath(t, "detail.gpx"), - Name: "Detailed Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", + GPXPath: testGPXPath(t, "detail.gpx"), + Name: "Detailed Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, })) _, err := db.Exec(` INSERT INTO mountain_passes (osm_id, name, elevation, latitude, longitude) @@ -275,14 +275,14 @@ func TestHandlerCreatesOfficialClimbFromRoutePoints(t *testing.T) { routePath := filepath.Join(t.TempDir(), "official-climb.gpx") require.NoError(t, os.WriteFile(routePath, []byte(officialClimbTrackGPX), 0o600)) require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", - GPXPath: routePath, - Name: "Climb Candidate", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 2_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", + GPXPath: routePath, + Name: "Climb Candidate", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 2_000, })) item, found, err := ride.GetByExternalID(db, "strava:550e8400-e29b-41d4-a716-446655440000") require.NoError(t, err) @@ -334,13 +334,13 @@ func TestHandlerCreatesOfficialClimbFromRoutePoints(t *testing.T) { func TestHandlerRendersRideDetailWithoutRoute(t *testing.T) { server, db := newWebTestServer(t) item := ride.StoredRide{ - ExternalID: "strava:14701658670", - Name: "Indoor Ride", - Type: "VirtualRide", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:14701658670", + Name: "Indoor Ride", + ExternalSportType: "VirtualRide", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, } require.NoError(t, ride.Save(db, item)) stored, found, err := ride.GetByExternalID(db, item.ExternalID) @@ -361,22 +361,22 @@ func TestHandlerRendersRideDetailWithoutRoute(t *testing.T) { func TestHandlerRendersAnalyticsChart(t *testing.T) { server, db := newWebTestServer(t) first := ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440001", - Name: "Fastish Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 40_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440001", + Name: "Fastish Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 40_000, } second := ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440002", - Name: "Climbing Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), - DistanceM: 40_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440002", + Name: "Climbing Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), + DistanceM: 40_000, } require.NoError(t, ride.Save(db, first)) require.NoError(t, ride.Save(db, second)) @@ -407,22 +407,22 @@ func TestHandlerRendersAnalyticsChart(t *testing.T) { func TestHandlerFiltersAnalyticsByDistance(t *testing.T) { server, db := newWebTestServer(t) short := ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440003", - Name: "Short Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 40_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440003", + Name: "Short Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 40_000, } long := ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440004", - Name: "Long Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), - DistanceM: 100_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440004", + Name: "Long Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), + DistanceM: 100_000, } require.NoError(t, ride.Save(db, short)) require.NoError(t, ride.Save(db, long)) @@ -462,7 +462,7 @@ func TestHandlerReturnsNotFoundForUnknownRide(t *testing.T) { func TestHandlerShowsErrorForUnavailableRideRoute(t *testing.T) { server, db := newWebTestServer(t) _, err := db.Exec(` - INSERT INTO rides (external_id, gpx_path, name, type, start_date, distance_m, external_moving_time_s, elapsed_time_s, total_elevation_gain_m, average_speed_mps) + INSERT INTO rides (external_id, gpx_path, name, external_sport_type, start_date, distance_m, external_moving_time_s, elapsed_time_s, total_elevation_gain_m, average_speed_mps) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `, "strava:6ba7b810-9dad-41d1-80b4-00c04fd430c8", "missing.gpx", "Unavailable Route", "Ride", "2026-08-01T07:00:00Z", 20_000, 0, 0, 0, 0) require.NoError(t, err) @@ -634,12 +634,12 @@ func TestSyncRidesResyncsTitleFromList(t *testing.T) { startDate := time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC) gpxPath := testGPXPath(t, "existing.gpx") require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:789", - GPXPath: gpxPath, - Name: "Old Title", - Type: "Ride", - StartDate: startDate, - DistanceM: 20_000, + ExternalID: "strava:789", + GPXPath: gpxPath, + Name: "Old Title", + ExternalSportType: "Ride", + StartDate: startDate, + DistanceM: 20_000, })) // Verify the title was corrected on Strava (ride #789). client := fakeSyncClient{ @@ -666,12 +666,12 @@ func TestSyncRidesSkipsWhenTitleUnchanged(t *testing.T) { server, db := newWebTestServer(t) startDate := time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC) require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:789", - GPXPath: testGPXPath(t, "existing2.gpx"), - Name: "Same Title", - Type: "Ride", - StartDate: startDate, - DistanceM: 20_000, + ExternalID: "strava:789", + GPXPath: testGPXPath(t, "existing2.gpx"), + Name: "Same Title", + ExternalSportType: "Ride", + StartDate: startDate, + DistanceM: 20_000, })) client := fakeSyncClient{ activities: []strava.Activity{ @@ -805,14 +805,14 @@ func TestRideSortHeadersToggleDirection(t *testing.T) { func TestBuildRideViewsUsesStoredCotacol(t *testing.T) { _, db := newWebTestServer(t) stored := ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", - GPXPath: testGPXPath(t, "stored.gpx"), - Name: "Stored Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", + GPXPath: testGPXPath(t, "stored.gpx"), + Name: "Stored Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, } require.NoError(t, ride.Save(db, stored)) _, err := db.Exec("UPDATE rides SET gpx_path = ? WHERE external_id = ?", "missing.gpx", stored.ExternalID) @@ -831,7 +831,7 @@ func TestBuildRideViewMovingTimePrefersCanonical(t *testing.T) { ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", GPXPath: testGPXPath(t, "moving.gpx"), Name: "Moving Ride", - Type: "Ride", + ExternalSportType: "Ride", StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), DistanceM: 20_000, ExternalMovingTimeS: 7_200, @@ -847,24 +847,24 @@ func TestBuildRideViewMovingTimePrefersCanonical(t *testing.T) { func TestHandlerSortsRidesByDistance(t *testing.T) { server, db := newWebTestServer(t) require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", - GPXPath: testGPXPath(t, "near.gpx"), - Name: "Near Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", + GPXPath: testGPXPath(t, "near.gpx"), + Name: "Near Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, })) require.NoError(t, ride.Save(db, ride.StoredRide{ - ExternalID: "strava:6ba7b810-9dad-41d1-80b4-00c04fd430c8", - GPXPath: testGPXPath(t, "far.gpx"), - Name: "Far Ride", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), - DistanceM: 40_000, + ExternalID: "strava:6ba7b810-9dad-41d1-80b4-00c04fd430c8", + GPXPath: testGPXPath(t, "far.gpx"), + Name: "Far Ride", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), + DistanceM: 40_000, })) req := httptest.NewRequest(http.MethodGet, "/?sort=distance&dir=asc", nil) @@ -880,24 +880,24 @@ func TestHandlerSortsRidesByDistance(t *testing.T) { func TestHandlerSortsRidesByCotacol(t *testing.T) { server, db := newWebTestServer(t) first := ride.StoredRide{ - ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", - GPXPath: testGPXPath(t, "first.gpx"), - Name: "Low Cotacol", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), - DistanceM: 20_000, + ExternalID: "strava:550e8400-e29b-41d4-a716-446655440000", + GPXPath: testGPXPath(t, "first.gpx"), + Name: "Low Cotacol", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 1, 7, 0, 0, 0, time.UTC), + DistanceM: 20_000, } second := ride.StoredRide{ - ExternalID: "strava:6ba7b810-9dad-41d1-80b4-00c04fd430c8", - GPXPath: testGPXPath(t, "second.gpx"), - Name: "High Cotacol", - Type: "Ride", - BikeType: ride.BikeTypeRoad, - RideType: ride.RideTypeTraining, - StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), - DistanceM: 40_000, + ExternalID: "strava:6ba7b810-9dad-41d1-80b4-00c04fd430c8", + GPXPath: testGPXPath(t, "second.gpx"), + Name: "High Cotacol", + ExternalSportType: "Ride", + BikeType: ride.BikeTypeRoad, + RideType: ride.RideTypeTraining, + StartDate: time.Date(2026, 8, 2, 7, 0, 0, 0, time.UTC), + DistanceM: 40_000, } require.NoError(t, ride.Save(db, first)) require.NoError(t, ride.Save(db, second)) diff --git a/web/sync.go b/web/sync.go index 8ed306f..73e8146 100644 --- a/web/sync.go +++ b/web/sync.go @@ -215,12 +215,12 @@ func rideFromActivity(externalID, gpxPath, fitPath string, activity strava.Activ if activityType == "" { activityType = activity.Type } - return ride.StoredRide{ + stored := ride.StoredRide{ ExternalID: externalID, GPXPath: gpxPath, FitPath: fitPath, Name: activity.Name, - Type: activityType, + ExternalSportType: activityType, StartDate: activity.StartDate, DistanceM: activity.DistanceM, ExternalMovingTimeS: activity.MovingTimeS, @@ -228,6 +228,10 @@ func rideFromActivity(externalID, gpxPath, fitPath string, activity strava.Activ TotalElevationGainM: activity.TotalElevationGainM, AverageSpeedMps: activity.AverageSpeedMps, } + if bikeType, ok := ride.BikeTypeForExternalSportType(activityType); ok { + stored.BikeType = bikeType + } + return stored } func skipSyncActivity(progress *SyncProgress, report func(SyncProgress) error, activity strava.Activity, err error) error { diff --git a/web/templates.templ b/web/templates.templ index db60ca9..5bf6b15 100644 --- a/web/templates.templ +++ b/web/templates.templ @@ -91,7 +91,7 @@ templ RidesContent(data RidesPageData) { </tr></thead> <tbody> for _, item := range data.Items { - <tr><td><strong><a href={ templ.URL(rideDetailURL(item.Ride.ID)) }>{ item.Ride.Name }</a></strong><br/><small>{ item.Ride.Type }</small></td><td>{ formatRideDate(item.Ride.StartDate) }</td><td class="numeric">{ formatDistance(item.Ride.DistanceM) }</td><td class="numeric">{ item.MovingTime }</td><td class="numeric">{ formatSpeed(item.Ride.AverageSpeedMps) }</td><td class="numeric">{ formatElevation(item.Ride.TotalElevationGainM) }</td><td class="numeric">{ item.Cotacol }</td><td class="numeric">{ item.CotacolPer100Km }</td></tr> + <tr><td><strong><a href={ templ.URL(rideDetailURL(item.Ride.ID)) }>{ item.Ride.Name }</a></strong><br/><small>{ formatRideCategories(item.Ride) }</small></td><td>{ formatRideDate(item.Ride.StartDate) }</td><td class="numeric">{ formatDistance(item.Ride.DistanceM) }</td><td class="numeric">{ item.MovingTime }</td><td class="numeric">{ formatSpeed(item.Ride.AverageSpeedMps) }</td><td class="numeric">{ formatElevation(item.Ride.TotalElevationGainM) }</td><td class="numeric">{ item.Cotacol }</td><td class="numeric">{ item.CotacolPer100Km }</td></tr> } </tbody> </table> @@ -206,7 +206,7 @@ templ RideDetailPage(data RideDetailView) { templ RideDetailContent(data RideDetailView) { <div class="toolbar"> - <div><h1 class="ride-detail-title">{ data.Ride.Name }</h1><p class="lead">{ data.Ride.Type } · { formatRideDate(data.Ride.StartDate) }</p></div> + <div><h1 class="ride-detail-title">{ data.Ride.Name }</h1><p class="lead">{ formatRideCategories(data.Ride) } · { formatRideDate(data.Ride.StartDate) }</p></div> <div class="toolbar-actions"> if data.ExternalURL != "" { <a class="button secondary" href={ templ.URL(data.ExternalURL) } target="_blank" rel="noopener">View on Strava</a> @@ -448,7 +448,7 @@ templ DataQualityContent(data DataQualityPageData) { for _, item := range data.Items { <tr> <td><input type="checkbox" name="ride_ids" value={ formatRideID(item.Ride.ID) } class="data-quality-checkbox"/></td> - <td><strong><a href={ templ.URL(rideDetailURL(item.Ride.ID)) }>{ item.Ride.Name }</a></strong><br/><small>{ item.Ride.Type }</small></td> + <td><strong><a href={ templ.URL(rideDetailURL(item.Ride.ID)) }>{ item.Ride.Name }</a></strong><br/><small>{ formatRideCategories(item.Ride) }</small></td> <td>{ formatRideDate(item.Ride.StartDate) }</td> <td class="numeric">{ formatDistance(item.Ride.DistanceM) }</td> <td>{ formatCategoryOrEmpty(string(item.Ride.BikeType)) }</td> |
