Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 17x 8x 6x 2x 2x | /**
* Route-local view type for a completed workout as shown on the history list.
* Normalises the embedded workout_logs relation (0-or-1) to flat fields.
* Not exported from shared — this shape is specific to the history route.
*/
export interface CompletedWorkoutRow {
id: string;
scheduled_date: string; // 'YYYY-MM-DD'
session_type: string;
session_type_display: string; // capitalised server-side
overall_feeling: string | null;
was_scaled: boolean;
}
/**
* Sort completed workouts for display — newest first, id DESC as stable tiebreak.
*
* The DB query already applies ORDER BY scheduled_date DESC, id DESC (primary,
* efficient path). This pure helper re-asserts the same ordering rule so it is
* unit-testable without a DB mock, and encodes it defensively in the loader
* (mirrors the selectNextWorkout precedent). The DB order is the source of
* truth at runtime; the helper is a testable re-assertion of the same rule.
*
* Pure: no mutation of the input array.
*/
export function sortCompletedWorkouts(rows: CompletedWorkoutRow[]): CompletedWorkoutRow[] {
return [...rows].sort((a, b) => {
if (a.scheduled_date !== b.scheduled_date) {
// Descending: b before a when b > a
return b.scheduled_date < a.scheduled_date ? -1 : 1;
}
Eif (a.id !== b.id) {
// Descending: b before a when b > a
return b.id < a.id ? -1 : 1;
}
return 0;
});
}
|