Align supply material actions
This commit is contained in:
@@ -2110,23 +2110,14 @@ const AffectedProducts = ({ products }: { products: SupplyPurchaseNeed['products
|
||||
<div className="mt-3 flex flex-wrap items-center gap-2 border-t border-dark-border/70 pt-3">
|
||||
<span className="text-[10px] font-bold uppercase tracking-widest text-dark-muted">Produtos afetados</span>
|
||||
{products.slice(0, 3).map(product => (
|
||||
<div key={product.productId} className="flex max-w-full items-center overflow-hidden rounded-md border border-dark-border bg-dark-input">
|
||||
<RouterLink
|
||||
to={`/products/${product.productId}`}
|
||||
className="min-w-0 cursor-pointer truncate px-2 py-1 text-[11px] font-bold text-dark-muted transition-colors hover:text-brand-primary"
|
||||
title={product.name}
|
||||
>
|
||||
#{product.productId} · {product.name}
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to={`/products/${product.productId}`}
|
||||
className="flex h-7 w-7 shrink-0 items-center justify-center border-l border-dark-border text-brand-primary transition-colors hover:bg-brand-primary/10"
|
||||
title={`Ver produto ${product.name}`}
|
||||
aria-label={`Ver produto ${product.name}`}
|
||||
>
|
||||
<Eye className="h-3.5 w-3.5" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
<RouterLink
|
||||
key={product.productId}
|
||||
to={`/products/${product.productId}`}
|
||||
className="max-w-full cursor-pointer truncate rounded-md border border-dark-border bg-dark-input px-2 py-1 text-[11px] font-bold text-dark-muted transition-colors hover:border-brand-primary hover:text-brand-primary"
|
||||
title={product.name}
|
||||
>
|
||||
#{product.productId} · {product.name}
|
||||
</RouterLink>
|
||||
))}
|
||||
{products.length > 3 && <span className="text-xs font-bold text-dark-muted">+{products.length - 3} SKUs</span>}
|
||||
</div>
|
||||
@@ -2136,10 +2127,11 @@ const AffectedProducts = ({ products }: { products: SupplyPurchaseNeed['products
|
||||
const PurchaseMaterialQueue = ({ needs, onEditMaterial }: { needs: SupplyPurchaseNeed[]; onEditMaterial: (need: SupplyPurchaseNeed) => void }) => (
|
||||
<>
|
||||
<div className="border-b border-dark-border bg-dark-input/40 px-4 py-3">
|
||||
<div className="grid gap-3 text-[10px] font-bold uppercase tracking-widest text-dark-muted xl:grid-cols-[minmax(300px,1.35fr)_minmax(380px,1fr)_150px]">
|
||||
<span>Material e impacto</span>
|
||||
<div className="grid gap-3 text-[10px] font-bold uppercase tracking-widest text-dark-muted xl:grid-cols-[minmax(280px,1.35fr)_minmax(380px,1fr)_150px_88px]">
|
||||
<span>Material</span>
|
||||
<span className="hidden xl:block">Como a compra foi calculada</span>
|
||||
<span className="hidden text-right xl:block">Decisão</span>
|
||||
<span className="hidden text-right xl:block">Impacto</span>
|
||||
<span className="hidden text-right xl:block">Ações</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="divide-y divide-dark-border">
|
||||
@@ -2166,7 +2158,7 @@ const PurchaseMaterialQueue = ({ needs, onEditMaterial }: { needs: SupplyPurchas
|
||||
|
||||
return (
|
||||
<article key={need.material} className={`border-l-2 ${accent} px-4 py-4 transition-colors hover:bg-dark-input/35`}>
|
||||
<div className="grid gap-4 xl:grid-cols-[minmax(300px,1.35fr)_minmax(380px,1fr)_150px] xl:items-center">
|
||||
<div className="grid gap-4 xl:grid-cols-[minmax(280px,1.35fr)_minmax(380px,1fr)_150px_88px] xl:items-center">
|
||||
<div className="min-w-0">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<h3 className="text-sm font-bold text-dark-text">{getNeedDisplayName(need)}</h3>
|
||||
@@ -2202,15 +2194,25 @@ const PurchaseMaterialQueue = ({ needs, onEditMaterial }: { needs: SupplyPurchas
|
||||
<p className="text-[10px] font-bold uppercase tracking-widest text-dark-muted">Impacto</p>
|
||||
<p className="mt-1 text-sm font-bold text-dark-text">{products.length} {products.length === 1 ? 'SKU' : 'SKUs'} dependem</p>
|
||||
<p className="mt-1 text-xs font-semibold text-dark-muted">{formatNumber(sumNeedProducts(need, 'suggestedQuantity'))} un. planejadas</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 xl:justify-self-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onEditMaterial(need)}
|
||||
className="mt-3 inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg border border-dark-border bg-dark-input text-sky-300 transition-colors hover:border-sky-400/50 hover:bg-sky-400/10"
|
||||
className="inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-dark-input text-dark-text transition-colors hover:bg-dark-border"
|
||||
title={`Editar dados de ${getNeedDisplayName(need)}`}
|
||||
aria-label={`Editar dados de ${getNeedDisplayName(need)}`}
|
||||
>
|
||||
<Pencil className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
<RouterLink
|
||||
to={getMaterialRegistrationPath(need.material)}
|
||||
className="inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-brand-primary/10 text-brand-primary transition-opacity hover:opacity-80"
|
||||
title={`Ver cadastro de ${getNeedDisplayName(need)}`}
|
||||
aria-label={`Ver cadastro de ${getNeedDisplayName(need)}`}
|
||||
>
|
||||
<Eye className="h-3.5 w-3.5" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2225,10 +2227,11 @@ const PurchaseMaterialQueue = ({ needs, onEditMaterial }: { needs: SupplyPurchas
|
||||
const PurchaseServiceQueue = ({ needs, onEditMaterial }: { needs: SupplyPurchaseNeed[]; onEditMaterial: (need: SupplyPurchaseNeed) => void }) => (
|
||||
<>
|
||||
<div className="border-b border-dark-border bg-dark-input/40 px-4 py-3">
|
||||
<div className="grid gap-3 text-[10px] font-bold uppercase tracking-widest text-dark-muted xl:grid-cols-[minmax(320px,1.4fr)_minmax(260px,1fr)_180px]">
|
||||
<span>Serviço e impacto</span>
|
||||
<div className="grid gap-3 text-[10px] font-bold uppercase tracking-widest text-dark-muted xl:grid-cols-[minmax(300px,1.4fr)_minmax(260px,1fr)_150px_88px]">
|
||||
<span>Serviço</span>
|
||||
<span className="hidden xl:block">Volume a programar</span>
|
||||
<span className="hidden text-right xl:block">Próximo passo</span>
|
||||
<span className="hidden text-right xl:block">Impacto</span>
|
||||
<span className="hidden text-right xl:block">Ações</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="divide-y divide-dark-border">
|
||||
@@ -2238,7 +2241,7 @@ const PurchaseServiceQueue = ({ needs, onEditMaterial }: { needs: SupplyPurchase
|
||||
|
||||
return (
|
||||
<article key={need.material} className={`border-l-2 ${isCovered ? 'border-l-emerald-400' : 'border-l-sky-400'} px-4 py-4 transition-colors hover:bg-dark-input/35`}>
|
||||
<div className="grid gap-4 xl:grid-cols-[minmax(320px,1.4fr)_minmax(260px,1fr)_180px] xl:items-center">
|
||||
<div className="grid gap-4 xl:grid-cols-[minmax(300px,1.4fr)_minmax(260px,1fr)_150px_88px] xl:items-center">
|
||||
<div className="min-w-0">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<h3 className="text-sm font-bold text-dark-text">{getNeedDisplayName(need)}</h3>
|
||||
@@ -2268,15 +2271,25 @@ const PurchaseServiceQueue = ({ needs, onEditMaterial }: { needs: SupplyPurchase
|
||||
<p className="text-[10px] font-bold uppercase tracking-widest text-dark-muted">Impacto</p>
|
||||
<p className="mt-1 text-sm font-bold text-dark-text">{products.length} {products.length === 1 ? 'SKU' : 'SKUs'} dependem</p>
|
||||
<p className="mt-1 text-xs font-semibold text-dark-muted">{formatNumber(sumNeedProducts(need, 'suggestedQuantity'))} un. planejadas</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 xl:justify-self-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onEditMaterial(need)}
|
||||
className="mt-3 inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg border border-dark-border bg-dark-input text-sky-300 transition-colors hover:border-sky-400/50 hover:bg-sky-400/10"
|
||||
className="inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-dark-input text-dark-text transition-colors hover:bg-dark-border"
|
||||
title={`Editar dados de ${getNeedDisplayName(need)}`}
|
||||
aria-label={`Editar dados de ${getNeedDisplayName(need)}`}
|
||||
>
|
||||
<Pencil className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
<RouterLink
|
||||
to={getMaterialRegistrationPath(need.material)}
|
||||
className="inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-brand-primary/10 text-brand-primary transition-opacity hover:opacity-80"
|
||||
title={`Ver cadastro de ${getNeedDisplayName(need)}`}
|
||||
aria-label={`Ver cadastro de ${getNeedDisplayName(need)}`}
|
||||
>
|
||||
<Eye className="h-3.5 w-3.5" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2293,6 +2306,12 @@ const getMaterialRegistrationSku = (material: string) => {
|
||||
return /^[A-Z0-9_-]{2,}$/i.test(candidate) ? candidate : '';
|
||||
};
|
||||
|
||||
const getMaterialRegistrationPath = (material: string) => buildSkuEditPath({
|
||||
sku: getMaterialRegistrationSku(material),
|
||||
name: material,
|
||||
type: 'raw_material',
|
||||
});
|
||||
|
||||
const MaterialDetailsModal = ({
|
||||
need,
|
||||
onClose,
|
||||
@@ -2309,11 +2328,7 @@ const MaterialDetailsModal = ({
|
||||
});
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const registrationPath = buildSkuEditPath({
|
||||
sku: getMaterialRegistrationSku(need.material),
|
||||
name: need.material,
|
||||
type: 'raw_material',
|
||||
});
|
||||
const registrationPath = getMaterialRegistrationPath(need.material);
|
||||
|
||||
const submit = async (event: FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user