File size: 3,224 Bytes
35527e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import type { Activity, ProcessedData } from '@/types';

/**
 * Format date to YYYY-MM-DD in local timezone (not UTC)
 */
function formatDateLocal(date: Date): string {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}

export function processActivities(activities: Activity[], dateRange?: { start: Date; end: Date }): ProcessedData {
    if (activities.length === 0 && !dateRange) {
        return {
            activities: [],
            dates: [],
            distances: [],
            durations: [],
            tss: [],
        };
    }

    // Sort activities by date
    const sortedActivities = [...activities].sort((a, b) => a.date.getTime() - b.date.getTime());

    // Get date range
    const startDate = dateRange?.start || (sortedActivities.length > 0 ? new Date(sortedActivities[0].date) : new Date());
    const endDate = dateRange?.end || (sortedActivities.length > 0 ? new Date(sortedActivities[sortedActivities.length - 1].date) : new Date());

    // Create a map of date -> activities
    const activityMap = new Map<string, Activity[]>();
    sortedActivities.forEach(activity => {
        const dateStr = formatDateLocal(activity.date);
        if (!activityMap.has(dateStr)) {
            activityMap.set(dateStr, []);
        }
        activityMap.get(dateStr)!.push(activity);
    });

    // Generate all dates in range
    const dates: string[] = [];
    const distances: (number | null)[] = [];
    const durations: (number | null)[] = [];
    const tss: (number | null)[] = [];

    for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
        const dateStr = formatDateLocal(d);
        dates.push(dateStr);

        const dayActivities = activityMap.get(dateStr) || [];

        if (dayActivities.length === 0) {
            // No activity this day
            distances.push(null);
            durations.push(null);
            tss.push(null);
        } else {
            // Sum up activities for the day
            let totalDistance = 0;
            let totalDuration = 0;
            let totalTss = 0;
            let hasDistance = false;
            let hasDuration = false;
            let hasTss = false;

            dayActivities.forEach(activity => {
                if (activity.distance !== undefined) {
                    totalDistance += activity.distance;
                    hasDistance = true;
                }
                if (activity.duration !== undefined) {
                    totalDuration += activity.duration;
                    hasDuration = true;
                }
                if (activity.trainingStressScore !== undefined) {
                    totalTss += activity.trainingStressScore;
                    hasTss = true;
                }
            });

            distances.push(hasDistance ? totalDistance : null);
            durations.push(hasDuration ? totalDuration : null);
            tss.push(hasTss ? totalTss : null);
        }
    }

    return {
        activities: sortedActivities,
        dates,
        distances,
        durations,
        tss,
    };
}