feat(F-109): completed feature

This commit is contained in:
chattie
2026-08-21 10:00:04 +02:00
parent 840c839f67
commit 673aa0f0d2
9 changed files with 85 additions and 68 deletions

View File

@@ -13,9 +13,6 @@ interface VariantRow {
editValue: string;
saving: boolean;
msg: string;
editingSku: boolean;
editSkuValue: string;
savingSku: boolean;
editingEan: boolean;
editEanValue: string;
savingEan: boolean;
@@ -79,9 +76,6 @@ export default function InventoryPage() {
editValue: '',
saving: false,
msg: '',
editingSku: false,
editSkuValue: '',
savingSku: false,
editingEan: false,
editEanValue: '',
savingEan: false,
@@ -120,19 +114,6 @@ export default function InventoryPage() {
useEffect(() => { load(); }, [load]);
// Save SKU inline
const handleSaveSku = async (variantId: string, productId: string, newSku: string) => {
if (!newSku.trim()) return;
setRows(prev => prev.map(r => r.variant.id === variantId ? { ...r, savingSku: true } : r));
try {
const updated = await productsApi.updateVariant(productId, variantId, { sku: newSku.trim() });
setRows(prev => prev.map(r => r.variant.id === variantId ? { ...r, variant: { ...r.variant, sku: updated.sku }, editingSku: false, savingSku: false, msg: '✓' } : r));
setTimeout(() => setRows(prev => prev.map(r => r.variant.id === variantId ? { ...r, msg: '' } : r)), 3000);
} catch {
setRows(prev => prev.map(r => r.variant.id === variantId ? { ...r, savingSku: false, msg: 'Error' } : r));
}
};
// Save EAN inline
const handleSaveEan = async (variantId: string, productId: string, newEan: string) => {
setRows(prev => prev.map(r => r.variant.id === variantId ? { ...r, savingEan: true } : r));
@@ -215,7 +196,7 @@ export default function InventoryPage() {
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-gray-900">Inventario</h1>
<p className="text-sm text-gray-500 mt-0.5">{rows.length} variantes</p>
<p className="text-sm text-gray-500 mt-0.5">{rows.length} productos</p>
</div>
</div>
@@ -289,7 +270,7 @@ export default function InventoryPage() {
) : filtered.length === 0 ? (
<div className="p-12 text-center">
<p className="text-4xl mb-3">📦</p>
<p className="text-gray-500 text-sm">No hay variantes para este filtro</p>
<p className="text-gray-500 text-sm">No hay productos para este filtro</p>
</div>
) : (
<div className="overflow-x-auto">
@@ -297,7 +278,6 @@ export default function InventoryPage() {
<thead>
<tr className="bg-gray-50 border-b border-gray-200 text-left">
<th className="px-4 py-3 font-semibold text-gray-600 text-xs uppercase tracking-wide">Producto</th>
<th className="px-4 py-3 font-semibold text-gray-600 text-xs uppercase tracking-wide">SKU</th>
<th className="px-4 py-3 font-semibold text-gray-600 text-xs uppercase tracking-wide">EAN</th>
<th className="px-4 py-3 font-semibold text-gray-600 text-xs uppercase tracking-wide">Stock</th>
<th className="px-4 py-3 font-semibold text-gray-600 text-xs uppercase tracking-wide">Estado</th>
@@ -309,27 +289,6 @@ export default function InventoryPage() {
<td className="px-4 py-3">
<p className="text-sm font-medium text-gray-900">{row.productName}</p>
</td>
<td className="px-4 py-3">
{row.editingSku ? (
<input
autoFocus
value={row.editSkuValue}
onChange={e => setRows(prev => prev.map(r => r.variant.id === row.variant.id ? { ...r, editSkuValue: e.target.value } : r))}
onBlur={() => handleSaveSku(row.variant.id, row.productId, row.editSkuValue)}
onKeyDown={e => { if (e.key === 'Enter') handleSaveSku(row.variant.id, row.productId, row.editSkuValue); if (e.key === 'Escape') setRows(prev => prev.map(r => r.variant.id === row.variant.id ? { ...r, editingSku: false } : r)); }}
disabled={row.savingSku}
className="w-full px-2 py-1 border border-[#2D6A4F] rounded text-xs focus:ring-1 focus:ring-[#2D6A4F] outline-none disabled:opacity-50"
/>
) : (
<button
onClick={() => setRows(prev => prev.map(r => r.variant.id === row.variant.id ? { ...r, editingSku: true, editSkuValue: row.variant.sku } : r))}
title="Clic para editar SKU"
className="font-mono text-xs text-gray-600 hover:text-[#2D6A4F] cursor-text text-left w-full truncate block disabled:opacity-50"
>
{row.variant.sku}
</button>
)}
</td>
<td className="px-4 py-3">
{row.editingEan ? (
<input

File diff suppressed because one or more lines are too long