added resumit flow and changes in quaterly surveys
This commit is contained in:
parent
63c7fb461d
commit
a24a4064e7
@ -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 {
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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(
|
||||
() => ({
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user