map now working
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import type { Sport } from './types';
|
||||
|
||||
export function formatDistance(m: number | null, unit: 'metric' | 'imperial' = 'metric'): string {
|
||||
if (m == null) return '—';
|
||||
if (unit === 'imperial') {
|
||||
const miles = m / 1609.344;
|
||||
return miles >= 10 ? `${miles.toFixed(1)} mi` : `${miles.toFixed(2)} mi`;
|
||||
}
|
||||
const km = m / 1000;
|
||||
return km >= 10 ? `${km.toFixed(1)} km` : `${km.toFixed(2)} km`;
|
||||
}
|
||||
|
||||
export function formatDuration(s: number | null): string {
|
||||
if (s == null) return '—';
|
||||
const h = Math.floor(s / 3600);
|
||||
const m = Math.floor((s % 3600) / 60);
|
||||
const sec = s % 60;
|
||||
if (h > 0) return `${h}h ${m.toString().padStart(2, '0')}m`;
|
||||
return `${m}m ${sec.toString().padStart(2, '0')}s`;
|
||||
}
|
||||
|
||||
export function formatSpeed(kmh: number | null): string {
|
||||
if (kmh == null) return '—';
|
||||
return `${kmh.toFixed(1)} km/h`;
|
||||
}
|
||||
|
||||
export function formatElevation(m: number | null): string {
|
||||
if (m == null) return '—';
|
||||
return `${Math.round(m)} m`;
|
||||
}
|
||||
|
||||
export function formatDate(iso: string): string {
|
||||
return new Date(iso).toLocaleDateString('en-GB', {
|
||||
day: 'numeric', month: 'short', year: 'numeric',
|
||||
});
|
||||
}
|
||||
|
||||
export function formatTime(iso: string): string {
|
||||
return new Date(iso).toLocaleTimeString('en-GB', {
|
||||
hour: '2-digit', minute: '2-digit',
|
||||
});
|
||||
}
|
||||
|
||||
export function formatDateShort(iso: string): string {
|
||||
return new Date(iso).toLocaleDateString('en-GB', {
|
||||
day: 'numeric', month: 'short',
|
||||
});
|
||||
}
|
||||
|
||||
const SPORT_ICONS: Record<Sport, string> = {
|
||||
cycling: '🚴',
|
||||
running: '🏃',
|
||||
hiking: '🥾',
|
||||
walking: '🚶',
|
||||
swimming: '🏊',
|
||||
other: '⚡',
|
||||
};
|
||||
|
||||
const SPORT_COLORS: Record<Sport, string> = {
|
||||
cycling: '#00c8ff',
|
||||
running: '#ff6b35',
|
||||
hiking: '#4ade80',
|
||||
walking: '#a3e635',
|
||||
swimming: '#38bdf8',
|
||||
other: '#a78bfa',
|
||||
};
|
||||
|
||||
export function sportIcon(sport: Sport): string {
|
||||
return SPORT_ICONS[sport] ?? '⚡';
|
||||
}
|
||||
|
||||
export function sportColor(sport: Sport): string {
|
||||
return SPORT_COLORS[sport] ?? '#a78bfa';
|
||||
}
|
||||
|
||||
export function sportLabel(sport: Sport, subSport?: string | null): string {
|
||||
const base = sport.charAt(0).toUpperCase() + sport.slice(1);
|
||||
if (subSport && subSport !== 'generic') {
|
||||
return `${subSport.charAt(0).toUpperCase() + subSport.slice(1)} ${base}`;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
@@ -24,6 +24,8 @@ export interface ActivitySummary {
|
||||
privacy: Privacy;
|
||||
detail_url: string | null;
|
||||
track_url: string | null;
|
||||
/** ~20 [lat, lon] pairs for card thumbnail — no separate fetch needed. */
|
||||
preview_coords: [number, number][] | null;
|
||||
}
|
||||
|
||||
export interface BASIndex {
|
||||
|
||||
Reference in New Issue
Block a user