This commit is contained in:
Malini 2026-02-06 12:48:28 +05:30
parent 34ebb5d622
commit 63c7fb461d
4 changed files with 74 additions and 37 deletions

View File

@ -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>

View File

@ -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>
)}

View File

@ -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"

View File

@ -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>