Files
mealprep/frontend/src/lib/planner/week.ts
Marcel Raddatz 5d2bb9e84e fix(planner): address all PR review blockers
- Fix logic bug `{#if !isPlanner === false}` - view/cook buttons now visible for all roles, swap only for planner
- Convert Tauschen from dead button to link with suggestions href
- Add week.ts unit tests (23 tests covering getWeekStart Sunday edge case, prevWeek/nextWeek, weekDays, isToday, formatWeekRange)
- Fix isToday to use UTC consistently (.toISOString().slice(0,10)) instead of local date
- Add server-side role guard to createPlan action (403 for members)
- Add weekStart format validation in createPlan action
- Add isSelected prop to DayMealCard with green treatment
- Make variety banner sticky on mobile (always visible per spec)
- Add day name abbreviation above date badge in desktop column headers
- Remove placeholder Navigation text from desktop sidebar
- Add aria-label to desktop empty tile buttons
- Add variety score partial failure test, multiple overlaps test, WeekStrip today+selected test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 11:07:47 +02:00

89 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Returns the ISO Monday (YYYY-MM-DD) for the week containing `date`.
*/
export function getWeekStart(date: Date): string {
const d = new Date(date);
const day = d.getUTCDay(); // 0=Sun, 1=Mon, …
const diff = day === 0 ? -6 : 1 - day; // shift to Monday
d.setUTCDate(d.getUTCDate() + diff);
return d.toISOString().slice(0, 10);
}
/**
* Returns the Monday of the previous week relative to `weekStart`.
*/
export function prevWeek(weekStart: string): string {
const d = new Date(weekStart + 'T00:00:00Z');
d.setUTCDate(d.getUTCDate() - 7);
return d.toISOString().slice(0, 10);
}
/**
* Returns the Monday of the next week relative to `weekStart`.
*/
export function nextWeek(weekStart: string): string {
const d = new Date(weekStart + 'T00:00:00Z');
d.setUTCDate(d.getUTCDate() + 7);
return d.toISOString().slice(0, 10);
}
/**
* Formats a date string (YYYY-MM-DD) as a localized day abbreviation.
*/
export function formatDayAbbr(dateStr: string, length: 'narrow' | 'short' = 'narrow'): string {
const d = new Date(dateStr + 'T00:00:00Z');
return d.toLocaleDateString('de-DE', { weekday: length, timeZone: 'UTC' });
}
/**
* Returns an array of 7 date strings for the week starting on `weekStart`.
*/
export function weekDays(weekStart: string): string[] {
const days: string[] = [];
for (let i = 0; i < 7; i++) {
const d = new Date(weekStart + 'T00:00:00Z');
d.setUTCDate(d.getUTCDate() + i);
days.push(d.toISOString().slice(0, 10));
}
return days;
}
/**
* Formats a date string as "Mo, 30.03." style label.
*/
export function formatDayLabel(dateStr: string): string {
const d = new Date(dateStr + 'T00:00:00Z');
const day = d.toLocaleDateString('de-DE', { weekday: 'short', timeZone: 'UTC' });
const date = d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', timeZone: 'UTC' });
return `${day}, ${date}`;
}
/**
* Formats a date string as "30. März" style label.
*/
export function formatDayFull(dateStr: string): string {
const d = new Date(dateStr + 'T00:00:00Z');
return d.toLocaleDateString('de-DE', { day: 'numeric', month: 'long', timeZone: 'UTC' });
}
/**
* Returns true if dateStr is today (UTC date).
* Uses UTC consistently with all other date functions in this module.
*/
export function isToday(dateStr: string): boolean {
const todayStr = new Date().toISOString().slice(0, 10);
return dateStr === todayStr;
}
/**
* Formats a week range: "30. Mär 5. Apr 2026".
*/
export function formatWeekRange(weekStart: string): string {
const start = new Date(weekStart + 'T00:00:00Z');
const end = new Date(weekStart + 'T00:00:00Z');
end.setUTCDate(end.getUTCDate() + 6);
const startStr = start.toLocaleDateString('de-DE', { day: 'numeric', month: 'short', timeZone: 'UTC' });
const endStr = end.toLocaleDateString('de-DE', { day: 'numeric', month: 'short', year: 'numeric', timeZone: 'UTC' });
return `${startStr} ${endStr}`;
}