Focus stock priorities on actionable diagnosis
This commit is contained in:
@@ -135,17 +135,17 @@ type DemandRow = ProductAnalyticsItem & {
|
||||
};
|
||||
|
||||
const demandQueueLabels: Record<DemandQueue, string> = {
|
||||
apparel: 'Cortar / Repor',
|
||||
apparel: 'Repor produtos',
|
||||
accessories: 'Repor acessórios',
|
||||
inputs: 'Comprar insumos',
|
||||
inputs: 'Insumos a comprar',
|
||||
review: 'Revisar dados',
|
||||
dead: 'Estoque parado',
|
||||
};
|
||||
|
||||
const demandQueueDescriptions: Record<DemandQueue, string> = {
|
||||
apparel: 'Produtos acabados com demanda ativa e cobertura abaixo da meta.',
|
||||
apparel: 'Diagnóstico de reposição de produtos acabados; o corte é definido no Plano de Corte.',
|
||||
accessories: 'Acessórios acabados com demanda ativa e cobertura abaixo da meta.',
|
||||
inputs: 'Embalagens, matérias-primas e insumos de produção com necessidade de reposição.',
|
||||
inputs: 'Embalagens, matérias-primas e insumos com necessidade comercial de reposição.',
|
||||
review: 'SKUs com informações pendentes para qualificar o planejamento.',
|
||||
dead: 'Itens com saldo disponível e baixa movimentação no período.',
|
||||
};
|
||||
@@ -600,7 +600,7 @@ const DemandPlanningScreen = () => {
|
||||
return (
|
||||
<div className={pageClassName}>
|
||||
<div className="grid grid-cols-1 gap-4 2xl:grid-cols-[minmax(520px,1fr)_auto] 2xl:items-start">
|
||||
<Header title="Planejamento Operacional" subtitle="Prioridades de reposição, compra e revisão calculadas por demanda, estoque e cobertura." backTo="/supplies" />
|
||||
<Header title="Prioridades de Estoque" subtitle="Diagnóstico de reposição, compra e dados. O Plano de Corte continua sendo a decisão de produção." backTo="/supplies" />
|
||||
<DateRangePicker
|
||||
dateRange={dateRange}
|
||||
onChange={(range) => {
|
||||
@@ -712,41 +712,37 @@ const DemandPlanningScreen = () => {
|
||||
) : queueRows.length ? (
|
||||
<div className="overflow-hidden rounded-2xl border border-dark-border bg-dark-card shadow-sm">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full min-w-[1080px] table-fixed border-collapse">
|
||||
<colgroup>
|
||||
<col className="w-[120px]" />
|
||||
<table className="w-full min-w-[860px] table-fixed border-collapse">
|
||||
<colgroup>
|
||||
<col />
|
||||
<col className="w-[140px]" />
|
||||
<col className="w-[120px]" />
|
||||
<col className="w-[120px]" />
|
||||
<col className="w-[120px]" />
|
||||
<col className="w-[130px]" />
|
||||
<col className="w-[100px]" />
|
||||
<col className="w-[140px]" />
|
||||
</colgroup>
|
||||
<thead className="border-b border-dark-border bg-dark-header text-xs font-bold uppercase tracking-widest text-dark-muted">
|
||||
<tr>
|
||||
<th scope="col" className="px-4 py-3 text-left">SKU</th>
|
||||
<th scope="col" className="px-4 py-3 text-left">Produto</th>
|
||||
<th scope="col" className="px-4 py-3 text-left">Tipo</th>
|
||||
<th scope="col" className="px-4 py-3 text-right">Média/dia</th>
|
||||
<th scope="col" className="px-4 py-3 text-right">Estoque</th>
|
||||
<th scope="col" className="px-4 py-3 text-right">Cobertura</th>
|
||||
<th scope="col" className="px-4 py-3 text-right">{queue === 'dead' ? 'Valor estoque' : 'Sugestão'}</th>
|
||||
<th scope="col" className="px-4 py-3 text-right">Ações</th>
|
||||
<th scope="col" className="px-4 py-3 text-right">Próximo passo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-dark-border">
|
||||
{paginatedRows.map(row => (
|
||||
<tr key={row.id} className="transition-colors hover:bg-dark-input/50">
|
||||
<td className="px-4 py-2.5 font-mono text-[11px] text-dark-muted">#{row.id}</td>
|
||||
<td className="px-4 py-2.5">
|
||||
<p className="truncate text-sm font-bold text-dark-text" title={row.name}>{row.name}</p>
|
||||
<p className="mt-1 truncate text-xs font-semibold text-dark-muted">
|
||||
Cor: {row.color || '-'} · Tam.: {row.size || '-'}
|
||||
<div className="mt-1 flex flex-wrap items-center gap-1.5">
|
||||
<span className="font-mono text-[10px] font-semibold text-dark-muted">#{row.id}</span>
|
||||
<ProductTypeBadge type={row.productType} />
|
||||
<span className="text-xs font-semibold text-dark-muted">Cor: {row.color || '-'} · Tam.: {row.size || '-'}</span>
|
||||
{row.missingData.length ? ` · Falta: ${row.missingData.join(', ')}` : ''}
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-4 py-2.5"><ProductTypeBadge type={row.productType} /></td>
|
||||
<td className="px-4 py-2.5 text-right text-sm font-bold text-dark-text">{formatNumber(row.dailySales, 2)}</td>
|
||||
<td className="px-4 py-2.5 text-right text-sm font-bold text-dark-text">{formatNumber(row.stock, 0)} un.</td>
|
||||
<td className="px-4 py-2.5 text-right text-sm font-bold text-dark-text">{formatDays(row.daysOfCover)}</td>
|
||||
@@ -757,24 +753,42 @@ const DemandPlanningScreen = () => {
|
||||
</td>
|
||||
<td className="px-4 py-2.5 text-right">
|
||||
<div className="flex justify-end gap-2">
|
||||
{queue === 'apparel' && (
|
||||
<RouterLink
|
||||
to="/cutting"
|
||||
className="inline-flex h-8 items-center gap-1.5 rounded-lg bg-brand-primary/10 px-2.5 text-xs font-bold text-brand-primary transition-opacity hover:opacity-80"
|
||||
title="Abrir Plano de Corte"
|
||||
>
|
||||
<Scissors className="h-3.5 w-3.5" /> Corte
|
||||
</RouterLink>
|
||||
)}
|
||||
{queue === 'inputs' && (
|
||||
<RouterLink
|
||||
to="/supplies/purchase-needs?tab=materials&filter=to_buy"
|
||||
className="inline-flex h-8 items-center gap-1.5 rounded-lg bg-brand-primary/10 px-2.5 text-xs font-bold text-brand-primary transition-opacity hover:opacity-80"
|
||||
title="Abrir Necessidade de Compra"
|
||||
>
|
||||
<BarChart3 className="h-3.5 w-3.5" /> Compra
|
||||
</RouterLink>
|
||||
)}
|
||||
{queue === 'review' && (
|
||||
<RouterLink
|
||||
to="/planning-issues"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-lg bg-dark-input text-dark-text transition-colors hover:bg-dark-border"
|
||||
className="inline-flex h-8 items-center gap-1.5 rounded-lg bg-dark-input px-2.5 text-xs font-bold text-dark-text transition-colors hover:bg-dark-border"
|
||||
title="Abrir dados pendentes"
|
||||
aria-label="Abrir dados pendentes"
|
||||
>
|
||||
<Pencil className="h-3.5 w-3.5" />
|
||||
<Pencil className="h-3.5 w-3.5" /> Corrigir
|
||||
</RouterLink>
|
||||
)}
|
||||
{queue !== 'apparel' && queue !== 'inputs' && queue !== 'review' && (
|
||||
<RouterLink
|
||||
to={`/products/${row.id}`}
|
||||
className="inline-flex h-8 items-center gap-1.5 rounded-lg bg-brand-primary/10 px-2.5 text-xs font-bold text-brand-primary transition-opacity hover:opacity-80"
|
||||
title={`Ver SKU ${row.id}`}
|
||||
>
|
||||
Ver produto <ArrowRight className="h-3.5 w-3.5" />
|
||||
</RouterLink>
|
||||
)}
|
||||
<RouterLink
|
||||
to={`/products/${row.id}`}
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-lg bg-brand-primary/10 text-brand-primary transition-opacity hover:opacity-80"
|
||||
title={`Ver SKU ${row.id}`}
|
||||
aria-label={`Ver SKU ${row.id}`}
|
||||
>
|
||||
<ArrowRight className="h-3.5 w-3.5" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user