Fix upc validation api call

This commit is contained in:
2025-03-05 22:08:50 -05:00
parent 36a5186c17
commit bc5607f48c
4 changed files with 73 additions and 57 deletions

View File

@@ -37,38 +37,6 @@ const ValidationIcon = React.memo(({ error }: { error: ErrorObject }) => (
ValidationIcon.displayName = 'ValidationIcon';
// Separate component for item number cells to ensure they update independently
const ItemNumberCell = React.memo(({
value,
itemNumber,
isValidating,
width
}: {
value: any,
itemNumber?: string,
isValidating?: boolean,
width: number
}) => (
<TableCell className="p-1" style={{ width: `${width}px`, minWidth: `${width}px` }}>
<div className="px-2 py-1 text-sm">
{isValidating ? (
<div className="flex items-center gap-2">
<Loader2 className="h-4 w-4 animate-spin text-blue-500" />
<span>{itemNumber || value || ''}</span>
</div>
) : (
<span>{itemNumber || value || ''}</span>
)}
</div>
</TableCell>
), (prev, next) => (
prev.value === next.value &&
prev.itemNumber === next.itemNumber &&
prev.isValidating === next.isValidating
));
ItemNumberCell.displayName = 'ItemNumberCell';
// Memoized base cell content component
const BaseCellContent = React.memo(({
field,
@@ -143,6 +111,66 @@ export interface ValidationCellProps {
rowIndex: number
}
const ItemNumberCell = React.memo(({
value,
itemNumber,
isValidating,
width,
errors = [],
field,
onChange
}: {
value: any,
itemNumber?: string,
isValidating?: boolean,
width: number,
errors?: ErrorObject[],
field: Field<string>,
onChange: (value: any) => void
}) => {
const hasError = errors.some(error => error.level === 'error' || error.level === 'warning');
const isRequiredButEmpty = errors.some(error => error.level === 'required' && (!value || value.trim() === ''));
const nonRequiredErrors = errors.filter(error => error.level !== 'required');
return (
<TableCell className="p-1" style={{ width: `${width}px`, minWidth: `${width}px` }}>
<div className={`relative ${hasError || isRequiredButEmpty ? 'border-red-500' : ''}`}>
{isValidating ? (
<div className="flex items-center justify-center gap-2">
<Loader2 className="h-4 w-4 animate-spin text-blue-500" />
<span>{itemNumber || value || ''}</span>
</div>
) : (
<div className="truncate overflow-hidden">
<BaseCellContent
field={field}
value={itemNumber || value}
onChange={onChange}
hasErrors={hasError || isRequiredButEmpty}
options={[]}
/>
</div>
)}
{nonRequiredErrors.length > 0 && !isRequiredButEmpty && (
<div className="absolute right-2 top-1/2 -translate-y-1/2 z-20">
<ValidationIcon error={{
message: nonRequiredErrors.map(e => e.message).join('\n'),
level: 'error'
}} />
</div>
)}
</div>
</TableCell>
);
}, (prev, next) => (
prev.value === next.value &&
prev.itemNumber === next.itemNumber &&
prev.isValidating === next.isValidating &&
JSON.stringify(prev.errors) === JSON.stringify(next.errors)
));
ItemNumberCell.displayName = 'ItemNumberCell';
const ValidationCell = ({
field,
value,
@@ -161,14 +189,13 @@ const ValidationCell = ({
itemNumber={itemNumber}
isValidating={isValidating}
width={width}
errors={errors}
field={field}
onChange={onChange}
/>
);
}
// For UPC fields, show loading indicator during validation
const isUpcField = fieldKey === 'upc' || fieldKey === 'barcode';
const showLoadingIndicator = isUpcField && isValidating;
// Error states
const hasError = errors.some(error => error.level === 'error' || error.level === 'warning');
const isRequiredButEmpty = errors.some(error => error.level === 'required' && (!value || value.trim() === ''));
@@ -176,12 +203,8 @@ const ValidationCell = ({
return (
<TableCell className="p-1" style={{ width: `${width}px`, minWidth: `${width}px` }}>
<div className={`relative ${hasError || isRequiredButEmpty ? 'border-red-500' : ''} ${showLoadingIndicator ? 'border-blue-500' : ''}`}>
{showLoadingIndicator && (
<div className="absolute right-2 top-1/2 -translate-y-1/2 z-10">
<Loader2 className="h-4 w-4 animate-spin text-blue-500" />
</div>
)}
<div className={`relative ${hasError || isRequiredButEmpty ? 'border-red-500' : ''}`}>
<div className="truncate overflow-hidden">
<BaseCellContent
@@ -220,15 +243,6 @@ export default React.memo(ValidationCell, (prev, next) => {
);
}
// For UPC fields, include validation state in comparison
if (prev.fieldKey === 'upc' || prev.fieldKey === 'barcode') {
return (
prev.value === next.value &&
prevErrorsStr === nextErrorsStr &&
prev.isValidating === next.isValidating
);
}
// For all other fields, compare core props
return (
prev.value === next.value &&

View File

@@ -10,6 +10,7 @@ import { ProductSearchDialog } from '@/components/products/ProductSearchDialog'
import SearchableTemplateSelect from './SearchableTemplateSelect'
import { useAiValidation } from '../hooks/useAiValidation'
import { AiValidationDialogs } from './AiValidationDialogs'
import config from '@/config'
/**
* ValidationContainer component - the main wrapper for the validation step
@@ -187,7 +188,7 @@ const ValidationContainer = <T extends string>({
}
// Make API call to validate UPC
const response = await fetch(`/api/import/check-upc-and-generate-sku?upc=${encodeURIComponent(upcValue)}&supplierId=${encodeURIComponent(supplierId)}`);
const response = await fetch(`${config.apiUrl}/import/check-upc-and-generate-sku?upc=${encodeURIComponent(upcValue)}&supplierId=${encodeURIComponent(supplierId)}`);
// Process the response
if (response.status === 409) {

View File

@@ -1,4 +1,5 @@
import { useState, useCallback, useRef } from 'react'
import config from '@/config'
interface UpcValidationResult {
error?: boolean
@@ -67,7 +68,7 @@ export const useUpcValidation = () => {
try {
// Call the UPC validation API
const response = await fetch(`/api/import/check-upc-and-generate-sku?upc=${encodeURIComponent(upcValue)}&supplierId=${encodeURIComponent(supplier)}`);
const response = await fetch(`${config.apiUrl}/import/check-upc-and-generate-sku?upc=${encodeURIComponent(upcValue)}&supplierId=${encodeURIComponent(supplier)}`);
if (response.status === 409) {
const errorData = await response.json();

View File

@@ -76,7 +76,7 @@ declare global {
}
// Use a helper to get API URL consistently
export const getApiUrl = () => window.config?.apiUrl || '/api';
export const getApiUrl = () => config.apiUrl;
// Main validation state hook
export const useValidationState = <T extends string>({
@@ -125,7 +125,7 @@ export const useValidationState = <T extends string>({
const fetchProductByUpc = useCallback(async (supplier: string, upc: string): Promise<ValidationResult> => {
try {
// Use the correct endpoint and parameter names
const response = await fetch(`${getApiUrl()}/check-upc-and-generate-sku?supplierId=${encodeURIComponent(supplier)}&upc=${encodeURIComponent(upc)}`, {
const response = await fetch(`${getApiUrl()}/import/check-upc-and-generate-sku?supplierId=${encodeURIComponent(supplier)}&upc=${encodeURIComponent(upc)}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
@@ -224,7 +224,7 @@ export const useValidationState = <T extends string>({
}
// Make API call to validate UPC
const response = await fetch(`/api/import/check-upc-and-generate-sku?upc=${encodeURIComponent(upcValue)}&supplierId=${encodeURIComponent(supplierId)}`);
const response = await fetch(`${config.apiUrl}/import/check-upc-and-generate-sku?upc=${encodeURIComponent(upcValue)}&supplierId=${encodeURIComponent(supplierId)}`);
if (response.status === 409) {
// UPC already exists - show validation error