Files
compras/resources/js/pages/preview/principal.tsx
T

267 lines
13 KiB
TypeScript

import { Head, Link } from '@inertiajs/react';
import {
ArrowRight,
CheckCheck,
ChevronDown,
ClipboardList,
Clock3,
Plus,
Wallet,
} from 'lucide-react';
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
const href = (screen: string) =>
screen.startsWith('?') ? `/consulta${screen}` : `/consulta/${screen}`;
const requests = [
{
number: 'REQ-DEMO-024',
description: 'Material de escritório',
department: 'Administração',
amount: '24 500,00 MT',
status: 'Em aprovação',
},
{
number: 'REQ-DEMO-023',
description: 'Peças para manutenção',
department: 'Produção',
amount: '86 200,00 MT',
status: 'Aprovada',
},
{
number: 'REQ-DEMO-022',
description: 'Consumíveis de limpeza',
department: 'Operações',
amount: '12 800,00 MT',
status: 'Rascunho',
},
];
export default function PrincipalProposal() {
const [filter, setFilter] = useState('Todos os estados');
const visible = requests.filter(
(request) => filter === 'Todos os estados' || request.status === filter,
);
return (
<>
<Head title="Proposta de ecrã principal" />
<div className="min-h-screen bg-slate-50 text-slate-900">
<div className="mx-auto flex max-w-7xl flex-col gap-7 px-5 py-8 lg:px-8 lg:py-10">
<section className="flex flex-wrap items-end justify-between gap-5">
<div>
<p className="text-xs font-semibold tracking-widest text-red-700 uppercase">
O seu espaço de trabalho
</p>
<h1 className="mt-2 text-3xl font-semibold tracking-tight">
As compras, numa só vista.
</h1>
<p className="mt-3 max-w-xl text-sm leading-6 text-slate-500">
Veja o que precisa da sua atenção e avance para
a próxima tarefa.
</p>
</div>
<Button
asChild
className="bg-[#ed1c24] text-white hover:bg-[#b91c1c]"
>
<Link href="/consulta/requisicoes">
<Plus className="size-4" />
Explorar requisições
</Link>
</Button>
</section>
<section
aria-label="Indicadores de demonstração"
className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4"
>
{[
{
label: 'Requisições',
value: '24',
detail: 'Pedidos neste exemplo',
icon: ClipboardList,
},
{
label: 'Em aprovação',
value: '6',
detail: '2 aguardam a sua decisão',
icon: Clock3,
},
{
label: 'Aprovadas',
value: '15',
detail: 'Com circuito concluído',
icon: CheckCheck,
},
{
label: 'Valor aprovado',
value: '428 500 MT',
detail: 'Estimativa de demonstração, com IVA',
icon: Wallet,
},
].map((card) => (
<div
key={card.label}
className="rounded-2xl border border-slate-200 bg-white p-5 shadow-xs"
>
<div className="flex items-center justify-between text-sm text-slate-500">
{card.label}
<card.icon className="size-4 text-red-700" />
</div>
<p className="mt-5 text-3xl font-semibold tracking-tight">
{card.value}
</p>
<p className="mt-2 text-xs text-slate-500">
{card.detail}
</p>
</div>
))}
</section>
<div className="grid items-start gap-6 lg:grid-cols-[minmax(0,1fr)_320px]">
<section className="overflow-hidden rounded-2xl border border-slate-200 bg-white">
<div className="flex flex-wrap items-center justify-between gap-4 border-b border-slate-100 p-5">
<div>
<h2 className="font-semibold">
Requisições recentes
</h2>
<p className="mt-1 text-xs text-slate-400">
Exemplos para avaliar a organização do
ecrã
</p>
</div>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="outline"
size="sm"
className="border-slate-200 bg-white text-slate-700"
>
{filter}
<ChevronDown className="size-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{[
'Todos os estados',
'Em aprovação',
'Aprovada',
'Rascunho',
].map((status) => (
<DropdownMenuItem
key={status}
onSelect={() =>
setFilter(status)
}
>
{status}
{filter === status && (
<CheckCheck className="ml-auto size-4" />
)}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</div>
<div className="divide-y divide-slate-100">
{visible.map((request) => (
<Link
key={request.number}
href="/consulta/requisicoes"
className="flex flex-wrap items-center justify-between gap-4 p-5 transition-colors hover:bg-slate-50"
>
<div>
<p className="text-xs font-medium text-red-700">
{request.number}
</p>
<p className="mt-1 text-sm font-medium">
{request.description}
</p>
<p className="mt-1 text-xs text-slate-400">
{request.department}
</p>
</div>
<div className="text-right">
<p className="text-sm font-semibold">
{request.amount}
</p>
<span
className={`mt-2 inline-flex rounded-full px-2.5 py-1 text-xs ${request.status === 'Aprovada' ? 'bg-red-50 text-[#ed1c24]' : request.status === 'Em aprovação' ? 'bg-amber-50 text-amber-800' : 'bg-slate-100 text-slate-600'}`}
>
{request.status}
</span>
</div>
</Link>
))}
</div>
<Link
href="/consulta/requisicoes"
className="flex items-center justify-center gap-2 border-t border-slate-100 p-4 text-sm font-medium text-[#ed1c24]"
>
Ver todas as requisições
<ArrowRight className="size-4" />
</Link>
</section>
<aside className="flex flex-col gap-5">
<section className="rounded-2xl border-t-4 border-[#ed1c24] bg-[#090909] p-6 text-white">
<span className="inline-flex rounded-xl bg-white/10 p-2.5">
<Clock3 className="size-5" />
</span>
<h2 className="mt-4 text-lg font-semibold">
A sua atenção faz a diferença
</h2>
<p className="mt-2 text-sm leading-6 text-slate-200">
Neste exemplo, 2 pedidos aguardam a sua
decisão. Consulte os detalhes antes de
aprovar.
</p>
<Button
asChild
className="mt-5 w-full bg-white text-[#b91c1c] hover:bg-red-50"
>
<Link href="/consulta/requisicoes">
Consultar pedidos
<ArrowRight className="size-4" />
</Link>
</Button>
</section>
<section className="rounded-2xl border border-slate-200 bg-white p-5">
<h2 className="font-semibold">
Acessos rápidos
</h2>
<div className="mt-3 space-y-1">
{[
['Conferir entregas', 'recepcoes'],
[
'Consultar reforços',
'?ecra=reinforcements',
],
[
'Encontrar fornecedor',
'fornecedores',
],
].map(([label, screen]) => (
<Link
key={screen}
href={href(screen)}
className="flex items-center justify-between rounded-lg py-3 text-sm text-slate-600 hover:bg-slate-50 hover:text-[#ed1c24]"
>
{label}
<ArrowRight className="size-4" />
</Link>
))}
</div>
</section>
</aside>
</div>
</div>
</div>
</>
);
}