frontend: week-filter totals (distance/time/count) on Activities; colour HIIT & gym/no-GPS workouts red
Build and push images / validate (push) Successful in 3s
Build and push images / build-backend (push) Successful in 5s
Build and push images / build-worker (push) Successful in 5s
Build and push images / build-frontend (push) Successful in 9s

This commit is contained in:
2026-06-21 09:40:50 +01:00
parent 7d52b28f9d
commit e8615dd12d
2 changed files with 23 additions and 3 deletions
+13 -2
View File
@@ -44,6 +44,10 @@ export default function ActivitiesPage() {
const clearDateFilter = () => navigate('/activities') const clearDateFilter = () => navigate('/activities')
// Totals for the currently shown (date-filtered) list
const totalDistanceM = activities?.reduce((sum, a) => sum + (a.distance_m || 0), 0) || 0
const totalDurationS = activities?.reduce((sum, a) => sum + (a.duration_s || 0), 0) || 0
return ( return (
<div className="p-4 md:p-6"> <div className="p-4 md:p-6">
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4">
@@ -74,13 +78,20 @@ export default function ActivitiesPage() {
</div> </div>
)} )}
{/* Date filter chip */} {/* Date filter chip + week totals */}
{fromParam && ( {fromParam && (
<div className="flex items-center gap-2 mb-4"> <div className="flex flex-wrap items-center gap-2 mb-4">
<span className="text-xs bg-blue-600/20 text-blue-300 border border-blue-500/30 px-3 py-1 rounded-full"> <span className="text-xs bg-blue-600/20 text-blue-300 border border-blue-500/30 px-3 py-1 rounded-full">
Week of {format(new Date(fromParam), 'MMM d, yyyy')} Week of {format(new Date(fromParam), 'MMM d, yyyy')}
</span> </span>
<button onClick={clearDateFilter} className="text-xs text-gray-500 hover:text-gray-300 transition-colors"> Clear</button> <button onClick={clearDateFilter} className="text-xs text-gray-500 hover:text-gray-300 transition-colors"> Clear</button>
{activities?.length > 0 && (
<span className="text-xs text-gray-400 ml-1">
<span className="text-gray-200 font-medium">{formatDistance(totalDistanceM, unit)}</span> ·{' '}
<span className="text-gray-200 font-medium">{formatDuration(totalDurationS)}</span> ·{' '}
{activities.length} {activities.length === 1 ? 'activity' : 'activities'}
</span>
)}
</div> </div>
)} )}
+10 -1
View File
@@ -117,7 +117,15 @@ export const METRIC_COLOR = {
WEIGHT: '#3b82f6', // blue WEIGHT: '#3b82f6', // blue
} }
// Gym / no-GPS workout types (HIIT, strength, cardio machines etc.) — coloured
// red so they stand out from the GPS-based outdoor activities.
const GYM_SPORTS = new Set([
'hiit', 'training', 'fitness_equipment',
'strength_training', 'strength', 'cardio_training', 'cardio',
])
export function sportColor(sportType) { export function sportColor(sportType) {
const s = sportType?.toLowerCase()
const colors = { const colors = {
running: '#22c55e', // green running: '#22c55e', // green
cycling: '#f97316', // orange cycling: '#f97316', // orange
@@ -126,5 +134,6 @@ export function sportColor(sportType) {
swimming:'#38bdf8', // sky swimming:'#38bdf8', // sky
other: '#9ca3af', // gray other: '#9ca3af', // gray
} }
return colors[sportType?.toLowerCase()] || '#9ca3af' if (GYM_SPORTS.has(s)) return '#ef4444' // red
return colors[s] || '#9ca3af'
} }