Segments Phase 4: detail page, activity efforts, athlete tab, new APIs
New API endpoints:
- GET /api/segments/{id} — single segment metadata
- GET /api/activities/{id}/segment_efforts — efforts for an activity (auth)
- GET /api/users/{handle}/segment_summary — public best time + count per segment
New components:
- SegmentDetail.svelte — map + metadata + effort table (with PR/Δ) + rescan button
- SegmentsPage.svelte — URL router: shows detail when /segments/{id}/, list otherwise
Updated:
- segments/index.astro — now uses SegmentsPage router
- nginx-activity.conf — add /segments/ try_files rule for client-side routing
- ActivityDetail.svelte — segment efforts block below laps
- AthleteView.svelte — Segments tab with best time + effort count per segment
- format.ts — add formatElapsed() for compact m:ss display
This commit is contained in:
@@ -26,6 +26,16 @@ export function formatDuration(s: number | null): string {
|
||||
return `${m}m ${sec.toString().padStart(2, '0')}s`;
|
||||
}
|
||||
|
||||
/** Compact m:ss or h:mm:ss for segment effort tables. */
|
||||
export function formatElapsed(s: number): string {
|
||||
s = Math.floor(s);
|
||||
const h = Math.floor(s / 3600);
|
||||
const m = Math.floor((s % 3600) / 60);
|
||||
const sec = s % 60;
|
||||
if (h > 0) return `${h}:${m.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`;
|
||||
return `${m}:${sec.toString().padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
export function formatSpeed(kmh: number | null): string {
|
||||
if (kmh == null) return '—';
|
||||
return `${kmh.toFixed(1)} km/h`;
|
||||
|
||||
Reference in New Issue
Block a user