import { Head, Link } from '@inertiajs/react'; import { ArrowLeft, ArrowRight, CalendarDays, Plus } from 'lucide-react'; import { PageHeading } from '@/components/page-heading'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import type { Reservation } from '@/types'; const weekdays = ['Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb', 'Dom']; export default function ReservationCalendar({ month, reservations, }: { month: string; reservations: Reservation[]; }) { const [year, monthNumber] = month.split('-').map(Number); const monthStart = new Date(year, monthNumber - 1, 1); const firstWeekday = (monthStart.getDay() + 6) % 7; const daysInMonth = new Date(year, monthNumber, 0).getDate(); const cellCount = Math.ceil((firstWeekday + daysInMonth) / 7) * 7; const gridStart = new Date(year, monthNumber - 1, 1 - firstWeekday); const days = Array.from({ length: cellCount }, (_, index) => { const date = new Date(gridStart); date.setDate(gridStart.getDate() + index); return date; }); const title = new Intl.DateTimeFormat('pt-PT', { month: 'long', year: 'numeric', }).format(monthStart); const previousMonth = monthKey(new Date(year, monthNumber - 2, 1)); const nextMonth = monthKey(new Date(year, monthNumber, 1)); return ( <>
Nova requisição } />

{title}

{weekdays.map((day) => (
{day}
))}
{days.map((day) => { const dayStart = new Date( day.getFullYear(), day.getMonth(), day.getDate(), ); const dayEnd = new Date( day.getFullYear(), day.getMonth(), day.getDate() + 1, ); const entries = reservations.filter( (reservation) => new Date(reservation.starts_at) < dayEnd && new Date(reservation.ends_at) > dayStart, ); const isCurrentMonth = day.getMonth() === monthNumber - 1; const isToday = sameDay(day, new Date()); return (
{day.getDate()}
{entries .slice(0, 3) .map((reservation) => (
item.asset.name).join(', ')}`} className={cn( 'truncate rounded border-l-2 bg-slate-100 px-1.5 py-1 text-[10px] font-medium sm:text-xs dark:bg-slate-900', statusBorder( reservation.status, ), )} > {reservation.reference}
))} {entries.length > 3 && (

+{entries.length - 3} pedido(s)

)}
); })}
{reservations.length === 0 && (
Não existem requisições neste mês.
)}
); } function Legend({ color, label }: { color: string; label: string }) { return ( {label} ); } function monthKey(date: Date): string { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`; } function sameDay(left: Date, right: Date): boolean { return ( left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth() && left.getDate() === right.getDate() ); } function statusBorder(status: string): string { if (['cancelled', 'rejected', 'expired', 'no_show'].includes(status)) { return 'border-slate-400 opacity-60'; } if (['approved', 'ready', 'delivered', 'in_use'].includes(status)) { return 'border-emerald-500'; } return 'border-amber-500'; } ReservationCalendar.layout = { breadcrumbs: [ { title: 'Requisições', href: '/requisicoes' }, { title: 'Calendário', href: '/requisicoes/calendario' }, ], };