160 lines
6.6 KiB
TypeScript
160 lines
6.6 KiB
TypeScript
import { Head, Link, useForm } from '@inertiajs/react';
|
|
import { Plus, Search } from 'lucide-react';
|
|
import {
|
|
PageTitle,
|
|
Panel,
|
|
RequisitionTable,
|
|
controlClass,
|
|
} from '@/components/procurement';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { statusLabels } from '@/types/procurement';
|
|
import type { Requisition } from '@/types/procurement';
|
|
|
|
type Props = {
|
|
requisitions: {
|
|
data: Requisition[];
|
|
current_page: number;
|
|
last_page: number;
|
|
prev_page_url: string | null;
|
|
next_page_url: string | null;
|
|
total: number;
|
|
};
|
|
filters: { search?: string; status?: string; view?: string };
|
|
};
|
|
export default function Index({ requisitions, filters }: Props) {
|
|
const form = useForm({
|
|
search: filters.search ?? '',
|
|
status: filters.status ?? '',
|
|
view: filters.view ?? 'all',
|
|
});
|
|
const views: Record<string, { title: string; description: string }> = {
|
|
all: {
|
|
title: 'Requisições autorizadas',
|
|
description:
|
|
'Consulte os pedidos disponíveis para o seu perfil e acompanhe o estado de cada processo.',
|
|
},
|
|
mine: {
|
|
title:
|
|
filters.status === 'draft'
|
|
? 'Os meus rascunhos'
|
|
: 'Minhas requisições',
|
|
description:
|
|
'Pedidos criados por si, desde o rascunho até à decisão.',
|
|
},
|
|
approvals: {
|
|
title: 'Pendentes para mim',
|
|
description:
|
|
'Pedidos em que a próxima etapa pode ser decidida por si. A elegibilidade é conferida pelo servidor.',
|
|
},
|
|
decided: {
|
|
title: 'Minhas decisões',
|
|
description:
|
|
'Histórico dos pedidos em que registou uma aprovação ou rejeição.',
|
|
},
|
|
};
|
|
const view = views[filters.view ?? 'all'] ?? views.all;
|
|
return (
|
|
<>
|
|
<Head title={view.title} />
|
|
<div className="mx-auto flex w-full max-w-7xl flex-col gap-7 p-5 lg:p-8">
|
|
<PageTitle
|
|
eyebrow="Compras"
|
|
title={view.title}
|
|
description={view.description}
|
|
action={
|
|
<Button asChild>
|
|
<Link href="/requisicoes/criar">
|
|
<Plus className="size-4" />
|
|
Nova requisição
|
|
</Link>
|
|
</Button>
|
|
}
|
|
/>
|
|
<Panel title="Pedidos de compra">
|
|
<form
|
|
className="mb-6 flex flex-wrap gap-3"
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
form.get('/requisicoes', { preserveState: true });
|
|
}}
|
|
>
|
|
<select
|
|
className={`${controlClass} max-w-60`}
|
|
aria-label="Conjunto de pedidos"
|
|
value={form.data.view}
|
|
onChange={(e) =>
|
|
form.setData('view', e.target.value)
|
|
}
|
|
>
|
|
<option value="all">Todas as autorizadas</option>
|
|
<option value="mine">Minhas requisições</option>
|
|
<option value="approvals">
|
|
Pendentes para mim
|
|
</option>
|
|
<option value="decided">Minhas decisões</option>
|
|
</select>
|
|
<Input
|
|
className="max-w-xs"
|
|
aria-label="Pesquisar pela referência"
|
|
placeholder="Pesquisar referência…"
|
|
value={form.data.search}
|
|
onChange={(e) =>
|
|
form.setData('search', e.target.value)
|
|
}
|
|
/>
|
|
<select
|
|
className={`${controlClass} max-w-48`}
|
|
aria-label="Filtrar por estado"
|
|
value={form.data.status}
|
|
onChange={(e) =>
|
|
form.setData('status', e.target.value)
|
|
}
|
|
>
|
|
<option value="">Todos os estados</option>
|
|
{Object.entries(statusLabels).map(
|
|
([key, label]) => (
|
|
<option key={key} value={key}>
|
|
{label}
|
|
</option>
|
|
),
|
|
)}
|
|
</select>
|
|
<Button variant="outline" disabled={form.processing}>
|
|
<Search className="size-4" />
|
|
Filtrar
|
|
</Button>
|
|
</form>
|
|
<RequisitionTable rows={requisitions.data} />
|
|
<div className="mt-5 flex flex-wrap items-center justify-between gap-3 border-t pt-4 text-sm text-muted-foreground">
|
|
<p>
|
|
{requisitions.total} pedidos · Página{' '}
|
|
{requisitions.current_page} de{' '}
|
|
{requisitions.last_page}
|
|
</p>
|
|
<div className="flex gap-2">
|
|
{requisitions.prev_page_url && (
|
|
<Button asChild variant="outline" size="sm">
|
|
<Link href={requisitions.prev_page_url}>
|
|
Anterior
|
|
</Link>
|
|
</Button>
|
|
)}
|
|
{requisitions.next_page_url && (
|
|
<Button asChild variant="outline" size="sm">
|
|
<Link href={requisitions.next_page_url}>
|
|
Seguinte
|
|
</Link>
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</Panel>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
Index.layout = {
|
|
breadcrumbs: [{ title: 'Requisições', href: '/requisicoes' }],
|
|
};
|