diff --git a/src/params/fitnessMonth.ts b/src/params/fitnessMonth.ts new file mode 100644 index 00000000..00edf4bd --- /dev/null +++ b/src/params/fitnessMonth.ts @@ -0,0 +1,5 @@ +import type { ParamMatcher } from '@sveltejs/kit'; + +export const match: ParamMatcher = (param) => { + return /^\d{4}-\d{2}$/.test(param); +}; diff --git a/src/routes/api/fitness/sessions/+server.ts b/src/routes/api/fitness/sessions/+server.ts index 296edb5c..debd5ca2 100644 --- a/src/routes/api/fitness/sessions/+server.ts +++ b/src/routes/api/fitness/sessions/+server.ts @@ -27,8 +27,16 @@ export const GET: RequestHandler = async ({ url, locals }) => { const limit = parseInt(url.searchParams.get('limit') || '20'); const offset = parseInt(url.searchParams.get('offset') || '0'); - - const query = { createdBy: session.user.nickname }; + const month = url.searchParams.get('month'); // YYYY-MM + + const query: Record = { createdBy: session.user.nickname }; + if (month && /^\d{4}-\d{2}$/.test(month)) { + const start = new Date(month + '-01T00:00:00.000Z'); + const end = new Date(start); + end.setMonth(end.getMonth() + 1); + query.startTime = { $gte: start, $lt: end }; + } + const [sessions, total] = await Promise.all([ WorkoutSession.find(query).select('-exercises.gpsTrack -gpsTrack') .sort({ startTime: -1 }).limit(limit).skip(offset), diff --git a/src/routes/fitness/[history=fitnessHistory]/+page.server.ts b/src/routes/fitness/[history=fitnessHistory]/+page.server.ts deleted file mode 100644 index febbe1e7..00000000 --- a/src/routes/fitness/[history=fitnessHistory]/+page.server.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { PageServerLoad } from './$types'; - -export const load: PageServerLoad = async ({ fetch, url }) => { - const month = url.searchParams.get('month') || ''; - const params = new URLSearchParams({ limit: '50' }); - if (month) params.set('month', month); - - const res = await fetch(`/api/fitness/sessions?${params}`); - return { - sessions: await res.json() - }; -}; diff --git a/src/routes/fitness/[history=fitnessHistory]/+page.svelte b/src/routes/fitness/[history=fitnessHistory]/+page.svelte deleted file mode 100644 index 08e6759f..00000000 --- a/src/routes/fitness/[history=fitnessHistory]/+page.svelte +++ /dev/null @@ -1,121 +0,0 @@ - - -{t('history_title', lang)} - Bocken - -
-

{t('history_title', lang)}

- - {#if sessions.length === 0} -

{t('no_workouts_yet', lang)}

- {:else} - {#each Object.entries(grouped) as [month, monthSessions] (month)} -
-

{month} — {monthSessions.length} {monthSessions.length !== 1 ? t('workouts_plural', lang) : t('workout_singular', lang)}

-
- {#each monthSessions as session (session._id)} - - {/each} -
-
- {/each} - - {#if sessions.length < total} - - {/if} - {/if} -
- - diff --git a/src/routes/fitness/[history=fitnessHistory]/[[month=fitnessMonth]]/+page.server.ts b/src/routes/fitness/[history=fitnessHistory]/[[month=fitnessMonth]]/+page.server.ts new file mode 100644 index 00000000..4f670d74 --- /dev/null +++ b/src/routes/fitness/[history=fitnessHistory]/[[month=fitnessMonth]]/+page.server.ts @@ -0,0 +1,36 @@ +import type { PageServerLoad } from './$types'; + +export const load: PageServerLoad = async ({ fetch, params }) => { + const month = params.month; // YYYY-MM or undefined + + if (month) { + // Specific month view + const res = await fetch(`/api/fitness/sessions?month=${month}&limit=200`); + return { + sessions: await res.json(), + month, + }; + } + + // Default: last 2 months + const now = new Date(); + const twoMonthsAgo = new Date(now.getFullYear(), now.getMonth() - 1, 1); + const fromMonth = `${twoMonthsAgo.getFullYear()}-${String(twoMonthsAgo.getMonth() + 1).padStart(2, '0')}`; + const currentMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`; + + const [curRes, prevRes] = await Promise.all([ + fetch(`/api/fitness/sessions?month=${currentMonth}&limit=200`), + fetch(`/api/fitness/sessions?month=${fromMonth}&limit=200`), + ]); + + const curData = await curRes.json(); + const prevData = await prevRes.json(); + + return { + sessions: { + sessions: [...(curData.sessions ?? []), ...(prevData.sessions ?? [])], + total: (curData.total ?? 0) + (prevData.total ?? 0), + }, + month: null, + }; +}; diff --git a/src/routes/fitness/[history=fitnessHistory]/[[month=fitnessMonth]]/+page.svelte b/src/routes/fitness/[history=fitnessHistory]/[[month=fitnessMonth]]/+page.svelte new file mode 100644 index 00000000..93aad152 --- /dev/null +++ b/src/routes/fitness/[history=fitnessHistory]/[[month=fitnessMonth]]/+page.svelte @@ -0,0 +1,150 @@ + + +{t('history_title', lang)} - Bocken + +
+

{t('history_title', lang)}

+ + {#if sessions.length === 0} +

{t('no_workouts_yet', lang)}

+ {:else} + {#each Object.entries(grouped) as [month, monthSessions] (month)} +
+

{month} — {monthSessions.length} {monthSessions.length !== 1 ? t('workouts_plural', lang) : t('workout_singular', lang)}

+
+ {#each monthSessions as session (session._id)} + + {/each} +
+
+ {/each} + {/if} + + +
+ +