Refocus cutting plan table
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Link, useOutletContext, useSearchParams } from 'react-router-dom';
|
||||
import { AlertTriangle, ArrowLeft, ClipboardList, Download, Eye, Layers3, Pencil, RotateCcw, Ruler, Save as SaveIcon, Scissors, Search, Settings2, X } from 'lucide-react';
|
||||
import { AlertTriangle, ArrowLeft, ClipboardList, Download, Layers3, Pencil, RotateCcw, Ruler, Save as SaveIcon, Scissors, Search, Settings2, X } from 'lucide-react';
|
||||
import DateRangePicker from '../components/DateRangePicker';
|
||||
import PaginationControls from '../components/PaginationControls';
|
||||
import ProductColorBadge from '../components/ProductColorBadge';
|
||||
@@ -668,7 +668,7 @@ const Cutting = () => {
|
||||
const renderCutStatus = (row: CutPlanSkuRow) => {
|
||||
const readiness = materialReadinessByProductId.get(row.id);
|
||||
if (readiness?.status === 'ready') {
|
||||
return <span className="inline-flex rounded-full border border-emerald-400/30 bg-emerald-400/10 px-2.5 py-1 text-xs font-bold text-emerald-300">Pronto para cortar</span>;
|
||||
return <span className="inline-flex h-2.5 w-2.5 rounded-full bg-emerald-400 shadow-[0_0_0_4px_rgba(52,211,153,0.10)]" title="Pronto para cortar" aria-label="Pronto para cortar" />;
|
||||
}
|
||||
if (readiness?.status === 'material_ready') {
|
||||
return <span className="inline-flex max-w-full items-center gap-1.5 rounded-full border border-amber-400/30 bg-amber-400/10 px-2.5 py-1 text-xs font-bold text-amber-300" title={row.issues.map(issue => issueLabels[issue]).join(', ')}><AlertTriangle className="h-3.5 w-3.5 shrink-0" /><span className="truncate">Dados pendentes</span></span>;
|
||||
@@ -1355,30 +1355,31 @@ const Cutting = () => {
|
||||
) : (
|
||||
<div className={`overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-dark-border dark:bg-dark-card ${isRefreshing ? 'refreshing-content' : ''}`} aria-busy={isRefreshing}>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full min-w-[940px] table-fixed text-left text-sm">
|
||||
<table className="w-full min-w-[900px] table-fixed text-left text-sm">
|
||||
<colgroup>
|
||||
<col className="w-[380px]" />
|
||||
<col className="w-[120px]" />
|
||||
<col className="w-[120px]" />
|
||||
<col className="w-[140px]" />
|
||||
<col className="w-[220px]" />
|
||||
<col className="w-[100px]" />
|
||||
<col className="w-[40%]" />
|
||||
<col className="w-[15%]" />
|
||||
<col className="w-[25%]" />
|
||||
<col className="w-[12%]" />
|
||||
<col className="w-[8%]" />
|
||||
</colgroup>
|
||||
<thead className="border-b border-zinc-100 bg-zinc-50 text-zinc-500 dark:border-dark-border dark:bg-dark-header dark:text-dark-muted">
|
||||
<thead className="sticky top-0 z-10 border-b border-zinc-100 bg-zinc-50 text-zinc-500 dark:border-dark-border dark:bg-dark-header dark:text-dark-muted">
|
||||
<tr>
|
||||
<th className="px-4 py-4 text-[10px] font-bold uppercase tracking-wider">Produto</th>
|
||||
<th className="px-4 py-4 text-[10px] font-bold uppercase tracking-wider">Demanda</th>
|
||||
<th className="px-4 py-4 text-[10px] font-bold uppercase tracking-wider">Estoque</th>
|
||||
<th className="px-4 py-4 text-[10px] font-bold uppercase tracking-wider">Necessidade</th>
|
||||
<th className="px-4 py-4 text-[10px] font-bold uppercase tracking-wider">Situação para corte</th>
|
||||
<th className="px-4 py-4 text-[10px] font-bold uppercase tracking-wider">Cortar agora</th>
|
||||
<th className="px-4 py-4 text-[10px] font-bold uppercase tracking-wider">Demanda / disponível</th>
|
||||
<th className="px-4 py-4 text-center text-[10px] font-bold uppercase tracking-wider">Status</th>
|
||||
<th className="px-4 py-4 text-right text-[10px] font-bold uppercase tracking-wider">Ações</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-zinc-100 dark:divide-dark-border">
|
||||
{paginatedRows.map(row => (
|
||||
<tr key={row.id} className="transition-colors hover:bg-zinc-50/80 dark:hover:bg-dark-input/50">
|
||||
{paginatedRows.map(row => {
|
||||
const readiness = materialReadinessByProductId.get(row.id);
|
||||
const needsAttention = readiness?.status !== 'ready';
|
||||
return (
|
||||
<tr key={row.id} className={`transition-colors hover:bg-zinc-50/80 dark:hover:bg-dark-input/50 ${needsAttention ? 'border-l-2 border-amber-400/70' : ''}`}>
|
||||
<td className="max-w-0 px-4 py-2.5">
|
||||
<div className="truncate font-semibold text-zinc-900 dark:text-dark-text" title={row.name}>{row.name}</div>
|
||||
<Link to={`/products/${row.id}`} className="block truncate font-semibold text-zinc-900 transition-colors hover:text-brand-primary dark:text-dark-text" title={`Ver ${row.name}`}>{row.name}</Link>
|
||||
<div className="mt-1 flex flex-wrap items-center gap-1.5">
|
||||
<span className="font-mono text-[10px] font-medium text-zinc-400 dark:text-dark-muted">#{row.id}</span>
|
||||
<span className={`inline-flex rounded-full border px-2 py-0.5 text-[10px] font-bold ${familyStyles[row.family.key]}`}>{row.family.materialLabel}</span>
|
||||
@@ -1387,21 +1388,17 @@ const Cutting = () => {
|
||||
</div>
|
||||
<div className="mt-1 text-[10px] font-medium text-zinc-400 dark:text-dark-muted">Média: {formatNumber(row.dailySales, 2)} un./dia · Cobertura: {formatDays(row.daysOfCover)}</div>
|
||||
</td>
|
||||
<td className="px-4 py-2.5 font-bold whitespace-nowrap text-zinc-900 dark:text-dark-text">{formatNumber(row.projectedDemand, 1)} un.</td>
|
||||
<td className="px-4 py-2.5 whitespace-nowrap">
|
||||
<div className="font-bold text-zinc-900 dark:text-dark-text">{formatNumber(row.stock)} un.</div>
|
||||
{!!row.openProductionQuantity && (
|
||||
<div className="text-[10px] font-semibold text-dark-muted">Disp. {formatNumber(row.availableQuantity)} un.</div>
|
||||
)}
|
||||
<div className="text-lg font-bold text-red-300">{formatNumber(row.suggestedCutQuantity)} un.</div>
|
||||
<div className="mt-1 text-[10px] font-semibold text-dark-muted">necessidade calculada</div>
|
||||
</td>
|
||||
<td className="px-4 py-2.5 whitespace-nowrap">
|
||||
<span className={row.suggestedCutQuantity > 0 ? 'font-bold text-red-300' : 'font-bold text-emerald-300'}>
|
||||
{formatNumber(row.suggestedCutQuantity)} un.
|
||||
</span>
|
||||
<div className="text-sm font-bold text-dark-text">Demanda {formatNumber(row.projectedDemand, 1)} un.</div>
|
||||
<div className="mt-1 text-xs font-semibold text-dark-muted">Disponível {formatNumber(row.availableQuantity)} un.{row.openProductionQuantity ? ` · ${formatNumber(row.openProductionQuantity)} em OP` : ''}</div>
|
||||
</td>
|
||||
<td className="px-4 py-2.5 align-middle">{renderCutStatus(row)}</td>
|
||||
<td className="px-4 py-2.5 text-center align-middle">{renderCutStatus(row)}</td>
|
||||
<td className="px-4 py-2.5 text-right">
|
||||
<div className="flex justify-end gap-2">
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => openQuickCutEdit(row)}
|
||||
@@ -1411,18 +1408,10 @@ const Cutting = () => {
|
||||
>
|
||||
<Pencil className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
<Link
|
||||
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}`}
|
||||
>
|
||||
<Eye className="h-3.5 w-3.5" />
|
||||
</Link>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
)})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user