Files
compras/resources/js/pages/dashboard.tsx
T
2026-10-30 20:14:24 +02:00

197 lines
8.4 KiB
TypeScript

import { Head, Link, usePage } from '@inertiajs/react';
import {
ArrowRight,
CheckCheck,
ClipboardList,
Clock3,
Plus,
Wallet,
} from 'lucide-react';
import { PageTitle, Panel, RequisitionTable } from '@/components/procurement';
import { Button } from '@/components/ui/button';
import { money } from '@/types/procurement';
import type { Company, Requisition } from '@/types/procurement';
type Props = {
company: Company | null;
stats: {
total: number;
pending: number;
approved: number;
approvedMinor: number;
awaitingMe: number;
};
recent: Requisition[];
approvals: Requisition[];
};
export default function Dashboard({
company,
stats,
recent,
approvals,
}: Props) {
const canRequest = usePage().props.canRequest === true;
const publicNavigation = !!usePage().props.publicNavigation;
const cards = [
{
label: 'Requisições',
value: stats.total,
icon: ClipboardList,
detail: 'Total de pedidos visíveis',
},
{
label: 'Em aprovação',
value: stats.pending,
icon: Clock3,
detail: `${stats.awaitingMe} aguardam a sua decisão`,
},
{
label: 'Aprovadas',
value: stats.approved,
icon: CheckCheck,
detail: 'Todas as etapas concluídas',
},
{
label: 'Valor aprovado',
value: money(Number(stats.approvedMinor)),
icon: Wallet,
detail: 'Estimativa em MZN, com IVA',
},
];
return (
<>
<Head title="Visão geral" />
<div className="mx-auto flex w-full max-w-7xl flex-col gap-7 p-5 lg:p-8">
<PageTitle
eyebrow={company?.name ?? 'Bem-vindo ao SGC'}
title="Visão geral das compras"
description="Acompanhe os pedidos, as aprovações e a actividade da sua empresa."
action={
!publicNavigation &&
(!company || canRequest) && (
<Button
asChild
className="bg-teal-700 text-white hover:bg-teal-800"
>
<Link
href={
company
? '/requisicoes/criar'
: '/empresa/iniciar'
}
>
<Plus className="size-4" />
{company
? 'Nova requisição'
: 'Configurar empresa'}
</Link>
</Button>
)
}
/>
{!company && !publicNavigation ? (
<Panel
title="Vamos configurar a sua empresa"
description="Crie a organização e o primeiro departamento. Depois pode adicionar a equipa e começar a registar pedidos."
>
<Button asChild>
<Link href="/empresa/iniciar">
Começar configuração{' '}
<ArrowRight className="size-4" />
</Link>
</Button>
</Panel>
) : (
<>
<div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
{cards.map((card) => (
<div
key={card.label}
className="rounded-xl border bg-card p-5 shadow-xs"
>
<div className="flex items-center justify-between text-sm text-muted-foreground">
<span>{card.label}</span>
<card.icon className="size-4 text-teal-700 dark:text-teal-400" />
</div>
<p className="mt-5 text-2xl font-semibold tracking-tight">
{card.value}
</p>
<p className="mt-2 text-xs text-muted-foreground">
{card.detail}
</p>
</div>
))}
</div>
{company?.rules_provisional && (
<div className="rounded-xl border border-amber-200 bg-amber-50 px-5 py-4 text-sm text-amber-900 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100">
<strong>
Ambiente de desenvolvimento · regras
provisórias.
</strong>{' '}
Escalões de {money(company.first_limit_minor)} e{' '}
{money(company.second_limit_minor)}, calculados{' '}
{company.approval_includes_tax ? 'com' : 'sem'}{' '}
IVA. Os parâmetros precisam de validação antes
de compras reais.
</div>
)}
{approvals.length > 0 && (
<Panel
title="À espera da sua aprovação"
description="Abra um pedido para conferir os artigos e registar a decisão."
>
<div className="divide-y">
{approvals.map((r) => (
<Link
key={r.id}
href={`/requisicoes/${r.id}`}
className="flex items-center justify-between gap-4 py-3"
>
<div>
<p className="font-medium">
{r.number}
</p>
<p className="mt-1 line-clamp-1 text-sm text-muted-foreground">
{r.justification}
</p>
</div>
<span className="flex shrink-0 items-center gap-3 text-sm font-medium">
{money(r.total_minor)}
<ArrowRight className="size-4" />
</span>
</Link>
))}
</div>
</Panel>
)}
<Panel
title="Requisições recentes"
description="Últimos pedidos disponíveis para o seu perfil."
>
<RequisitionTable rows={recent} />
<div className="mt-4 border-t pt-4">
<Link
href="/requisicoes"
className="inline-flex items-center gap-2 text-sm font-medium text-teal-700 dark:text-teal-400"
>
Ver todas as requisições{' '}
<ArrowRight className="size-4" />
</Link>
</div>
</Panel>
</>
)}
</div>
</>
);
}
Dashboard.layout = {
breadcrumbs: [
{
title: 'Visão geral',
href: '/dashboard',
},
],
};