first commit
Some checks failed
tests / ci (push) Has been cancelled

This commit is contained in:
2026-10-27 11:01:11 +00:00
parent 9b8b21c853
commit fb04d71a8d
29 changed files with 9733 additions and 326 deletions

View File

@@ -1,9 +1,18 @@
import { Head, Link, useForm } from '@inertiajs/react';
import { Ban, CalendarDays, MessageSquareText, Plus } from 'lucide-react';
import { Head, Link, useForm, router } from '@inertiajs/react';
import {
Ban,
CalendarDays,
MessageSquareText,
Plus,
Repeat,
Filter,
X,
} from 'lucide-react';
import { useState } from 'react';
import InputError from '@/components/input-error';
import { PageHeading } from '@/components/page-heading';
import { ReservationStatus } from '@/components/reservation-status';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
Dialog,
@@ -14,12 +23,39 @@ import {
DialogTitle,
} from '@/components/ui/dialog';
import { Label } from '@/components/ui/label';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import type { Paginated, Reservation } from '@/types';
const statusOptions = [
{ value: '', label: 'Todos os estados' },
{ value: 'pending_approval', label: 'Pendente de aprovação' },
{ value: 'awaiting_information', label: 'A aguardar esclarecimentos' },
{ value: 'approved', label: 'Aprovada' },
{ value: 'ready', label: 'Pronta para entrega' },
{ value: 'delivered', label: 'Entregue' },
{ value: 'in_use', label: 'Em utilização' },
{ value: 'returned', label: 'Devolvida' },
{ value: 'completed', label: 'Concluída' },
{ value: 'rejected', label: 'Rejeitada' },
{ value: 'cancelled', label: 'Cancelada' },
{ value: 'expired', label: 'Expirada' },
{ value: 'no_show', label: 'Falta' },
{ value: 'overdue', label: 'Atrasada' },
{ value: 'incident', label: 'Incidente' },
];
export default function ReservationsIndex({
reservations,
status = '',
}: {
reservations: Paginated<Reservation>;
status?: string;
}) {
const [selected, setSelected] = useState<Reservation | null>(null);
const [clarification, setClarification] = useState<Reservation | null>(
@@ -39,6 +75,13 @@ export default function ReservationsIndex({
'ready',
];
function handleStatusChange(value: string) {
router.get('/requisicoes', { status: value || undefined }, {
preserveState: true,
preserveScroll: true,
});
}
function openCancellation(reservation: Reservation) {
cancelForm.reset();
cancelForm.clearErrors();
@@ -93,6 +136,32 @@ export default function ReservationsIndex({
</Button>
}
/>
<div className="flex items-center gap-3">
<div className="flex items-center gap-2">
<Filter className="size-4 text-muted-foreground" />
<Select value={status} onValueChange={handleStatusChange}>
<SelectTrigger className="w-64">
<SelectValue placeholder="Filtrar por estado" />
</SelectTrigger>
<SelectContent>
{statusOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
{status && (
<Button
variant="ghost"
size="sm"
onClick={() => handleStatusChange('')}
>
<X className="size-4" />
</Button>
)}
</div>
</div>
{reservations.data.length ? (
<div className="overflow-hidden rounded-xl border bg-card">
<div className="hidden grid-cols-[150px_1fr_220px_150px_110px] gap-4 border-b bg-slate-50 px-5 py-3 text-xs font-medium text-muted-foreground uppercase md:grid dark:bg-slate-900">
@@ -107,9 +176,20 @@ export default function ReservationsIndex({
key={reservation.id}
className="grid gap-3 border-b px-5 py-4 last:border-0 md:grid-cols-[150px_1fr_220px_150px_110px] md:items-center"
>
<span className="font-mono text-sm font-medium">
{reservation.reference}
</span>
<div className="flex flex-col gap-1">
<span className="font-mono text-sm font-medium">
{reservation.reference}
</span>
{reservation.recurring_group_id && (
<Badge
variant="outline"
className="w-fit gap-1 border-primary/30 text-[10px] text-primary"
>
<Repeat className="size-2.5" />{' '}
Série semanal
</Badge>
)}
</div>
<div className="flex flex-col items-start gap-1">
{reservation.status ===
'awaiting_information' && (