import { useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { format, startOfWeek, addDays, isSameDay, isBefore, startOfDay } from 'date-fns'; import type { UpcomingItem } from '@/types'; import { cn } from '@/lib/utils'; interface WeekTimelineProps { items: UpcomingItem[]; } const typeColors: Record = { todo: 'bg-blue-400', event: 'bg-purple-400', reminder: 'bg-orange-400', }; export default function WeekTimeline({ items }: WeekTimelineProps) { const navigate = useNavigate(); const today = useMemo(() => startOfDay(new Date()), []); const weekStart = useMemo(() => startOfWeek(today, { weekStartsOn: 1 }), [today]); const days = useMemo(() => { return Array.from({ length: 7 }, (_, i) => { const date = addDays(weekStart, i); const dayItems = items.filter((item) => { const itemDate = item.datetime ? new Date(item.datetime) : new Date(item.date); return isSameDay(startOfDay(itemDate), date); }); return { date, key: format(date, 'yyyy-MM-dd'), dayName: format(date, 'EEE'), dayNum: format(date, 'd'), isToday: isSameDay(date, today), isPast: isBefore(date, today), items: dayItems, }; }); }, [weekStart, today, items]); return (
{days.map((day) => (
navigate('/calendar', { state: { date: day.key, view: 'timeGridDay' } })} className={cn( 'flex-1 flex flex-col items-center gap-1 sm:gap-1.5 rounded-lg py-2 sm:py-3 px-1 sm:px-2 transition-all duration-200 border cursor-pointer', day.isToday ? 'bg-accent/10 border-accent/30 shadow-[0_0_12px_hsl(var(--accent-color)/0.15)]' : day.isPast ? 'border-transparent opacity-50 hover:opacity-75 hover:scale-[1.04] hover:bg-card-elevated' : 'border-transparent hover:border-border/50 hover:scale-[1.04] hover:bg-card-elevated' )} > {day.dayName} {day.dayNum}
{day.items.slice(0, 4).map((item) => (
))} {day.items.length > 4 && ( +{day.items.length - 4} )} {day.isToday && (
)}
))}
); }