feat(F-091): completed feature

This commit is contained in:
chattie
2026-08-20 21:47:31 +02:00
parent d29c9b71c9
commit 4d0970df5d
12 changed files with 204 additions and 61 deletions

View File

@@ -1,7 +1,7 @@
'use client';
import { useState, useEffect } from 'react';
import { useState, useEffect, useRef } from 'react';
import { productsApi, inventoryApi, pricingApi } from '@/lib/api-client';
import type { ProductVariant, VariantPrice, StockAvailability } from '@/types';
import { ApiError, type ProductVariant, type VariantPrice, type StockAvailability } from '@/types';
interface VariantRow {
variant: ProductVariant;
@@ -75,6 +75,7 @@ export function InventorySection({ productId }: InventorySectionProps) {
const [rows, setRows] = useState<Record<string, VariantRow>>({});
const [savingVariant, setSavingVariant] = useState<string | null>(null);
const [saveMsg, setSaveMsg] = useState<Record<string, string>>({});
const savingCodes = useRef(new Set<string>());
// Load variants
useEffect(() => {
@@ -307,6 +308,9 @@ export function InventorySection({ productId }: InventorySectionProps) {
}));
return;
}
const saveKey = `sku:${variantId}`;
if (savingCodes.current.has(saveKey)) return;
savingCodes.current.add(saveKey);
setRows((prev) => ({ ...prev, [variantId]: { ...r, savingSku: true } }));
setSaveMsg((prev) => ({ ...prev, [variantId]: '' }));
try {
@@ -323,12 +327,17 @@ export function InventorySection({ productId }: InventorySectionProps) {
}));
setSaveMsg((prev) => ({ ...prev, [variantId]: '✓ Guardado' }));
setTimeout(() => setSaveMsg((prev) => ({ ...prev, [variantId]: '' })), 3000);
} catch {
setSaveMsg((prev) => ({ ...prev, [variantId]: 'Error' }));
} catch (error) {
const message = error instanceof ApiError && error.statusCode === 409
? 'El SKU ya existe en otra variante'
: 'No se pudo guardar el SKU';
setSaveMsg((prev) => ({ ...prev, [variantId]: message }));
setRows((prev) => ({
...prev,
[variantId]: { ...prev[variantId], editingSku: false, savingSku: false, skuValue: prev[variantId].variant.sku },
}));
} finally {
savingCodes.current.delete(saveKey);
}
};
@@ -342,6 +351,9 @@ export function InventorySection({ productId }: InventorySectionProps) {
}));
return;
}
const saveKey = `ean:${variantId}`;
if (savingCodes.current.has(saveKey)) return;
savingCodes.current.add(saveKey);
setRows((prev) => ({ ...prev, [variantId]: { ...r, savingEan: true } }));
setSaveMsg((prev) => ({ ...prev, [variantId]: '' }));
try {
@@ -358,12 +370,17 @@ export function InventorySection({ productId }: InventorySectionProps) {
}));
setSaveMsg((prev) => ({ ...prev, [variantId]: '✓ Guardado' }));
setTimeout(() => setSaveMsg((prev) => ({ ...prev, [variantId]: '' })), 3000);
} catch {
setSaveMsg((prev) => ({ ...prev, [variantId]: 'Error' }));
} catch (error) {
const message = error instanceof ApiError && error.statusCode === 409
? 'El EAN ya existe en otra variante'
: 'No se pudo guardar el EAN';
setSaveMsg((prev) => ({ ...prev, [variantId]: message }));
setRows((prev) => ({
...prev,
[variantId]: { ...prev[variantId], editingEan: false, savingEan: false, eanValue: prev[variantId].variant.ean ?? '' },
}));
} finally {
savingCodes.current.delete(saveKey);
}
};