feat(stats): implement SleepTimetable with enhanced date formatting and fixed tests
Build Frontend / build (push) Failing after 10m34s

This commit is contained in:
2026-06-11 17:18:21 +02:00
parent bb58389675
commit da76baa2ae
4 changed files with 23 additions and 17 deletions
@@ -9,15 +9,16 @@ interface TimetableProps {
day_end: string; day_end: string;
} }
function getDayName(dateStr: string) { export function getDayName(dateStr: string) {
return new Date(dateStr + 'T00:00:00').toLocaleDateString('en-US', { weekday: 'short' }); return new Date(dateStr + 'T00:00:00').toLocaleDateString('en-US', { weekday: 'short' });
} }
function formatDayLabel(dateStr: string) { export function formatDayLabel(dateStr: string) {
const date = new Date(dateStr + 'T00:00:00'); const date = new Date(dateStr + 'T00:00:00');
const weekday = date.toLocaleDateString('en-US', { weekday: 'short' }); const weekday = date.toLocaleDateString('en-US', { weekday: 'short' });
const day = date.getDate(); const day = date.getDate();
return `${weekday} ${day}`; const month = date.getMonth() + 1;
return `${weekday} ${day}/${month}`;
} }
function formatTimeLabel(mins: number) { function formatTimeLabel(mins: number) {
@@ -176,7 +177,7 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) =
<div className="h-2" /> {/* Empty corner cell */} <div className="h-2" /> {/* Empty corner cell */}
{visibleDays.map((day) => ( {visibleDays.map((day) => (
<div key={day} className="text-center text-[10px] font-medium text-gray-500 uppercase flex items-center justify-center h-2"> <div key={day} className="text-center text-[10px] font-medium text-gray-500 uppercase flex items-center justify-center h-2">
{getDayName(day)} {formatDayLabel(day)}
</div> </div>
))} ))}
</div> </div>
@@ -0,0 +1,9 @@
import { describe, it, expect } from 'vitest';
import { formatDayLabel } from '../SleepTimetable';
describe('formatDayLabel', () => {
it('formats date as "Weekday D/M"', () => {
expect(formatDayLabel('2025-06-09')).toBe('Mon 9/6');
expect(formatDayLabel('2025-06-10')).toBe('Tue 10/6');
});
});
@@ -56,9 +56,9 @@ describe('SleepTimetable', () => {
}); });
render(<Timetable {...singleDayProps} />); render(<Timetable {...singleDayProps} />);
// Check if it renders the single day header // Check if it renders the single day header
expect(screen.getByText(/18/i)).toBeInTheDocument(); // Check if it renders the single day header with date format
expect(screen.getByText(/Fri 18\/4/i)).toBeInTheDocument();
}); });
it('handles a large date range', () => { it('handles a large date range', () => {
const largeRangeProps = { ...defaultProps, from_date: '2025-01-01', to_date: '2025-01-31' }; const largeRangeProps = { ...defaultProps, from_date: '2025-01-01', to_date: '2025-01-31' };
(useStats as any).mockReturnValue({ (useStats as any).mockReturnValue({
@@ -91,12 +91,11 @@ describe('SleepTimetable', () => {
vi.stubGlobal('innerWidth', 1024); vi.stubGlobal('innerWidth', 1024);
render(<Timetable {...defaultProps} />); render(<Timetable {...defaultProps} />);
expect(screen.getByText(/18/i)).toBeInTheDocument(); expect(screen.getByText(/Fri 18\/4/i)).toBeInTheDocument();
expect(screen.getByText(/19/i)).toBeInTheDocument(); expect(screen.getByText(/Sat 19\/4/i)).toBeInTheDocument();
expect(screen.getByText(/20/i)).toBeInTheDocument(); expect(screen.getByText(/Sun 20\/4/i)).toBeInTheDocument();
expect(screen.getByText(/21/i)).toBeInTheDocument(); expect(screen.getByText(/Mon 21\/4/i)).toBeInTheDocument();
}); });
it('Medium Tier (400-768px): shows tab groups and updates on click', () => { it('Medium Tier (400-768px): shows tab groups and updates on click', () => {
(useStats as any).mockReturnValue({ timetable: mockTimetable, isLoading: false }); (useStats as any).mockReturnValue({ timetable: mockTimetable, isLoading: false });
vi.stubGlobal('innerWidth', 500); vi.stubGlobal('innerWidth', 500);
@@ -134,17 +133,14 @@ describe('SleepTimetable', () => {
}); });
expect(screen.getByRole('button', { name: /21/i })).toBeInTheDocument(); expect(screen.getByRole('button', { name: /21/i })).toBeInTheDocument();
expect(screen.getByRole('button', { name: /20/i })).toBeInTheDocument(); expect(screen.getByRole('button', { name: /21\/4/i })).toBeInTheDocument();
act(() => { act(() => {
fireEvent.click(screen.getByRole('button', { name: /20/i })); fireEvent.click(screen.getByRole('button', { name: /20/i }));
}); });
expect(container.querySelector('[data-testid^="cell-2025-04-20-"]')).toBeInTheDocument(); expect(container.querySelector('[data-testid^="cell-2025-04-20-"]')).toBeInTheDocument();
expect(container.querySelector('[data-testid^="cell-2025-04-21-"]')).not.toBeInTheDocument(); expect(container.querySelector('[data-testid^="cell-2025-04-21-"]')).not.toBeInTheDocument();
}); });
}); });
describe('Grid Accuracy', () => { describe('Grid Accuracy', () => {
it('renders sleeping cells correctly', () => { it('renders sleeping cells correctly', () => {
const day = '2025-04-18'; const day = '2025-04-18';
+2 -2
View File
@@ -2,8 +2,8 @@
- [/frontend start] Check so that all tests actually make sense, maybe some are now obsolete, and some are missing - [/frontend start] Check so that all tests actually make sense, maybe some are now obsolete, and some are missing
- [ ] Add a test coverage metric to both frontend and backend so that we can check how much of the code is tested. I would like >=90% - [ ] Add a test coverage metric to both frontend and backend so that we can check how much of the code is tested. I would like >=90%
- [ ] Go over Claude's slop-cleanup-stuff - [/] Go over Claude's slop-cleanup-stuff
- [ ] Add dates on the sleep timetable days - [x] Add dates on the sleep timetable days
- [x] Update the "Sleep Sessions" by adding a fake pagination view in the frontend so that I don't have to scroll so much. Instead, I want to simply click "next" and "previous" (with like numbers in between like a google search) - [x] Update the "Sleep Sessions" by adding a fake pagination view in the frontend so that I don't have to scroll so much. Instead, I want to simply click "next" and "previous" (with like numbers in between like a google search)
- [x] Bug with gitea workflow: - [x] Bug with gitea workflow: