fix
This commit is contained in:
parent
34ebb5d622
commit
63c7fb461d
@ -433,7 +433,7 @@ const handleDeleteDraft = async (e, submission) => {
|
||||
handleDeleteDraft(e, draftToDelete);
|
||||
setShowDeleteConfirm(false);
|
||||
}}
|
||||
className="px-4 py-2 bg-[#B52520] text-white rounded-md hover:bg-[#9D1F1B] focus:outline-none"
|
||||
className="px-4 py-2 bg-[#92722A] text-white rounded-md hover:bg-[#A88632] focus:outline-none"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
|
||||
@ -395,7 +395,8 @@ const ProductData = ({
|
||||
const [showDataDefinitions, setShowDataDefinitions] = React.useState(true);
|
||||
const [showEntryRules, setShowEntryRules] = React.useState(true);
|
||||
const [showInfoCard, setShowInfoCard] = React.useState(true);
|
||||
const MAX_PRODUCTS = 10;
|
||||
const [availableProductsCount, setAvailableProductsCount] = React.useState(0);
|
||||
const [maxProducts, setMaxProducts] = React.useState(0);
|
||||
const nextId = React.useRef(products.length + 1);
|
||||
const [variationReasons, setVariationReasons] = React.useState([]);
|
||||
const [isLoadingReasons, setIsLoadingReasons] = React.useState(false);
|
||||
@ -407,6 +408,7 @@ const ProductData = ({
|
||||
const [isLoadingProducts, setIsLoadingProducts] = React.useState(false);
|
||||
const [productsError, setProductsError] = React.useState('');
|
||||
const [showDraftSaved, setShowDraftSaved] = React.useState(false);
|
||||
const MAX_PRODUCTS = maxProducts;
|
||||
// Remove the unused state variables since we'll use the props directly
|
||||
const [unitOptions, setUnitOptions] = React.useState([]);
|
||||
const [isLoadingUnits, setIsLoadingUnits] = React.useState(false);
|
||||
@ -1439,42 +1441,64 @@ useEffect(() => {
|
||||
}
|
||||
};
|
||||
|
||||
// Check if there are any products available to add
|
||||
// Get the total number of unique products available
|
||||
const getAvailableProductsCount = () => {
|
||||
try {
|
||||
const currentSubmissionStr = localStorage.getItem('currentSubmission');
|
||||
let submittedProductIds = [];
|
||||
let submittedProductIds = new Set();
|
||||
|
||||
// Get submitted product IDs from current submission
|
||||
if (currentSubmissionStr) {
|
||||
const currentSubmission = JSON.parse(currentSubmissionStr);
|
||||
if (currentSubmission.products && Array.isArray(currentSubmission.products)) {
|
||||
submittedProductIds = currentSubmission.products
|
||||
.filter(p => p.product_id)
|
||||
.map(p => p.product_id.toString());
|
||||
currentSubmission.products.forEach(p => {
|
||||
if (p.product_id) submittedProductIds.add(p.product_id.toString());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get all product IDs that are already selected in the current form
|
||||
const selectedProductIds = products
|
||||
.filter(p => p.product)
|
||||
.map(p => p.product.toString());
|
||||
// Get all unique product options
|
||||
const allProductOptions = new Map();
|
||||
productOptions.forEach(option => {
|
||||
const id = option.originalData?.product_id?.toString() || option.value;
|
||||
if (id && !allProductOptions.has(id)) {
|
||||
allProductOptions.set(id, option);
|
||||
}
|
||||
});
|
||||
|
||||
// Count how many products are available to add
|
||||
const availableProducts = productOptions.filter(option =>
|
||||
!submittedProductIds.includes(option.value) &&
|
||||
!selectedProductIds.includes(option.value) &&
|
||||
!submittedProductIds.includes(option.originalData?.product_id?.toString())
|
||||
// Get selected product IDs from current form
|
||||
const selectedProductIds = new Set(
|
||||
products
|
||||
.filter(p => p.product)
|
||||
.map(p => p.product.toString())
|
||||
);
|
||||
|
||||
return availableProducts.length;
|
||||
// Count available products (total unique products - submitted - selected)
|
||||
let availableCount = 0;
|
||||
for (const [id, option] of allProductOptions.entries()) {
|
||||
if (!submittedProductIds.has(id) && !selectedProductIds.has(option.value)) {
|
||||
availableCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return availableCount;
|
||||
} catch (error) {
|
||||
console.error('Error checking available products:', error);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
const availableProductsCount = getAvailableProductsCount();
|
||||
const canAddMoreProducts = products.length < MAX_PRODUCTS && availableProductsCount > 0;
|
||||
// Update availableProductsCount and maxProducts when products or options change
|
||||
React.useEffect(() => {
|
||||
const count = getAvailableProductsCount();
|
||||
const totalAvailable = productOptions.length;
|
||||
|
||||
setAvailableProductsCount(count);
|
||||
// Set max products to the total number of available products
|
||||
setMaxProducts(totalAvailable);
|
||||
}, [products, productOptions]);
|
||||
|
||||
const canAddMoreProducts = products.length < maxProducts && availableProductsCount > 0;
|
||||
|
||||
const isLoading = loading || isLoadingReasons || isLoadingZeroReasons || isLoadingProducts || isLoadingUnits;
|
||||
const hasError = error || reasonsError || zeroReasonsError || productsError || unitsError;
|
||||
@ -1659,21 +1683,21 @@ useEffect(() => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={addProduct}
|
||||
disabled={!canAddMoreProducts || isLoading}
|
||||
className={`inline-flex items-center gap-2 text-sm font-medium px-3 py-2 rounded ${
|
||||
!canAddMoreProducts || isLoading
|
||||
? 'bg-gray-200 text-gray-500 cursor-not-allowed'
|
||||
: 'bg-[#92722A] text-white cursor-pointer hover:bg-[#9e782f]'
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
onClick={addProduct}
|
||||
disabled={!canAddMoreProducts || isLoading}
|
||||
className={`inline-flex items-center gap-2 text-sm font-medium px-3 py-2 rounded ${
|
||||
!canAddMoreProducts || isLoading
|
||||
? 'bg-gray-200 text-gray-500 cursor-not-allowed'
|
||||
: 'bg-[#92722A] text-white cursor-pointer hover:bg-[#9e782f]'
|
||||
}`}
|
||||
>
|
||||
<span>+ Add Product</span>
|
||||
</button>
|
||||
{!canAddMoreProducts && (
|
||||
<span className="text-xs text-gray-600">
|
||||
{products.length >= MAX_PRODUCTS
|
||||
? `Maximum of ${MAX_PRODUCTS} products reached.`
|
||||
? 'No more products available to add.'
|
||||
: 'No more products available to add.'}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@ -523,7 +523,18 @@ const QuarterlyWindows = () => {
|
||||
};
|
||||
|
||||
const handleFormChange = (field) => (value) => {
|
||||
setForm(prev => ({ ...prev, [field]: value }));
|
||||
setForm(prev => {
|
||||
// If year is being changed, reset the date fields
|
||||
if (field === 'year' && prev.year !== value) {
|
||||
return {
|
||||
...prev,
|
||||
[field]: value,
|
||||
startDate: '',
|
||||
endDate: ''
|
||||
};
|
||||
}
|
||||
return { ...prev, [field]: value };
|
||||
});
|
||||
|
||||
// Clear validation error when user starts typing
|
||||
if (validationErrors[field]) {
|
||||
@ -940,7 +951,8 @@ const QuarterlyWindows = () => {
|
||||
}
|
||||
value={form.startDate}
|
||||
required
|
||||
minDate={new Date().toISOString().split('T')[0]}
|
||||
minDate={form.year ? `${form.year}-01-01` : new Date().toISOString().split('T')[0]}
|
||||
maxDate={form.year ? `${form.year}-12-31` : undefined}
|
||||
onChange={(e) => handleFormChange('startDate')(e.target.value)}
|
||||
placeholder="Select Date"
|
||||
error={validationErrors.startDate}
|
||||
@ -960,7 +972,8 @@ const QuarterlyWindows = () => {
|
||||
}
|
||||
value={form.endDate}
|
||||
required
|
||||
minDate={form.startDate || new Date().toISOString().split('T')[0]}
|
||||
minDate={form.startDate || (form.year ? `${form.year}-01-01` : new Date().toISOString().split('T')[0])}
|
||||
maxDate={form.year ? `${form.year}-12-31` : undefined}
|
||||
onChange={(e) => handleFormChange('endDate')(e.target.value)}
|
||||
placeholder="Select Date"
|
||||
error={validationErrors.endDate}
|
||||
@ -977,8 +990,8 @@ const QuarterlyWindows = () => {
|
||||
label="Grace Period (Days)"
|
||||
value={form.gracePeriod}
|
||||
onChange={(e) => handleFormChange('gracePeriod')(e.target.value)}
|
||||
options={['5 days', '10 days', '15 days', '20 days', '30 days'].map((item) => ({
|
||||
label: item,
|
||||
options={['0 day', '5 days', '10 days', '15 days', '20 days', '30 days'].map((item) => ({
|
||||
label: item === '0 day' ? 'No Grace Period' : item,
|
||||
value: item,
|
||||
}))}
|
||||
placeholder="Select Grace Period"
|
||||
|
||||
@ -11,7 +11,7 @@ const downloadIconSrc = '/assets/images/DownloadSimple.svg';
|
||||
const pencilActiveSrc = '/assets/images/PencilSimple.svg';
|
||||
const pencilInactiveSrc = '/assets/images/pencilsimple-inactive.svg';
|
||||
import CustomToast from '@/components/common/CustomToast';
|
||||
const deleteIconSrc = '/assets/images/Trash - active.svg';
|
||||
const trashActiveSrc = '/assets/images/Trash - active.svg';
|
||||
const trashInactiveSrc = '/assets/images/Trash - Inactive.svg';
|
||||
import { deleteDraftSubmission } from '@/services/submissions/submissionService';
|
||||
import { HiMiniArrowPathRoundedSquare } from 'react-icons/hi2';
|
||||
@ -207,7 +207,7 @@ const showToast = (message, type = 'success') => {
|
||||
onMouseLeave={() => setHoveredDelete(null)}
|
||||
>
|
||||
<img
|
||||
src={hoveredDelete === record.id ? deleteIconSrc : trashInactiveSrc}
|
||||
src={hoveredDelete === record.id ? trashInactiveSrc : trashActiveSrc}
|
||||
alt="Delete"
|
||||
className="h-5 w-5 transition-colors"
|
||||
/>
|
||||
@ -465,7 +465,7 @@ const showToast = (message, type = 'success') => {
|
||||
e.stopPropagation();
|
||||
confirmDeleteDraft();
|
||||
}}
|
||||
className="px-4 py-2 bg-[#B52520] text-white rounded-md hover:bg-[#9D1F1B] focus:outline-none"
|
||||
className="px-4 py-2 bg-[#92722A] text-white rounded-md hover:bg-[#A88632] focus:outline-none"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user