added resumit flow and changes in quaterly surveys

This commit is contained in:
Malini 2026-02-06 14:29:29 +05:30
parent 63c7fb461d
commit a24a4064e7
5 changed files with 278 additions and 47 deletions

View File

@ -159,12 +159,60 @@ export const SubmissionHistory = ({ history = [], loading = false, error = '' })
const pageSize = 10;
const navigate = useNavigate();
const handleViewDetails = (submission) => {
navigate('/overview', { state: { selectedSubmission: submission } });
};
const handleResubmit = async (submission) => {
try {
const response = await fetchSubmissionDetail(submission.id);
const submissionData = response.data;
// Structure the data in the format expected by the component
const formattedData = {
...submissionData,
establishment: {
...submissionData.establishment,
establishment_contact_email: submissionData.establishment.establishment_contact_email,
emirate: submissionData.establishment.establishment_emirate_id,
establishment_emirate_id: submissionData.establishment.establishment_emirate_id
},
employeeInfo: {
emiratiMale: submissionData.establishment.emirati_male,
emiratiFemale: submissionData.establishment.emirati_female,
nonEmiratiMale: submissionData.establishment.non_emirati_male,
nonEmiratiFemale: submissionData.establishment.non_emirati_female,
totalEmirati: submissionData.establishment.total_emirati,
totalEmployees: submissionData.establishment.total_employees
},
products: submissionData.products || [],
quarterWindow: submissionData.quarter_window || {}
};
// Save the complete data to localStorage
localStorage.setItem('resubmissionData', JSON.stringify(formattedData));
// Save products separately
if (submissionData.products && submissionData.products.length > 0) {
localStorage.setItem('submissionProducts', JSON.stringify(submissionData.products));
}
// Set resubmission flags
localStorage.setItem('isResubmission', 'true');
// Navigate to survey with resubmission state
navigate('/survey', {
state: {
submission: formattedData,
isResubmit: true,
fromResubmit: true
}
});
} catch (error) {
console.error('Error fetching submission details:', error);
showToast('Failed to load submission for resubmission', 'error');
}
};
const handleEdit = async (submission) => {
if (submission.status.toLowerCase() === 'draft') {
try {

View File

@ -52,7 +52,7 @@ const ProductDetails = ({
bgColor: 'bg-red-50',
textColor: 'text-red-600',
iconColor: 'text-red-500',
message: 'Your survey has been rejected. Please review and resubmit.',
message: 'Your survey has been rejected.',
icon: '/assets/images/Vector-rejected.svg',
iconAlt: 'Rejected',
iconClassName: 'mr-2 h-5 w-5 flex-shrink-0'
@ -357,8 +357,8 @@ const ProductDetails = ({
}}
className="ml-auto px-3 py-1 bg-[#FEF2F2] text-[#7C2320] text-sm font-medium rounded hover:bg-[#FEF2F2] transition-colors"
>
Resubmit
<img src="/assets/images/arrow-right-bold 1.svg" alt="" className="w-4 h-4 ml-1 inline-block" />
{/* Resubmit */}
{/* <img src="/assets/images/arrow-right-bold 1.svg" alt="" className="w-4 h-4 ml-1 inline-block" /> */}
</button>
)}
</div>

View File

@ -338,41 +338,40 @@ const EstablishmentInfo = ({
};
// Store establishment data in localStorage during resubmission
React.useEffect(() => {
// Check if this is a resubmission
const isResubmit = location.state?.fromResubmit;
if (isResubmit && data) {
try {
// Get existing resubmission data if it exists
const existingData = JSON.parse(localStorage.getItem('resubmissionData') || '{}');
// Update with establishment data
const updatedData = {
...existingData,
establishment: {
id: data.establishmentId,
name: data.establishmentName,
permanent_factory_code: data.permanentFactoryCode,
industry_code: data.industryCode,
license_number: data.licenseNumber,
isic_code: data.isicCode,
emirate: data.emirate,
establishment_contact_email: data.establishment_contact_email,
employeeInfo: data.employeeInfo || {}
},
// Ensure quarter and year are included
quarter: data.quarter || surveyData.quarter,
year: data.year || surveyData.year
};
// Save back to localStorage
localStorage.setItem('resubmissionData', JSON.stringify(updatedData));
} catch (error) {
console.error('Error updating resubmission data with establishment info:', error);
}
// Store establishment data in localStorage during resubmission
React.useEffect(() => {
const isResubmit = location.state?.fromResubmit;
if (isResubmit) {
try {
const resubmissionData = JSON.parse(localStorage.getItem('resubmissionData') || '{}');
const establishmentData = resubmissionData.establishment || {};
// Update the form with the resubmission data
onChange({
...data,
establishmentId: establishmentData.id,
establishmentName: establishmentData.factory_name,
permanentFactoryCode: establishmentData.permanent_factory_code,
industryCode: establishmentData.industry_code,
licenseNumber: establishmentData.license_number,
isicCode: establishmentData.isic_code,
emirate: establishmentData.establishment_emirate_id,
establishment_contact_email: establishmentData.establishment_contact_email,
employeeInfo: {
emiratiMale: establishmentData.emirati_male || '',
nonEmiratiMale: establishmentData.non_emirati_male || '',
emiratiFemale: establishmentData.emirati_female || '',
nonEmiratiFemale: establishmentData.non_emirati_female || '',
totalEmployees: establishmentData.total_employees || '',
totalEmirati: establishmentData.total_emirati || ''
}
});
} catch (error) {
console.error('Error processing resubmission data:', error);
}
}, [data, location.state?.fromResubmit, surveyData.quarter, surveyData.year]);
}
}, [location.state]);
const info = React.useMemo(
() => ({

View File

@ -97,6 +97,8 @@ const SearchableSelect = ({
const [searchTerm, setSearchTerm] = React.useState('');
const selectRef = React.useRef(null);
const inputRef = React.useRef(null);
const [savedQuarter, setSavedQuarter] = React.useState(null);
const [savedYear, setSavedYear] = React.useState(null);
// Close dropdown when clicking outside
React.useEffect(() => {
@ -494,6 +496,116 @@ const ProductData = ({
fetchQuarterPeriods();
}, [quarter, year]);
// Load resubmission data when component mounts
useEffect(() => {
const loadResubmissionData = async () => {
try {
// Check for resubmission data in localStorage and location state
const resubmissionData = localStorage.getItem('resubmissionData') ||
(location.state?.submission && JSON.stringify(location.state.submission));
if (resubmissionData) {
const parsedData = JSON.parse(resubmissionData);
if (parsedData.products && Array.isArray(parsedData.products) && parsedData.products.length > 0) {
console.log('Loading resubmission products:', parsedData.products);
// Wait for product options to be loaded
if (productOptions.length === 0) {
await new Promise(resolve => {
const checkProducts = setInterval(() => {
if (productOptions.length > 0) {
clearInterval(checkProducts);
resolve();
}
}, 100);
});
}
// Map the products to match the expected format
const mappedProducts = await Promise.all(parsedData.products.map(async (product, index) => {
// Find the matching product in productOptions
const matchedProduct = productOptions.find(
p => p.value === product.product_id?.toString() ||
p.productId === product.product_id ||
p.originalData?.id === product.product_id
);
return {
id: product.id || `resubmit-${index}-${Date.now()}`,
product: matchedProduct?.value || product.product_id?.toString() || '',
productId: product.product_id,
productName: matchedProduct?.name || product.product?.product_name || product.product_name || '',
unit: product.unit_id?.toString() || product.unit?.id?.toString() || '',
unitName: product.unit?.uom || product.unit_name || '',
capacity: product.annual_installed_capacity?.toString() || '0',
// Previous Quarter (Q4) - October, November, December
octQuantity: product.previous_quantity_period_one?.toString() || '0',
novQuantity: product.previous_quantity_period_two?.toString() || '0',
decQuantity: product.previous_quantity_period_three?.toString() || '0',
octCost: product.previous_cost_period_one?.toString() || '0',
novCost: product.previous_cost_period_two?.toString() || '0',
decCost: product.previous_cost_period_three?.toString() || '0',
// Current Quarter (Q1) - January, February, March
janQuantity: product.current_quantity_period_one?.toString() || '0',
febQuantity: product.current_quantity_period_two?.toString() || '0',
marQuantity: product.current_quantity_period_three?.toString() || '0',
janCost: product.current_cost_period_one?.toString() || '0',
febCost: product.current_cost_period_two?.toString() || '0',
marCost: product.current_cost_period_three?.toString() || '0',
// Forecast Quarter (Q2) - April, May, June
aprQuantity: product.forecast_quantity_period_one?.toString() || '0',
mayQuantity: product.forecast_quantity_period_two?.toString() || '0',
junQuantity: product.forecast_quantity_period_three?.toString() || '0',
aprCost: product.forecast_cost_period_one?.toString() || '0',
mayCost: product.forecast_cost_period_two?.toString() || '0',
junCost: product.forecast_cost_period_three?.toString() || '0',
// Variation reasons
variationReason: product.variation_reason_master_id?.toString() || '',
otherVariationReason: product.other_variation_reason || '',
zeroTargetReason: product.zero_target_reason_master_id?.toString() || '',
otherZeroTargetReason: product.other_zero_target_reason || '',
remarks: product.remarks || '',
// Additional fields for better tracking
isResubmitted: true,
originalData: product
};
}));
console.log('Mapped products for resubmission:', mappedProducts);
// Update the products state with the mapped products
if (mappedProducts.length > 0) {
onProductsChange(mappedProducts);
// Set selected product IDs for tracking
setSelectedProductIds(mappedProducts
.map(p => p.productId || p.product)
.filter(Boolean)
);
// Set initial tab to show the first product
setActiveTab('current');
}
}
}
} catch (error) {
console.error('Error loading resubmission data:', error);
}
};
// Only load resubmission data if we're in resubmit mode and don't have products yet
const isResubmit = location.state?.isResubmit || false;
if (isResubmit && (!products || products.length === 0)) {
loadResubmissionData();
}
}, [onProductsChange, products, productOptions, location.state]);
const handleSaveDraft = async () => {
try {
setIsSavingDraft(true);
@ -882,22 +994,43 @@ useEffect(() => {
const formattedProducts = productsList.map(product => {
// Handle nested properties with dot notation
const productName = product['product.product_name'] || product.product_name || '';
const hsCode = product['product.hs_code'] || product.hs_code || '';
const unitName = product['product.unit.uom'] || '';
const productName = product['product.product_name'] || product.product_name || product.product?.product_name || '';
const hsCode = product['product.hs_code'] || product.hs_code || product.product?.hs_code || '';
const unitName = product['product.unit.uom'] || product.unit?.uom || '';
const productId = product.product_id || product.product?.id || product.id;
return {
value: product.id.toString(),
value: productId.toString(),
label: hsCode ? `${hsCode} - ${productName}` : productName,
originalData: product,
hsCode: hsCode,
name: productName,
productId: product.product_id, // Use product_id instead of id
product_id: product.product_id, // Add product_id directly to the object
productId: productId,
product_id: productId,
unit: unitName
};
});
setProductOptions(formattedProducts);
setProductOptions(prevOptions => {
// Only update if there are new products to avoid unnecessary re-renders
if (JSON.stringify(prevOptions) !== JSON.stringify(formattedProducts)) {
return formattedProducts;
}
return prevOptions;
});
// If we're in resubmit mode and have products in localStorage, trigger the resubmission load
const isResubmit = location.state?.isResubmit || false;
const resubmissionData = localStorage.getItem('resubmissionData');
if (isResubmit && resubmissionData) {
const parsedData = JSON.parse(resubmissionData);
if (parsedData.products && parsedData.products.length > 0) {
// Force a re-render to trigger the resubmission data load
onProductsChange([]);
}
}
} catch (error) {
console.error('Error fetching products:', error);
setProductsError('Failed to load products. Please try again.');
@ -915,7 +1048,7 @@ useEffect(() => {
};
fetchEstablishmentProducts();
}, []);
}, [location.state?.isResubmit]); // Add isResubmit to dependency array
// Moved inside the component
React.useEffect(() => {
const maxId = products.reduce((max, item) => (item && typeof item.id === 'number' ? Math.max(max, item.id) : max), 0);

View File

@ -226,6 +226,57 @@ const showToast = (message, type = 'success') => {
className="w-5 h-5 text-[#92722A] opacity-60 hover:opacity-100 transition-opacity cursor-pointer"
style={{ filter: 'invert(36%) sepia(49%) saturate(680%) hue-rotate(1deg) brightness(89%) contrast(91%)' }}
title="Resubmit"
onClick={async (e) => {
e.stopPropagation();
try {
const response = await fetchSubmissionDetail(record.id);
const submissionData = response.data;
// Structure the data in the format expected by the component
const formattedData = {
...submissionData,
establishment: {
...submissionData.establishment,
establishment_contact_email: submissionData.establishment.establishment_contact_email,
emirate: submissionData.establishment.establishment_emirate_id,
establishment_emirate_id: submissionData.establishment.establishment_emirate_id
},
employeeInfo: {
emiratiMale: submissionData.establishment.emirati_male,
emiratiFemale: submissionData.establishment.emirati_female,
nonEmiratiMale: submissionData.establishment.non_emirati_male,
nonEmiratiFemale: submissionData.establishment.non_emirati_female,
totalEmirati: submissionData.establishment.total_emirati,
totalEmployees: submissionData.establishment.total_employees
},
products: submissionData.products || [],
quarterWindow: submissionData.quarter_window || {}
};
// Save the complete data to localStorage
localStorage.setItem('resubmissionData', JSON.stringify(formattedData));
// Save products separately
if (submissionData.products && submissionData.products.length > 0) {
localStorage.setItem('submissionProducts', JSON.stringify(submissionData.products));
}
// Set resubmission flags
localStorage.setItem('isResubmission', 'true');
// Navigate to survey with resubmission state
navigate('/survey', {
state: {
submission: formattedData,
isResubmit: true,
fromResubmit: true
}
});
} catch (error) {
console.error('Error preparing resubmission:', error);
// Optionally show error to user
}
}}
/>
)}
</div>