Files
babymonitor/diff.md
T

248 lines
10 KiB
Markdown

diff --git a/frontend/src/components/stats/SessionList.tsx b/frontend/src/components/stats/SessionList.tsx
index 374e41c..2bd6ea7 100644
--- a/frontend/src/components/stats/SessionList.tsx
+++ b/frontend/src/components/stats/SessionList.tsx
@@ -1,15 +1,29 @@
import React, { useState } from 'react';
import { useSessions } from '../../hooks/useSleepSession';
+import { useSettings } from '../../hooks/useSettings';
+import { Pagination } from './Pagination';
import { Edit2, Check, X, Trash2 } from 'lucide-react';
import type { SleepSessionRead } from '../../types';
import { formatDateTime, toLocalDatetimeInputValue, getDurationMinutes, formatMinutes } from '../../utils/time';
export function SessionList() {
const { sessions, isLoading, updateSession, deleteSession, isDeleting } = useSessions();
+ const { settings } = useSettings();
+ const sessionsPerPage = settings.sessionsPerPage;
+
+ const [currentPage, setCurrentPage] = useState(1);
const [editingId, setEditingId] = useState<number | null>(null);
const [editStart, setEditStart] = useState<string>('');
const [editEnd, setEditEnd] = useState<string>('');
+ const totalPages = Math.ceil(sessions.length / sessionsPerPage);
+ const clampedPage = Math.max(1, Math.min(currentPage, totalPages || 1));
+
+ const paginatedSessions = sessions.slice(
+ (clampedPage - 1) * sessionsPerPage,
+ clampedPage * sessionsPerPage
+ );
+
if (isLoading) return <div className="text-center p-4">Loading sessions...</div>;
if (!sessions.length) return <div className="text-center p-4 text-gray-500">No sessions recorded.</div>;
@@ -55,7 +69,7 @@ export function SessionList() {
<div className="bg-white p-4 rounded-xl shadow-sm border border-gray-200">
<h3 className="text-lg font-semibold mb-4 text-gray-800">Sleep Sessions</h3>
<div className="space-y-2">
- {sessions.map((s) => (
+ {paginatedSessions.map((s) => (
<div key={s.id} className="border-b border-gray-100 last:border-0 py-3 sm:py-2">
{editingId === s.id ? (
<div className="flex flex-col space-y-3 py-1">
@@ -140,6 +154,13 @@ export function SessionList() {
</div>
))}
</div>
+ {sessions.length > sessionsPerPage && (
+ <Pagination
+ currentPage={clampedPage}
+ totalPages={totalPages}
+ onPageChange={setCurrentPage}
+ />
+ )}
</div>
);
}
diff --git a/frontend/src/components/stats/SettingsPopover.tsx b/frontend/src/components/stats/SettingsPopover.tsx
index 005a302..8031392 100644
--- a/frontend/src/components/stats/SettingsPopover.tsx
+++ b/frontend/src/components/stats/SettingsPopover.tsx
@@ -6,15 +6,17 @@ interface SettingsPopoverProps {
dayEnd: string;
wakeupRef: string;
bedtimeRef: string;
- onSave: (settings: { dayStart: string; dayEnd: string; wakeupRef: string; bedtimeRef: string }) => void;
+ sessionsPerPage: number;
+ onSave: (settings: { dayStart: string; dayEnd: string; wakeupRef: string; bedtimeRef: string; sessionsPerPage: number }) => void;
}
-export function SettingsPopover({ dayStart, dayEnd, wakeupRef, bedtimeRef, onSave }: SettingsPopoverProps) {
+export function SettingsPopover({ dayStart, dayEnd, wakeupRef, bedtimeRef, sessionsPerPage, onSave }: SettingsPopoverProps) {
const [isOpen, setIsOpen] = useState(false);
const [localDayStart, setLocalDayStart] = useState(dayStart);
const [localDayEnd, setLocalDayEnd] = useState(dayEnd);
const [localWakeupRef, setLocalWakeupRef] = useState(wakeupRef);
const [localBedtimeRef, setLocalBedtimeRef] = useState(bedtimeRef);
+ const [localSessionsPerPage, setLocalSessionsPerPage] = useState(sessionsPerPage);
const popoverRef = useRef<HTMLDivElement>(null);
useEffect(() => {
@@ -22,7 +24,8 @@ export function SettingsPopover({ dayStart, dayEnd, wakeupRef, bedtimeRef, onSav
setLocalDayEnd(dayEnd);
setLocalWakeupRef(wakeupRef);
setLocalBedtimeRef(bedtimeRef);
- }, [dayStart, dayEnd, wakeupRef, bedtimeRef]);
+ setLocalSessionsPerPage(sessionsPerPage);
+ }, [dayStart, dayEnd, wakeupRef, bedtimeRef, sessionsPerPage]);
useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
@@ -42,6 +45,7 @@ export function SettingsPopover({ dayStart, dayEnd, wakeupRef, bedtimeRef, onSav
dayEnd: localDayEnd,
wakeupRef: localWakeupRef,
bedtimeRef: localBedtimeRef,
+ sessionsPerPage: localSessionsPerPage,
});
setIsOpen(false);
};
@@ -65,44 +69,58 @@ export function SettingsPopover({ dayStart, dayEnd, wakeupRef, bedtimeRef, onSav
<div className="space-y-3">
<div>
-<label htmlFor="day-start" className="block text-xs text-gray-500 mb-1">Day starts (HH:MM)</label>
-<input
- id="day-start"
- type="time"
- value={localDayStart}
- onChange={(e) => setLocalDayStart(e.target.value)}
- className="w-full p-2 border rounded-md text-sm"
-/>
+ <label htmlFor="day-start" className="block text-xs text-gray-500 mb-1">Day starts (HH:MM)</label>
+ <input
+ id="day-start"
+ type="time"
+ value={localDayStart}
+ onChange={(e) => setLocalDayStart(e.target.value)}
+ className="w-full p-2 border rounded-md text-sm"
+ />
</div>
<div>
-<label htmlFor="day-end" className="block text-xs text-gray-500 mb-1">Day ends (HH:MM)</label>
-<input
- id="day-end"
- type="time"
- value={localDayEnd}
- onChange={(e) => setLocalDayEnd(e.target.value)}
- className="w-full p-2 border rounded-md text-sm"
-/>
+ <label htmlFor="day-end" className="block text-xs text-gray-500 mb-1">Day ends (HH:MM)</label>
+ <input
+ id="day-end"
+ type="time"
+ value={localDayEnd}
+ onChange={(e) => setLocalDayEnd(e.target.value)}
+ className="w-full p-2 border rounded-md text-sm"
+ />
</div>
<div>
-<label htmlFor="wakeup-ref" className="block text-xs text-gray-500 mb-1">Wakeup ref (HH:MM)</label>
-<input
- id="wakeup-ref"
- type="time"
- value={localWakeupRef}
- onChange={(e) => setLocalWakeupRef(e.target.value)}
- className="w-full p-2 border rounded-md text-sm"
-/>
+ <label htmlFor="wakeup-ref" className="block text-xs text-gray-500 mb-1">Wakeup ref (HH:MM)</label>
+ <input
+ id="wakeup-ref"
+ type="time"
+ value={localWakeupRef}
+ onChange={(e) => setLocalWakeupRef(e.target.value)}
+ className="w-full p-2 border rounded-md text-sm"
+ />
</div>
<div>
-<label htmlFor="bedtime-ref" className="block text-xs text-gray-500 mb-1">Bedtime ref (HH:MM)</label>
-<input
- id="bedtime-ref"
- type="time"
- value={localBedtimeRef}
- onChange={(e) => setLocalBedtimeRef(e.target.value)}
- className="w-full p-2 border rounded-md text-sm"
-/>
+ <label htmlFor="bedtime-ref" className="block text-xs text-gray-500 mb-1">Bedtime ref (HH:MM)</label>
+ <input
+ id="bedtime-ref"
+ type="time"
+ value={localBedtimeRef}
+ onChange={(e) => setLocalBedtimeRef(e.target.value)}
+ className="w-full p-2 border rounded-md text-sm"
+ />
+ </div>
+ <div>
+ <label htmlFor="sessions-per-page" className="block text-xs text-gray-500 mb-1">Results per page</label>
+ <select
+ id="sessions-per-page"
+ value={localSessionsPerPage}
+ onChange={(e) => setLocalSessionsPerPage(Number(e.target.value))}
+ className="w-full p-2 border rounded-md text-sm"
+ >
+ <option value={5}>5</option>
+ <option value={10}>10</option>
+ <option value={25}>25</option>
+ <option value={50}>50</option>
+ </select>
</div>
</div>
diff --git a/frontend/src/components/stats/StatsPage.tsx b/frontend/src/components/stats/StatsPage.tsx
index 2516d55..e3518c8 100644
--- a/frontend/src/components/stats/StatsPage.tsx
+++ b/frontend/src/components/stats/StatsPage.tsx
@@ -27,18 +27,20 @@ const StatsPage: React.FC = () => {
<h2 className="text-3xl font-extrabold text-slate-900 tracking-tight">Statistics</h2>
<p className="text-slate-500 text-sm mt-1">Overview of sleep patterns and trends</p>
</div>
- <SettingsPopover
- dayStart={settings.dayStart}
- dayEnd={settings.dayEnd}
- wakeupRef={settings.wakeupRef}
- bedtimeRef={settings.bedtimeRef}
- onSave={(s) => {
- update('dayStart', s.dayStart);
- update('dayEnd', s.dayEnd);
- update('wakeupRef', s.wakeupRef);
- update('bedtimeRef', s.bedtimeRef);
- }}
- />
+ <SettingsPopover
+ dayStart={settings.dayStart}
+ dayEnd={settings.dayEnd}
+ wakeupRef={settings.wakeupRef}
+ bedtimeRef={settings.bedtimeRef}
+ sessionsPerPage={settings.sessionsPerPage}
+ onSave={(s) => {
+ update('dayStart', s.dayStart);
+ update('dayEnd', s.dayEnd);
+ update('wakeupRef', s.wakeupRef);
+ update('bedtimeRef', s.bedtimeRef);
+ update('sessionsPerPage', s.sessionsPerPage);
+ }}
+ />
</div>
<div className="bg-white p-6 rounded-[2rem] shadow-md border border-gray-100">
diff --git a/frontend/src/hooks/useSettings.ts b/frontend/src/hooks/useSettings.ts
index c587fb3..d95899b 100644
--- a/frontend/src/hooks/useSettings.ts
+++ b/frontend/src/hooks/useSettings.ts
@@ -8,6 +8,7 @@ interface Settings {
wakeupRef: string;
bedtimeRef: string;
statsInterval: number;
+ sessionsPerPage: number;
}
const DEFAULT_SETTINGS: Settings = {
@@ -16,6 +17,7 @@ const DEFAULT_SETTINGS: Settings = {
wakeupRef: '04:00',
bedtimeRef: '19:00',
statsInterval: 7,
+ sessionsPerPage: 10,
};
export function useSettings() {