bug fixed
This commit is contained in:
parent
24e3c9117b
commit
8dca1f0a84
@ -29,7 +29,7 @@ const createEmptyCodeForm = () => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Toast notification component
|
// Toast notification component
|
||||||
const Toast = ({ message, type = 'success', onClose, position = 'modal' }) => {
|
const Toast = ({ message, type = 'success', onClose, position = 'page' }) => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
onClose();
|
onClose();
|
||||||
@ -50,20 +50,10 @@ const Toast = ({ message, type = 'success', onClose, position = 'modal' }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// For modal toasts, we'll use relative positioning
|
|
||||||
if (position === 'modal') {
|
|
||||||
return (
|
|
||||||
<div className="w-full mb-4">
|
|
||||||
<div className={`px-4 py-2 rounded-md text-sm ${getToastStyles()}`}>
|
|
||||||
{message}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default page-level toast
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed top-0 left-0 w-full flex justify-center z-50 mt-4">
|
<div className={`fixed top-4 left-1/2 -translate-x-1/2 z-[9999] transition-all duration-300 ${
|
||||||
|
message ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-2 pointer-events-none'
|
||||||
|
}`}>
|
||||||
<div className={`px-6 py-3 rounded-md shadow-lg font-medium ${getToastStyles()}`}>
|
<div className={`px-6 py-3 rounded-md shadow-lg font-medium ${getToastStyles()}`}>
|
||||||
{message}
|
{message}
|
||||||
</div>
|
</div>
|
||||||
@ -72,14 +62,48 @@ const Toast = ({ message, type = 'success', onClose, position = 'modal' }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Import Modal Component
|
// Import Modal Component
|
||||||
const ImportModal = ({ isOpen, onClose, onImport }) => {
|
const ImportModal = ({ isOpen, onClose, onImport, showToast: showToastProp }) => {
|
||||||
const [file, setFile] = React.useState(null);
|
const [file, setFile] = React.useState(null);
|
||||||
const [dragActive, setDragActive] = React.useState(false);
|
const [dragActive, setDragActive] = React.useState(false);
|
||||||
const [loading, setLoading] = React.useState(false);
|
const [loading, setLoading] = React.useState(false);
|
||||||
const [error, setError] = React.useState('');
|
const [error, setError] = React.useState('');
|
||||||
|
const [toast, setToast] = React.useState({
|
||||||
|
show: false,
|
||||||
|
message: '',
|
||||||
|
type: 'success',
|
||||||
|
position: 'modal'
|
||||||
|
});
|
||||||
|
|
||||||
const fileInputRef = React.useRef(null);
|
const fileInputRef = React.useRef(null);
|
||||||
|
|
||||||
|
const showToast = (message, type = 'success', position = 'modal') => {
|
||||||
|
console.log('showToast called with:', { message, type, position });
|
||||||
|
|
||||||
|
// Always use local toast state for the modal
|
||||||
|
setToast(prev => {
|
||||||
|
console.log('Updating toast state');
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
show: true,
|
||||||
|
message,
|
||||||
|
type,
|
||||||
|
position
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auto-hide after delay
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
console.log('Hiding toast after timeout');
|
||||||
|
setToast(prev => ({ ...prev, show: false }));
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
return () => {
|
||||||
|
console.log('Cleaning up toast timeout');
|
||||||
|
clearTimeout(timer);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const handleDrag = (e) => {
|
const handleDrag = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -128,6 +152,7 @@ const ImportModal = ({ isOpen, onClose, onImport }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleImport = async () => {
|
const handleImport = async () => {
|
||||||
|
console.log('handleImport called');
|
||||||
if (!file) {
|
if (!file) {
|
||||||
setError('Please select a file to import');
|
setError('Please select a file to import');
|
||||||
return;
|
return;
|
||||||
@ -137,42 +162,33 @@ const ImportModal = ({ isOpen, onClose, onImport }) => {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError('');
|
setError('');
|
||||||
|
|
||||||
// Call the uploadCSV API from productService
|
console.log('Calling productService.uploadCSV');
|
||||||
const response = await productService.uploadCSV(file);
|
const response = await productService.uploadCSV(file);
|
||||||
|
console.log('Upload response:', response);
|
||||||
|
|
||||||
// Check the response status
|
// Check the response status
|
||||||
if (response.status === 'failed') {
|
if (response.status === 'failed') {
|
||||||
|
console.log('Import failed with response:', response);
|
||||||
let errorMsg = response.message || 'Import failed';
|
let errorMsg = response.message || 'Import failed';
|
||||||
|
|
||||||
// Add duplicate HS codes to the error message if they exist
|
if (response.summary?.errors?.length > 0) {
|
||||||
// if (response.duplicate_hs_codes_in_system?.length > 0) {
|
errorMsg += '\n\nErrors:';
|
||||||
// errorMsg += `\nDuplicate HS codes found: ${response.duplicate_hs_codes_in_system.join(', ')}`;
|
response.summary.errors.forEach(err => {
|
||||||
// }
|
errorMsg += `\nRow ${err.row}: ${err.error}`;
|
||||||
|
});
|
||||||
// // Show error summary if available
|
}
|
||||||
// if (response.summary) {
|
|
||||||
// errorMsg += `\nTotal records: ${response.summary.total_records}`;
|
|
||||||
// errorMsg += `\nImported: ${response.summary.imported}`;
|
|
||||||
// errorMsg += `\nSkipped: ${response.summary.skipped}`;
|
|
||||||
|
|
||||||
if (response.summary.errors?.length > 0) {
|
|
||||||
errorMsg += '\n\nErrors:';
|
|
||||||
response.summary.errors.forEach(err => {
|
|
||||||
errorMsg += `\nRow ${err.row}: ${err.error}`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setError(errorMsg);
|
setError(errorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the onImport callback with the response data
|
// Close the modal first
|
||||||
await onImport(response);
|
|
||||||
|
|
||||||
// Reset and close on success
|
|
||||||
setFile(null);
|
setFile(null);
|
||||||
onClose();
|
onClose();
|
||||||
|
|
||||||
|
// Then call onImport which will trigger the parent's success handling
|
||||||
|
console.log('Calling onImport');
|
||||||
|
await onImport(response);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error uploading CSV:', err);
|
console.error('Error uploading CSV:', err);
|
||||||
let errorMessage = 'Failed to import file. Please try again.';
|
let errorMessage = 'Failed to import file. Please try again.';
|
||||||
@ -206,27 +222,7 @@ const ImportModal = ({ isOpen, onClose, onImport }) => {
|
|||||||
onClose();
|
onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
// const downloadSampleCSV = () => {
|
|
||||||
// const sampleData = [
|
|
||||||
// ['HS Code', 'Product Name', 'Unit'],
|
|
||||||
// ['0101', 'Live Horses', 'kg'],
|
|
||||||
// ['0102', 'Live Bovine Animals', 'kg'],
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// const csvContent = sampleData.map(row =>
|
|
||||||
// row.map(field => `"${field}"`).join(',')
|
|
||||||
// ).join('\n');
|
|
||||||
|
|
||||||
// const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
||||||
// const url = URL.createObjectURL(blob);
|
|
||||||
// const link = document.createElement('a');
|
|
||||||
// link.href = url;
|
|
||||||
// link.setAttribute('download', 'hs-codes-sample.csv');
|
|
||||||
// document.body.appendChild(link);
|
|
||||||
// link.click();
|
|
||||||
// document.body.removeChild(link);
|
|
||||||
// URL.revokeObjectURL(url);
|
|
||||||
// };
|
|
||||||
const downloadSampleCSV = async () => {
|
const downloadSampleCSV = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await productService.downloadSampleFile();
|
const response = await productService.downloadSampleFile();
|
||||||
@ -272,6 +268,18 @@ const ImportModal = ({ isOpen, onClose, onImport }) => {
|
|||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="p-6 space-y-4">
|
<div className="p-6 space-y-4">
|
||||||
|
{/* Toast notification within modal */}
|
||||||
|
{toast.show && toast.position === 'modal' && (
|
||||||
|
<Toast
|
||||||
|
message={toast.message}
|
||||||
|
type={toast.type}
|
||||||
|
position="modal"
|
||||||
|
onClose={() => {
|
||||||
|
console.log('Toast onClose called');
|
||||||
|
setToast(prev => ({ ...prev, show: false }));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{/* File Upload Area */}
|
{/* File Upload Area */}
|
||||||
<div
|
<div
|
||||||
className={`border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors ${
|
className={`border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors ${
|
||||||
@ -393,7 +401,7 @@ const IsicHsCodes = () => {
|
|||||||
show: false,
|
show: false,
|
||||||
message: '',
|
message: '',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
position: 'modal' // 'page' or 'modal'
|
position: 'page' // 'page' or 'modal'
|
||||||
});
|
});
|
||||||
const [showImportModal, setShowImportModal] = React.useState(false);
|
const [showImportModal, setShowImportModal] = React.useState(false);
|
||||||
const [isRefreshing, setIsRefreshing] = React.useState(false);
|
const [isRefreshing, setIsRefreshing] = React.useState(false);
|
||||||
@ -693,11 +701,11 @@ const IsicHsCodes = () => {
|
|||||||
setModalMode('view');
|
setModalMode('view');
|
||||||
} else {
|
} else {
|
||||||
console.error('Invalid product data received from API');
|
console.error('Invalid product data received from API');
|
||||||
showToast('Failed to load product details', 'error');
|
setToast({ show: true, message: 'Failed to load product details', type: 'error' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching product details:', error);
|
console.error('Error fetching product details:', error);
|
||||||
showToast('Error loading product details', 'error');
|
setToast({ show: true, message: 'Error loading product details', type: 'error' });
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@ -734,11 +742,11 @@ const IsicHsCodes = () => {
|
|||||||
setModalMode('edit');
|
setModalMode('edit');
|
||||||
} else {
|
} else {
|
||||||
console.error('Empty response received from API');
|
console.error('Empty response received from API');
|
||||||
showToast('Failed to load product details for editing', 'error');
|
setToast({ show: true, message: 'Failed to load product details for editing', type: 'error' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching product details for edit:', error);
|
console.error('Error fetching product details for edit:', error);
|
||||||
showToast('Error loading product details for editing', 'error');
|
setToast({ show: true, message: 'Error loading product details for editing', type: 'error' });
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@ -752,7 +760,7 @@ const IsicHsCodes = () => {
|
|||||||
|
|
||||||
if (!selected || !selected.id) {
|
if (!selected || !selected.id) {
|
||||||
console.error('No product selected or missing ID');
|
console.error('No product selected or missing ID');
|
||||||
showToast('Cannot delete: Product information is incomplete', 'error');
|
setToast({ show: true, message: 'Cannot delete: Product information is incomplete', type: 'error' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,7 +786,7 @@ const IsicHsCodes = () => {
|
|||||||
setShowDeleteConfirm(true);
|
setShowDeleteConfirm(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error preparing product for deletion:', error);
|
console.error('Error preparing product for deletion:', error);
|
||||||
showToast('Error loading product details for deletion', 'error');
|
setToast({ show: true, message: 'Error loading product details for deletion', type: 'error' });
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@ -799,7 +807,7 @@ const IsicHsCodes = () => {
|
|||||||
if (deletingRowIndex === null || deletingRowIndex < 0 || deletingRowIndex >= rowsData.length) {
|
if (deletingRowIndex === null || deletingRowIndex < 0 || deletingRowIndex >= rowsData.length) {
|
||||||
const errorMsg = 'Invalid row selected for deletion';
|
const errorMsg = 'Invalid row selected for deletion';
|
||||||
console.error(errorMsg, { deletingRowIndex, rowsDataLength: rowsData.length });
|
console.error(errorMsg, { deletingRowIndex, rowsDataLength: rowsData.length });
|
||||||
showToast(errorMsg, 'error');
|
setToast({ show: true, message: errorMsg, type: 'error' });
|
||||||
setShowDeleteConfirm(false);
|
setShowDeleteConfirm(false);
|
||||||
setDeletingRowIndex(null);
|
setDeletingRowIndex(null);
|
||||||
return;
|
return;
|
||||||
@ -832,7 +840,7 @@ const IsicHsCodes = () => {
|
|||||||
newData.splice(deletingRowIndex, 1);
|
newData.splice(deletingRowIndex, 1);
|
||||||
setRowsData(newData);
|
setRowsData(newData);
|
||||||
|
|
||||||
showToast('Product deleted successfully!', 'success');
|
setToast({ show: true, message: 'Product deleted successfully!', type: 'success' });
|
||||||
} catch (apiError) {
|
} catch (apiError) {
|
||||||
console.error('API Error:', apiError);
|
console.error('API Error:', apiError);
|
||||||
if (apiError.response && apiError.response.status === 204) {
|
if (apiError.response && apiError.response.status === 204) {
|
||||||
@ -850,18 +858,18 @@ const IsicHsCodes = () => {
|
|||||||
newData.splice(deletingRowIndex, 1);
|
newData.splice(deletingRowIndex, 1);
|
||||||
setRowsData(newData);
|
setRowsData(newData);
|
||||||
|
|
||||||
showToast('Product deleted successfully!', 'success');
|
setToast({ show: true, message: 'Product deleted successfully!', type: 'success' });
|
||||||
} else {
|
} else {
|
||||||
const errorMessage = apiError.response?.data?.message || 'Failed to delete product. Please try again.';
|
const errorMessage = apiError.response?.data?.message || 'Failed to delete product. Please try again.';
|
||||||
setError(errorMessage);
|
setError(errorMessage);
|
||||||
showToast(errorMessage, 'error');
|
setToast({ show: true, message: errorMessage, type: 'error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in delete process:', error);
|
console.error('Error in delete process:', error);
|
||||||
const errorMessage = error.message || 'An unexpected error occurred';
|
const errorMessage = error.message || 'An unexpected error occurred';
|
||||||
setError(errorMessage);
|
setError(errorMessage);
|
||||||
showToast(errorMessage, 'error');
|
setToast({ show: true, message: errorMessage, type: 'error' });
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
setShowDeleteConfirm(false);
|
setShowDeleteConfirm(false);
|
||||||
@ -886,8 +894,8 @@ const IsicHsCodes = () => {
|
|||||||
setForm(createEmptyCodeForm());
|
setForm(createEmptyCodeForm());
|
||||||
};
|
};
|
||||||
|
|
||||||
const showToast = (message, type = 'success', position = 'modal') => {
|
const showToast = (message, type = 'success') => {
|
||||||
setToast({ show: true, message, type, position });
|
setToast({ show: true, message, type });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setToast(prev => ({ ...prev, show: false }));
|
setToast(prev => ({ ...prev, show: false }));
|
||||||
}, 3000);
|
}, 3000);
|
||||||
@ -905,7 +913,7 @@ const IsicHsCodes = () => {
|
|||||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
await new Promise(resolve => setTimeout(resolve, 1500));
|
||||||
|
|
||||||
// Show success message
|
// Show success message
|
||||||
showToast('HS Codes imported successfully! New codes appear in the list.', 'success');
|
setToast({ show: true, message: 'HS Codes imported successfully! New codes appear in the list.', type: 'success' });
|
||||||
|
|
||||||
// In a real implementation, you would:
|
// In a real implementation, you would:
|
||||||
// 1. Call your import API endpoint
|
// 1. Call your import API endpoint
|
||||||
@ -913,7 +921,7 @@ const IsicHsCodes = () => {
|
|||||||
// 3. Update the rowsData state with the new data
|
// 3. Update the rowsData state with the new data
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showToast('Failed to import CSV file. Please try again.', 'error');
|
setToast({ show: true, message: 'Failed to import CSV file. Please try again.', type: 'error' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -945,14 +953,14 @@ const IsicHsCodes = () => {
|
|||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
|
|
||||||
showToast('CSV exported successfully!', 'success');
|
setToast({ show: true, message: 'CSV exported successfully!', type: 'success' });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveForm = async () => {
|
const handleSaveForm = async () => {
|
||||||
if (!form.code || !form.product) {
|
if (!form.code || !form.product) {
|
||||||
const errorMsg = 'Please fill in all required fields';
|
const errorMsg = 'Please fill in all required fields';
|
||||||
console.error(errorMsg);
|
console.error(errorMsg);
|
||||||
showToast(errorMsg, 'error');
|
setToast({ show: true, message: errorMsg, type: 'error' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -996,7 +1004,7 @@ const IsicHsCodes = () => {
|
|||||||
if (!productId) {
|
if (!productId) {
|
||||||
const errorMsg = 'Cannot update product: Product ID not found';
|
const errorMsg = 'Cannot update product: Product ID not found';
|
||||||
console.error(errorMsg);
|
console.error(errorMsg);
|
||||||
showToast(errorMsg, 'error');
|
setToast({ show: true, message: errorMsg, type: 'error' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1040,7 +1048,7 @@ const IsicHsCodes = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Show success message and reload the page after a short delay
|
// Show success message and reload the page after a short delay
|
||||||
showToast('Product updated successfully!', 'success');
|
setToast({ show: true, message: 'Product updated successfully!', type: 'success' });
|
||||||
closeModal();
|
closeModal();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
@ -1052,7 +1060,7 @@ const IsicHsCodes = () => {
|
|||||||
if (error.response?.data?.message) {
|
if (error.response?.data?.message) {
|
||||||
errorMessage = error.response.data.message;
|
errorMessage = error.response.data.message;
|
||||||
}
|
}
|
||||||
showToast(errorMessage, 'error');
|
setToast({ show: true, message: errorMessage, type: 'error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1077,7 +1085,7 @@ const IsicHsCodes = () => {
|
|||||||
|
|
||||||
setRowsData(prev => [newProduct, ...prev]);
|
setRowsData(prev => [newProduct, ...prev]);
|
||||||
setFilteredData(prev => [newProduct, ...prev]);
|
setFilteredData(prev => [newProduct, ...prev]);
|
||||||
showToast('Product created successfully!', 'success');
|
setToast({ show: true, message: 'Product created successfully!', type: 'success' });
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
// Reload the page after a short delay to reflect changes
|
// Reload the page after a short delay to reflect changes
|
||||||
@ -1090,7 +1098,7 @@ const IsicHsCodes = () => {
|
|||||||
if (createError.response?.data?.message) {
|
if (createError.response?.data?.message) {
|
||||||
errorMessage = createError.response.data.message;
|
errorMessage = createError.response.data.message;
|
||||||
}
|
}
|
||||||
showToast(errorMessage, 'error');
|
setToast({ show: true, message: errorMessage, type: 'error' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in handleSaveForm:', error);
|
console.error('Error in handleSaveForm:', error);
|
||||||
@ -1172,20 +1180,12 @@ const IsicHsCodes = () => {
|
|||||||
|
|
||||||
setRowsData(formattedData);
|
setRowsData(formattedData);
|
||||||
setFilteredData(formattedData);
|
setFilteredData(formattedData);
|
||||||
|
setToast({ show: true, message: 'HS Codes imported successfully!', type: 'success' });
|
||||||
}
|
}
|
||||||
|
|
||||||
setToast({
|
} catch (error) {
|
||||||
show: true,
|
console.error('Error refreshing HS codes:', error);
|
||||||
message: 'Data imported successfully!',
|
setToast({ show: true, message: 'Failed to refresh HS codes', type: 'error' });
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error refreshing product list:', err);
|
|
||||||
setToast({
|
|
||||||
show: true,
|
|
||||||
message: 'Data imported but failed to refresh the list. ' + (err.response?.data?.message || 'Please refresh the page manually.'),
|
|
||||||
type: 'error'
|
|
||||||
});
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsRefreshing(false);
|
setIsRefreshing(false);
|
||||||
}
|
}
|
||||||
@ -1194,12 +1194,11 @@ const IsicHsCodes = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
{/* Page-level toasts */}
|
{/* Page-level toasts */}
|
||||||
{toast.show && toast.position === 'page' && (
|
{toast.show && (
|
||||||
<Toast
|
<Toast
|
||||||
message={toast.message}
|
message={toast.message}
|
||||||
type={toast.type}
|
type={toast.type}
|
||||||
position="page"
|
onClose={() => setToast(prev => ({ ...prev, show: false }))}
|
||||||
onClose={() => setToast(prev => ({ ...prev, show: false }))}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -1207,7 +1206,10 @@ const IsicHsCodes = () => {
|
|||||||
<ImportModal
|
<ImportModal
|
||||||
isOpen={showImportModal}
|
isOpen={showImportModal}
|
||||||
onClose={() => setShowImportModal(false)}
|
onClose={() => setShowImportModal(false)}
|
||||||
onImport={handleImportSuccess}
|
onImport={(response) => {
|
||||||
|
handleImportSuccess(response);
|
||||||
|
setToast({ show: true, message: 'HS Codes imported successfully!', type: 'success' });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="bg-white w-full rounded-lg shadow-sm ring-1 ring-[#E5E7EB]">
|
<div className="bg-white w-full rounded-lg shadow-sm ring-1 ring-[#E5E7EB]">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user