diff --git a/client/src/pages/StatsPage.tsx b/client/src/pages/StatsPage.tsx index a016f59..6049257 100644 --- a/client/src/pages/StatsPage.tsx +++ b/client/src/pages/StatsPage.tsx @@ -126,9 +126,8 @@ export default function StatsPage() { const isCurrentOrFutureWeek = useMemo(() => { if (!dateRange) return true; - const currentWeekEnd = getLastWorkDayOfWeek(new Date()); - currentWeekEnd.setHours(23, 59, 59, 999); - return dateRange[1] >= currentWeekEnd; + // Porovnáváme jen dny (obě data nesou čas svého vzniku), dopředu jde jít nejvýše na aktuální týden + return formatDate(dateRange[1]) >= formatDate(getLastWorkDayOfWeek(new Date())); }, [dateRange]); const handleKeyDown = useCallback((e: any) => { diff --git a/server/changelogs/2026-08-25.json b/server/changelogs/2026-08-25.json new file mode 100644 index 0000000..6d2be4f --- /dev/null +++ b/server/changelogs/2026-08-25.json @@ -0,0 +1,3 @@ +[ + "Statistiky se nově načtou i pro aktuální týden, který ještě neskončil" +] diff --git a/server/src/stats.ts b/server/src/stats.ts index c12f4f5..b794494 100644 --- a/server/src/stats.ts +++ b/server/src/stats.ts @@ -5,6 +5,9 @@ import getStorage from "./storage"; const storage = getStorage(); +/** O kolik dní do budoucnosti smí sahat koncové datum požadovaného rozsahu. */ +const MAX_FUTURE_DAYS = 7; + /** * Vypočte a vrátí statistiky jednotlivých možností pro předaný rozsah dat. * @@ -25,9 +28,12 @@ export async function getStats(startDate: string, endDate: string): Promise today) { + // Aktuální týden se načítá i s dny, které teprve budou — povolíme proto rozsah + // sahající maximálně týden do budoucnosti + const maxEnd = new Date(); + maxEnd.setHours(23, 59, 59, 999); + maxEnd.setDate(maxEnd.getDate() + MAX_FUTURE_DAYS); + if (end > maxEnd) { throw new Error('Nelze načíst statistiky pro budoucí datum'); } diff --git a/server/src/tests/statsRoutes.test.ts b/server/src/tests/statsRoutes.test.ts index 89ed42a..51ecd2c 100644 --- a/server/src/tests/statsRoutes.test.ts +++ b/server/src/tests/statsRoutes.test.ts @@ -4,6 +4,7 @@ import bodyParser from 'body-parser'; import { generateToken } from '../auth'; import { resetMemoryStorage } from '../storage/memory'; import statsRouter from '../routes/statsRoutes'; +import { formatDate } from '../utils'; function buildApp() { const app = express(); @@ -52,6 +53,31 @@ test('GET /stats s budoucím datem vrátí 400', async () => { expect(res.status).toBe(400); }); +test('GET /stats s koncovým datem do týdne v budoucnosti vrátí 200', async () => { + // Aktuální týden se načítá i s dny, které teprve budou + const start = new Date(); + const end = new Date(); + end.setDate(end.getDate() + 3); + const res = await request(buildApp()) + .get('/api/stats') + .query({ startDate: formatDate(start), endDate: formatDate(end) }) + .set('Authorization', TOKEN); + expect(res.status).toBe(200); + expect(Array.isArray(res.body)).toBe(true); +}); + +test('GET /stats s koncovým datem více než týden v budoucnosti vrátí 400', async () => { + const start = new Date(); + start.setDate(start.getDate() + 8); + const end = new Date(start); + end.setDate(end.getDate() + 4); + const res = await request(buildApp()) + .get('/api/stats') + .query({ startDate: formatDate(start), endDate: formatDate(end) }) + .set('Authorization', TOKEN); + expect(res.status).toBe(400); +}); + test('GET /stats/export vrátí XLSX soubor', async () => { const res = await request(buildApp()) .get('/api/stats/export')