Mobile-responsive UI: bottom tab nav, stacked dashboard, page fixes for phones
- Layout: sidebar hidden below md; mobile top header + bottom tab bar (Dashboard/Activities/Health/Routes) with a More slide-up sheet holding Records/Import/Profile/Users, Garmin sync progress and sign-out - Dashboard: single-column widget stack on phones ordered from the saved desktop layout (stat cards pair into 2-col grid); drag-edit stays desktop-only; grid conditionally mounted so WidthProvider never measures a hidden container - New useMediaQuery/useIsMobile hook (matchMedia, md breakpoint) - ActivityDetail: 2-col stats on phones, wrapping map toolbar, Height control hidden on small screens - Activities: compact distance/time/pace line on mobile rows - Records/Users: horizontally scrollable tables; route records hide Pace/Date columns below sm - Profile forms single-column on phones; Routes expanded card stacks; Health flex-wrap fixes; p-4 md:p-6 page padding; h-dvh for mobile browser chrome - vite.config: VITE_PROXY_TARGET override for host-side dev Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -41,7 +41,7 @@ export default function ActivitiesPage() {
|
||||
const clearDateFilter = () => navigate('/activities')
|
||||
|
||||
return (
|
||||
<div className="p-6">
|
||||
<div className="p-4 md:p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h1 className="text-2xl font-bold text-white">Activities</h1>
|
||||
<Link
|
||||
@@ -54,7 +54,7 @@ export default function ActivitiesPage() {
|
||||
|
||||
{/* YTD stats */}
|
||||
{ytdStats && (
|
||||
<div className="flex gap-4 mb-4 text-sm">
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-1 mb-4 text-sm">
|
||||
{ytdStats.running_km > 0 && (
|
||||
<span className="text-blue-400">🏃 {ytdStats.running_km.toFixed(0)} km this year</span>
|
||||
)}
|
||||
@@ -100,7 +100,7 @@ export default function ActivitiesPage() {
|
||||
<Link
|
||||
key={activity.id}
|
||||
to={`/activities/${activity.id}`}
|
||||
className="flex items-center gap-4 bg-gray-900 hover:bg-gray-800 border border-gray-800 hover:border-gray-700 rounded-xl p-4 transition-all group"
|
||||
className="flex items-center gap-3 p-3 sm:gap-4 sm:p-4 bg-gray-900 hover:bg-gray-800 border border-gray-800 hover:border-gray-700 rounded-xl transition-all group"
|
||||
>
|
||||
{/* Sport indicator */}
|
||||
<div
|
||||
@@ -116,6 +116,10 @@ export default function ActivitiesPage() {
|
||||
{activity.name}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mt-0.5">{formatDate(activity.start_time)}</p>
|
||||
{/* Compact metrics line — the full metrics column is hidden below sm */}
|
||||
<p className="sm:hidden text-xs text-gray-400 mt-0.5 truncate">
|
||||
{formatDistance(activity.distance_m)} · {formatDuration(activity.duration_s)} · {formatPace(activity.avg_speed_ms, activity.sport_type)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Metrics */}
|
||||
|
||||
Reference in New Issue
Block a user