diff --git a/app/running/[id]/page.tsx b/app/running/[id]/page.tsx
index 7aa7582..5cab6d8 100644
--- a/app/running/[id]/page.tsx
+++ b/app/running/[id]/page.tsx
@@ -7,16 +7,9 @@ import { GcbChart } from "@/components/gcb-chart";
import { RunMetricChart } from "@/components/run-metric-chart";
import { StatCard } from "@/components/stat-card";
import { formatDate, formatDistance, formatDuration, formatPace } from "@/lib/format";
-import {
- fetchActivityRoutePoints,
- fetchActivityRunMetrics,
- getAuthorizedClient,
-} from "@/lib/garmin/client";
import { getLatestAnalysisForTarget, serializeAnalysis } from "@/lib/models/analysis";
import {
getRunningActivity,
- setRunningActivityMetrics,
- setRunningActivityRoutePoints,
type RunMetrics,
type RunningActivity,
} from "@/lib/models/running";
@@ -24,83 +17,34 @@ import { getCurrentUserId } from "@/lib/session";
export const dynamic = "force-dynamic";
-function mayHaveRoute(activity: RunningActivity): boolean {
- return Boolean(activity.hasRoute) || Boolean(activity.routePoints?.length);
-}
-
-async function RouteMapFetcher({
- activity,
- userId,
-}: {
- activity: RunningActivity;
- userId: string;
-}) {
- let routePoints = activity.routePoints;
-
- if ((!routePoints || !activity.elevationProfile) && mayHaveRoute(activity)) {
- try {
- const client = await getAuthorizedClient(userId);
- const result = await fetchActivityRoutePoints(client, activity.garminActivityId);
- if (result) {
- await setRunningActivityRoutePoints(userId, activity.garminActivityId, result.points, result.elevationProfile);
- routePoints = result.points;
- }
- } catch {
- // GPS fetch failed silently
- }
- }
-
+function RouteMap({ activity }: { activity: RunningActivity }) {
+ const routePoints = activity.routePoints;
return (
{routePoints && routePoints.length > 0 ? (
) : (
- Brak danych GPS
+ Brak danych GPS — zsynchronizuj ponownie
)}
);
}
-function hasValidElevation(profile: number[] | undefined): boolean {
- return Array.isArray(profile) && profile.some((v) => v > 0);
-}
-
-async function ElevationFetcher({
- activity,
- userId,
-}: {
- activity: RunningActivity;
- userId: string;
-}) {
- let elevationProfile = activity.elevationProfile;
-
- if (!hasValidElevation(elevationProfile) && mayHaveRoute(activity)) {
- try {
- const client = await getAuthorizedClient(userId);
- const result = await fetchActivityRoutePoints(client, activity.garminActivityId);
- if (result) {
- await setRunningActivityRoutePoints(userId, activity.garminActivityId, result.points, result.elevationProfile);
- elevationProfile = result.elevationProfile;
- }
- } catch {
- // silent
- }
- }
-
+function ElevationSection({ activity }: { activity: RunningActivity }) {
+ const elevationProfile = activity.elevationProfile;
if (!elevationProfile || elevationProfile.length < 2) return null;
const elevData = elevationProfile
.map((altM, i) => ({
- distanceKm: Math.round((i / elevationProfile!.length) * activity.distanceM / 10) / 100,
+ distanceKm: Math.round((i / elevationProfile.length) * activity.distanceM / 10) / 100,
altM,
}))
.filter((p) => p.altM > 0);
if (elevData.length < 2) return null;
- // Merge pace by fractional position (both arrays span the same run, different sample counts)
const paceSrc = activity.runMetrics?.paceSec;
const data = elevData.map((ep, i) => {
if (!paceSrc || paceSrc.length === 0) return ep;
@@ -122,33 +66,8 @@ function toChartData(
.filter((p) => p.value > 0);
}
-async function RunMetricsFetcher({
- activity,
- userId,
-}: {
- activity: RunningActivity;
- userId: string;
-}) {
- let metrics: RunMetrics | undefined = activity.runMetrics;
-
- const missingCadence = activity.avgCadence && !metrics?.cadenceSpm;
- const missingGcb = activity.avgGroundContactBalanceLeftPct && !metrics?.gcbLeftPct;
- // Re-fetch if paceSec missing or was computed from integer-rounded speeds (< 15 unique values = rounding artifact)
- const validPace = metrics?.paceSec?.filter((v) => v > 0) ?? [];
- const missingPace = validPace.length === 0 || new Set(validPace).size < 15;
-
- if ((!metrics || missingCadence || missingGcb || missingPace) && mayHaveRoute(activity)) {
- try {
- const client = await getAuthorizedClient(userId);
- const fetched = await fetchActivityRunMetrics(client, activity.garminActivityId);
- if (fetched) {
- await setRunningActivityMetrics(userId, activity.garminActivityId, fetched);
- metrics = fetched;
- }
- } catch {
- // silent
- }
- }
+function RunMetricsSection({ activity }: { activity: RunningActivity }) {
+ const metrics: RunMetrics | undefined = activity.runMetrics;
if (!metrics || metrics.distanceKm.length === 0) return null;
@@ -186,11 +105,6 @@ async function RunMetricsFetcher({
);
}
-function MapSkeleton() {
- return (
-
- );
-}
export default async function RunningActivityPage({
params,
@@ -215,9 +129,7 @@ export default async function RunningActivityPage({
- }>
-
-
+
@@ -261,13 +173,8 @@ export default async function RunningActivityPage({
) : null}
-
-
-
-
-
-
-
+
+
{
const since = await getLastSyncAt(userId);
const activities = await fetchRunningActivities(client);
@@ -39,6 +45,36 @@ async function syncWithClient(userId: string, client: GarminConnect): Promise a.hasRoute && (!a.routePoints?.length || !a.runMetrics?.paceSec))
+ .slice(0, ENRICH_PER_SYNC);
+
+ for (const activity of needsEnrich) {
+ try {
+ if (!activity.routePoints?.length) {
+ const route = await fetchActivityRoutePoints(client, activity.garminActivityId);
+ if (route) {
+ await setRunningActivityRoutePoints(
+ userId,
+ activity.garminActivityId,
+ route.points,
+ route.elevationProfile
+ );
+ }
+ }
+ if (!activity.runMetrics?.paceSec) {
+ const metrics = await fetchActivityRunMetrics(client, activity.garminActivityId);
+ if (metrics) {
+ await setRunningActivityMetrics(userId, activity.garminActivityId, metrics);
+ }
+ }
+ } catch {
+ // Rate limited or activity has no GPS — skip silently
+ }
+ }
+
revalidatePath("/running");
revalidatePath("/settings");
revalidatePath("/");
diff --git a/components/elevation-chart.tsx b/components/elevation-chart.tsx
index 42e24d3..1a1684a 100644
--- a/components/elevation-chart.tsx
+++ b/components/elevation-chart.tsx
@@ -53,7 +53,7 @@ export function ElevationChart({ data }: Props) {
};
return (
-
+
Profil wysokości
{hasPace && (