chnages in product details

This commit is contained in:
Malini 2025-11-13 13:53:14 +05:30
parent 2edb38db14
commit 8eee109297
6 changed files with 646 additions and 207 deletions

View File

@ -1,6 +1,6 @@
import React, { useState, useCallback, useMemo, useEffect } from 'react'; import React, { useState, useCallback, useMemo, useEffect } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { fetchSubmissionDetail } from '@/services/submissions/submissionService'; import { fetchSubmissionDetail, getQuarterPeriods } from '@/services/submissions/submissionService';
import Table from '@/components/common/Table'; import Table from '@/components/common/Table';
import ProductDetails from './ProductDetails'; import ProductDetails from './ProductDetails';
@ -196,9 +196,31 @@ export const DetailedOverview = ({ submission, onBack }) => {
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
}, [filteredProducts]); }, [filteredProducts]);
const handleViewDetails = (product) => { const handleViewDetails = async (product) => {
try {
setLoadingProduct(true);
// Extract quarter and year from the submission data
const quarter = submissionData.quarter; // e.g., 'Q1'
const year = submissionData.year; // e.g., 2025
// Fetch quarter periods
const response = await getQuarterPeriods(year, quarter);
// Update the selected product with quarter periods data
setSelectedProduct({
...product,
quarterPeriods: response.data
});
setShowToast(true);
} catch (error) {
console.error('Error fetching quarter periods:', error);
// Still show the product details even if quarter periods fetch fails
setSelectedProduct(product); setSelectedProduct(product);
setShowToast(true); setShowToast(true);
} finally {
setLoadingProduct(false);
}
}; };
const handleToastShown = () => { const handleToastShown = () => {
@ -420,11 +442,13 @@ export const DetailedOverview = ({ submission, onBack }) => {
return ( return (
<ProductDetails <ProductDetails
product={selectedProduct} product={selectedProduct}
onBack={() => setSelectedProduct(null)} onClose={() => setShowToast(false)}
onBack={() => setSelectedProduct(null)} // Add this line to handle back navigation
showToast={showToast} showToast={showToast}
onToastShown={handleToastShown} onToastShown={handleToastShown}
submissionDate={selectedProduct?.created_at || submissionData?.created_at || submissionData?.updated_at || new Date().toISOString()} submissionDate={selectedProduct?.created_at || submissionData?.created_at || submissionData?.updated_at || new Date().toISOString()}
submissionStatus={selectedProduct?.status || submissionData?.status || 'submitted'} submissionStatus={selectedProduct?.status || submissionData?.status || 'submitted'}
quarterPeriods={selectedProduct?.quarterPeriods || quarterPeriods}
/> />
); );
} }

View File

@ -2,7 +2,21 @@ import React, { useState, useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
const ProductDetails = ({ product, onBack, showToast: shouldShowToast, onToastShown, submissionDate, submissionStatus = 'approved' }) => { // Default onBack function if not provided
const defaultOnBack = () => {
console.log('No onBack handler provided');
};
const ProductDetails = ({
product = {},
onClose = () => {},
showToast = false,
onToastShown = () => {},
submissionDate = new Date().toISOString(),
submissionStatus = 'submitted',
quarterPeriods = null,
onBack = defaultOnBack
}) => {
const [toast, setToast] = useState(null); const [toast, setToast] = useState(null);
const toastShownRef = useRef(false); const toastShownRef = useRef(false);
@ -21,11 +35,12 @@ const ProductDetails = ({ product, onBack, showToast: shouldShowToast, onToastSh
}; };
useEffect(() => { useEffect(() => {
if (shouldShowToast && !toastShownRef.current) { if (showToast && !toastShownRef.current) {
const formattedDate = formatDate(submissionDate); const formattedDate = formatDate(submissionDate);
if (submissionStatus) { if (submissionStatus) {
const status = String(submissionStatus).toLowerCase(); const status = String(submissionStatus).toLowerCase();
console.log("Status",status)
const toastConfig = { const toastConfig = {
approved: { approved: {
type: 'approved', type: 'approved',
@ -76,7 +91,7 @@ const ProductDetails = ({ product, onBack, showToast: shouldShowToast, onToastSh
toastShownRef.current = true; toastShownRef.current = true;
onToastShown?.(); onToastShown?.();
} }
}, [shouldShowToast, product?.is_active, onToastShown, submissionDate, submissionStatus]); }, [showToast, product?.is_active, onToastShown, submissionDate, submissionStatus]);
const closeToast = () => { const closeToast = () => {
setToast(null); setToast(null);
@ -86,6 +101,34 @@ const ProductDetails = ({ product, onBack, showToast: shouldShowToast, onToastSh
useEffect(() => { useEffect(() => {
}, [product?.status, product?.is_active]); }, [product?.status, product?.is_active]);
// Default quarter periods if not provided
const defaultQuarterPeriods = {
previous_quarter: 'Q4',
previous_year: new Date().getFullYear() - 1,
current_quarter: 'Q1',
current_year: new Date().getFullYear(),
forecast_quarter: 'Q2',
forecast_year: new Date().getFullYear(),
previous_month: {
previous_period_one: 'Oct',
previous_period_two: 'Nov',
previous_period_three: 'Dec'
},
current_month: {
current_period_one: 'Jan',
current_period_two: 'Feb',
current_period_three: 'Mar'
},
forecast_month: {
forecast_period_one: 'Apr',
forecast_period_two: 'May',
forecast_period_three: 'Jun'
}
};
// Use provided quarterPeriods or fall back to defaults
const periods = quarterPeriods || product?.quarterPeriods || defaultQuarterPeriods;
const navigate = useNavigate(); const navigate = useNavigate();
// Function to save resubmission data to localStorage // Function to save resubmission data to localStorage
@ -369,13 +412,31 @@ const ProductDetails = ({ product, onBack, showToast: shouldShowToast, onToastSh
<div className="space-y-1"> <div className="space-y-1">
<label className="block text-sm font-medium text-[#6B7280]">Status</label> <label className="block text-sm font-medium text-[#6B7280]">Status</label>
<div className="mt-1"> <div className="mt-1">
<span className={`inline-flex items-center rounded-md px-3 py-1.5 text-sm font-medium ${ {(() => {
formattedProduct.status === 'Active' const status = String(submissionStatus).toLowerCase();
? 'bg-[#F3FAF4] text-[#2F663C] ring-1 ring-inset ring-green-600/20' let statusClass = 'px-2 py-0.5 text-xs font-medium';
: 'bg-yellow-50 text-yellow-700 ring-1 ring-inset ring-yellow-600/20' let displayText = status.charAt(0).toUpperCase() + status.slice(1);
}`}>
{formattedProduct.status} if (status === 'approved') {
statusClass += ' bg-[#F3FAF4] text-[#2F663C]';
} else if (status === 'rejected') {
statusClass += ' bg-red-50 text-red-600';
} else if (status === 'submitted' || status === 'active') {
statusClass += ' bg-[#E7F5FF] text-[#043DFF]';
displayText = status === 'active' ? 'Submitted' : displayText;
} else if (status === 'resubmitted') {
statusClass += ' bg-[#E7F5FF] text-[#043DFF]';
} else {
// Default/pending state
statusClass += ' bg-amber-50 text-amber-700';
}
return (
<span className={`inline-flex items-center rounded ${statusClass}`}>
{displayText}
</span> </span>
);
})()}
</div> </div>
</div> </div>
</div> </div>
@ -389,28 +450,46 @@ const ProductDetails = ({ product, onBack, showToast: shouldShowToast, onToastSh
<th rowSpan="2" className="border border-gray-300 py-2 px-3 text-left bg-[#F2ECCF] w-[140px]"> <th rowSpan="2" className="border border-gray-300 py-2 px-3 text-left bg-[#F2ECCF] w-[140px]">
Metric Metric
</th> </th>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#E9F6FF]">
Q4-2024 (Previous Quarter) {periods.previous_quarter}-{periods.previous_year} (Previous Quarter)
</th> </th>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F3FAF4]">
Q1-2025 (Current Quarter) {periods.current_quarter}-{periods.current_year} (Current Quarter)
</th> </th>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#FFF7E9]">
Q2-2025 (Next Quarter) {periods.forecast_quarter}-{periods.forecast_year} (Next Quarter)
</th> </th>
</tr> </tr>
{/* Second header row */} {/* Second header row */}
<tr className="bg-white text-[13px] font-medium"> <tr className="bg-white text-[13px] font-medium">
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">Oct</th> <th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">Nov</th> {periods.previous_month.previous_period_one}
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">Dec</th> </th>
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">Jan</th> <th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">Feb</th> {periods.previous_month.previous_period_two}
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">Mar</th> </th>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">Apr</th> <th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">May</th> {periods.previous_month.previous_period_three}
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">Jun</th> </th>
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{periods.current_month.current_period_one}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{periods.current_month.current_period_two}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{periods.current_month.current_period_three}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{periods.forecast_month.forecast_period_one}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{periods.forecast_month.forecast_period_two}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{periods.forecast_month.forecast_period_three}
</th>
</tr> </tr>
</thead> </thead>
@ -513,17 +592,32 @@ const ProductDetails = ({ product, onBack, showToast: shouldShowToast, onToastSh
</div> </div>
</div> */} </div> */}
</div> </div>
<button <div className="flex justify-between items-center mb-4">
{/* <button
onClick={onBack} onClick={onBack}
className="inline-flex items-center gap-2 h-9 px-4 mt-8 rounded-md border border-[#92722A] text-[#92722A] bg-transparent hover:bg-[#92722A]/10" className="flex items-center text-gray-600 hover:text-gray-800"
> >
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"> <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7" /> <path fillRule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clipRule="evenodd" />
</svg> </svg>
<span>Back</span> Back to List
</button> </button> */}
{/* <button
onClick={onClose}
className="text-gray-500 hover:text-gray-700"
aria-label="Close"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button> */}
</div>
</div> </div>
); );
}; };
ProductDetails.defaultProps = {
onBack: () => {}
};
export default ProductDetails; export default ProductDetails;

View File

@ -104,6 +104,12 @@ const EstablishmentInfo = ({
// Initialize from location state if available, otherwise use defaults // Initialize from location state if available, otherwise use defaults
if (location.state?.survey) { if (location.state?.survey) {
const { quarter, year, endDate } = location.state.survey; const { quarter, year, endDate } = location.state.survey;
console.log('Initializing survey data from location.state:', { quarter, year, endDate });
// Save to localStorage
const surveyPeriod = { quarter, year, endDate };
localStorage.setItem('currentSurveyPeriod', JSON.stringify(surveyPeriod));
return { return {
quarter: quarter || '', quarter: quarter || '',
year: year || '', year: year || '',
@ -112,6 +118,16 @@ const EstablishmentInfo = ({
} }
// Or use current quarter/year as fallback // Or use current quarter/year as fallback
const current = getCurrentQuarterAndYear(); const current = getCurrentQuarterAndYear();
console.log('Using current quarter/year as fallback:', current);
// Save to localStorage
const surveyPeriod = {
quarter: current.quarter,
year: current.year,
endDate: current.endDate
};
localStorage.setItem('currentSurveyPeriod', JSON.stringify(surveyPeriod));
return { return {
quarter: current.quarter, quarter: current.quarter,
year: current.year, year: current.year,
@ -119,6 +135,11 @@ const EstablishmentInfo = ({
}; };
}); });
// Log when surveyData changes
React.useEffect(() => {
console.log('surveyData updated:', surveyData);
}, [surveyData]);
// Update the ref whenever surveyData changes // Update the ref whenever surveyData changes
React.useEffect(() => { React.useEffect(() => {
surveyDataRef.current = surveyData; surveyDataRef.current = surveyData;

View File

@ -56,7 +56,8 @@ const SearchableSelect = ({
loading = false, loading = false,
disabled = false, disabled = false,
error = false, error = false,
className = '' className = '',
displayValue = undefined
}) => { }) => {
const [isOpen, setIsOpen] = React.useState(false); const [isOpen, setIsOpen] = React.useState(false);
const [searchTerm, setSearchTerm] = React.useState(''); const [searchTerm, setSearchTerm] = React.useState('');
@ -97,7 +98,9 @@ const SearchableSelect = ({
// Get selected option label // Get selected option label
const selectedOption = options.find(opt => opt.value === value); const selectedOption = options.find(opt => opt.value === value);
const displayValue = selectedOption ? selectedOption.label : ''; const displayValueToShow = displayValue !== undefined
? displayValue
: (selectedOption ? selectedOption.label : '');
// Handle option selection // Handle option selection
const handleSelect = (option) => { const handleSelect = (option) => {
@ -125,7 +128,7 @@ const SearchableSelect = ({
className={`flex items-center justify-between h-10 px-4 py-2 text-sm rounded-md border-2 ${borderColor} ${bgColor} ${disabled ? 'bg-gray-50 cursor-not-allowed' : 'cursor-pointer'}`} className={`flex items-center justify-between h-10 px-4 py-2 text-sm rounded-md border-2 ${borderColor} ${bgColor} ${disabled ? 'bg-gray-50 cursor-not-allowed' : 'cursor-pointer'}`}
onClick={() => !disabled && !loading && setIsOpen(!isOpen)} onClick={() => !disabled && !loading && setIsOpen(!isOpen)}
> >
<span className="truncate">{displayValue || placeholder}</span> <span className="truncate">{displayValueToShow || placeholder}</span>
{loading ? ( {loading ? (
<div className="h-4 w-4 animate-spin rounded-full border-2 border-[#92722A] border-t-transparent ml-2" /> <div className="h-4 w-4 animate-spin rounded-full border-2 border-[#92722A] border-t-transparent ml-2" />
) : ( ) : (
@ -311,7 +314,13 @@ const ProductData = ({
const [productsError, setProductsError] = React.useState(''); const [productsError, setProductsError] = React.useState('');
const [unitOptions, setUnitOptions] = React.useState([]); const [unitOptions, setUnitOptions] = React.useState([]);
const [isLoadingUnits, setIsLoadingUnits] = React.useState(false); const [isLoadingUnits, setIsLoadingUnits] = React.useState(false);
const [unitsError, setUnitsError] = React.useState(''); const [unitsError, setUnitsError] = React.useState(null);
// Debug: Log products data when it changes
useEffect(() => {
console.log('Products data updated:', products);
}, [products]);
const [activeTab, setActiveTab] = React.useState('current'); const [activeTab, setActiveTab] = React.useState('current');
const [isInitialLoad, setIsInitialLoad] = React.useState(true); const [isInitialLoad, setIsInitialLoad] = React.useState(true);
const [quarterPeriods, setQuarterPeriods] = React.useState(null); const [quarterPeriods, setQuarterPeriods] = React.useState(null);
@ -336,12 +345,28 @@ const ProductData = ({
useEffect(() => { useEffect(() => {
const fetchQuarterPeriods = async () => { const fetchQuarterPeriods = async () => {
if (!quarter || !year) return;
try { try {
// Try to get survey period from localStorage
const savedSurveyPeriod = localStorage.getItem('currentSurveyPeriod');
let periodYear = year;
let periodQuarter = quarter;
if (savedSurveyPeriod) {
const { quarter: savedQuarter, year: savedYear } = JSON.parse(savedSurveyPeriod);
console.log('Using survey period from localStorage:', { savedQuarter, savedYear });
periodYear = savedYear || year;
periodQuarter = savedQuarter || quarter;
}
if (!periodQuarter || !periodYear) {
console.warn('No quarter or year available for fetching periods');
return;
}
setIsLoadingPeriods(true); setIsLoadingPeriods(true);
const quarterNumber = quarter.replace('Q', ''); // Convert 'Q3' to '3' const quarterNumber = periodQuarter.replace('Q', ''); // Convert 'Q3' to '3'
const response = await getQuarterPeriods(parseInt(year), `Q${quarterNumber}`); console.log('Fetching quarter periods with:', { year: periodYear, quarter: `Q${quarterNumber}` });
const response = await getQuarterPeriods(parseInt(periodYear), `Q${quarterNumber}`);
setQuarterPeriods(response.data); setQuarterPeriods(response.data);
} catch (error) { } catch (error) {
console.error('Failed to fetch quarter periods:', error); console.error('Failed to fetch quarter periods:', error);
@ -526,6 +551,7 @@ const location = useLocation();
year: year || '' year: year || ''
})); }));
}, [quarter, year]); }, [quarter, year]);
console.log("surveyDatatest", surveyData);
const requiredMessage = 'Required'; const requiredMessage = 'Required';
const validateForm = () => { const validateForm = () => {
@ -916,11 +942,24 @@ const handleProductSelect = async (productId, establishmentId, id) => {
)} )}
<div className="flex justify-between items-center mb-2"> <div className="flex justify-between items-center mb-2">
<h2 className="text-xl font-semibold text-[#232528]">Step 2: Product Data Monthly Output & Cost</h2> <h2 className="text-xl font-semibold text-[#232528]">Step 2: Product Data Monthly Output & Cost</h2>
{(surveyData.quarter || surveyData.year) && ( {(() => {
// Try to get survey period from localStorage first
const savedSurveyPeriod = localStorage.getItem('currentSurveyPeriod');
let displayQuarter = quarter;
let displayYear = year;
if (savedSurveyPeriod) {
const { quarter: savedQuarter, year: savedYear } = JSON.parse(savedSurveyPeriod);
displayQuarter = savedQuarter || quarter;
displayYear = savedYear || year;
}
return (displayQuarter || displayYear) ? (
<div className="text-sm font-medium text-gray-600"> <div className="text-sm font-medium text-gray-600">
Quarter: <span className="text-[#92722A]">{surveyData.quarter}-{surveyData.year}</span> Quarter: <span className="text-[#92722A]">{displayQuarter}-{displayYear}</span>
</div> </div>
)} ) : null;
})()}
</div> </div>
{!showInfoCard && ( {!showInfoCard && (
<button <button
@ -956,15 +995,26 @@ const handleProductSelect = async (productId, establishmentId, id) => {
<div className="flex items-center space-x-1"> <div className="flex items-center space-x-1">
<img src={calendarIcon} alt="" className="h-4 w-4" /> <img src={calendarIcon} alt="" className="h-4 w-4" />
<span className="font-medium">Due:</span> <span className="font-medium">Due:</span>
{surveyData.endDate ? ( {(() => {
new Date(surveyData.endDate).toLocaleDateString('en-US', { // Try to get endDate from localStorage first
const savedSurveyPeriod = localStorage.getItem('currentSurveyPeriod');
let endDateToUse = surveyData.endDate;
if (savedSurveyPeriod) {
const { endDate } = JSON.parse(savedSurveyPeriod);
endDateToUse = endDate || surveyData.endDate;
}
return endDateToUse ? (
new Date(endDateToUse).toLocaleDateString('en-US', {
year: 'numeric', year: 'numeric',
month: 'short', month: 'short',
day: 'numeric' day: 'numeric'
}) })
) : ( ) : (
<span className="text-amber-600">To be announced</span> <span className="text-amber-600">To be announced</span>
)} );
})()}
</div> </div>
<div className="flex items-center space-x-1"> <div className="flex items-center space-x-1">
@ -1069,7 +1119,8 @@ const handleProductSelect = async (productId, establishmentId, id) => {
<SearchableSelect <SearchableSelect
placeholder={isLoadingProducts ? 'Loading products...' : 'Search product HS code...'} placeholder={isLoadingProducts ? 'Loading products...' : 'Search product HS code...'}
options={productOptions} options={productOptions}
value={p.productId?.toString() || p.product?.toString() || ''} value={p.productId?.toString() || p.product_id?.toString() || p.product?.toString() || ''}
displayValue={p.name || (p.hs_code && p.productName ? `${p.hs_code} - ${p.productName}` : p.productName) || ''}
onChange={async (e) => { onChange={async (e) => {
const selectedValue = e.target.value; const selectedValue = e.target.value;
// Clear error when user selects a product // Clear error when user selects a product
@ -1080,26 +1131,63 @@ const handleProductSelect = async (productId, establishmentId, id) => {
} }
// Find the selected product from options // Find the selected product from options
const selectedProduct = productOptions.find(opt => opt.value === selectedValue); const selectedProduct = productOptions.find(opt => opt.value === selectedValue || opt.productId?.toString() === selectedValue);
// Get unit information from the selected product // Get unit information from the selected product
const unitId = selectedProduct?.originalData?.['product.unit.id']; const unitId = selectedProduct?.originalData?.['product.unit.id'] ||
selectedProduct?.unitId ||
selectedProduct?.originalData?.unit_id;
const unitName = selectedProduct?.originalData?.['product.unit.uom'] || const unitName = selectedProduct?.originalData?.['product.unit.uom'] ||
selectedProduct?.originalData?.unit?.uom || selectedProduct?.originalData?.unit?.uom ||
selectedProduct?.unitName ||
selectedProduct?.unit || ''; selectedProduct?.unit || '';
// Create updated product with all necessary fields including unit info // Get the display name for the product - check multiple possible locations
let displayName = '';
if (selectedProduct) {
// Get HS code from various possible locations
const hsCode = selectedProduct.hsCode ||
selectedProduct.originalData?.['product.hs_code'] ||
selectedProduct.originalData?.hs_code ||
'';
// Get product name from various possible locations
const productName = selectedProduct.name ||
selectedProduct.originalData?.['product.name'] ||
selectedProduct.originalData?.product_name ||
selectedProduct.originalData?.name ||
'';
// Combine HS Code and Product Name for display
displayName = hsCode && productName ?
`${hsCode} - ${productName}` :
productName || selectedProduct.label ||
(selectedProduct.originalData ?
(selectedProduct.originalData['product.product_name'] ||
selectedProduct.originalData.product_name ||
selectedProduct.originalData.name) :
(selectedProduct.name || '')
);
}
// Create updated product with all necessary fields
const updatedProduct = { const updatedProduct = {
...p, ...p,
product: selectedProduct?.value || selectedValue, product: selectedValue, // Store the ID as string
productId: selectedProduct?.value || selectedValue, productId: selectedValue, // Also store as productId for consistency
product_id: selectedProduct?.value || selectedValue, product_id: selectedValue, // For backward compatibility
hs_code: selectedProduct?.hsCode || p.hs_code, hs_code: selectedProduct?.hsCode ||
name: selectedProduct?.name || p.name, (selectedProduct?.originalData ?
(selectedProduct.originalData['product.hs_code'] ||
selectedProduct.originalData.hs_code) :
'') || p.hs_code,
name: displayName || p.name, // Use the formatted display name
originalData: selectedProduct?.originalData || p.originalData, originalData: selectedProduct?.originalData || p.originalData,
// Set unit information // Set unit information
unit: unitId ? unitId.toString() : '', unit: unitId ? unitId.toString() : '',
unitName: unitName, unitName: unitName,
unit_id: unitId, unit_id: unitId ? unitId.toString() : '',
// Clear any previous unit-related errors // Clear any previous unit-related errors
...(formErrors[`unit_${idx}`] && { unitError: undefined }) ...(formErrors[`unit_${idx}`] && { unitError: undefined })
}; };
@ -1165,28 +1253,23 @@ const handleProductSelect = async (productId, establishmentId, id) => {
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-1">Unit <span className="text-red-500">*</span></label> <label className="block text-sm font-medium text-gray-700 mb-1">Unit <span className="text-red-500">*</span></label>
<SearchableSelect <SearchableSelect
placeholder={p.unitName || (isLoadingUnits ? 'Loading units...' : 'Search unit...')} placeholder={isLoadingUnits ? 'Loading units...' : 'Select unit'}
options={unitOptions} options={unitOptions}
value={p.unit} value={p.unit?.toString() || ''}
displayValue={p.unitName || ''}
onChange={(e) => { onChange={(e) => {
// Clear error when user selects a unit const unitId = e.target.value;
if (formErrors[`unit_${idx}`]) { const selectedUnit = unitOptions.find(u => u.value === unitId);
const newErrors = { ...formErrors }; const originalUnit = selectedUnit?.originalData || {};
delete newErrors[`unit_${idx}`]; const displayName = originalUnit.uom_short_name && originalUnit.uom
setFormErrors(newErrors); ? `${originalUnit.uom_short_name.toUpperCase()} - ${originalUnit.uom}`
} : selectedUnit?.label || '';
// Find the selected unit to get its name updateProductField(idx, 'unit', unitId);
const selectedUnit = unitOptions.find(unit => unit.value === e.target.value); updateProductField(idx, 'unitName', displayName);
updateProductField(p.id, 'unit', e.target.value, unitOptions);
// Also update unit name if a valid unit is selected
if (selectedUnit) {
updateProductField(p.id, 'unitName', selectedUnit.label || selectedUnit.name);
updateProductField(p.id, 'unit_id', selectedUnit.id || e.target.value);
}
}} }}
loading={isLoadingUnits} loading={isLoadingUnits}
error={!!formErrors[`unit_${idx}`]} error={!!formErrors[`unit_${idx}`]}
isDisabled={!!p.unitName} // Disable if unit is auto-filled from product disabled={!!p.unitName} // Disable if unit is auto-filled from product
/> />
<div className="h-5"> <div className="h-5">
{formErrors[`unit_${idx}`] && ( {formErrors[`unit_${idx}`] && (

View File

@ -1,5 +1,6 @@
import React from 'react'; import React, { useState, useEffect } from 'react';
import Table from '@/components/common/Table'; import Table from '@/components/common/Table';
import { getQuarterPeriods } from '@/services/submissions/submissionService';
const caretUpSrc = '/assets/images/caret-up.svg'; const caretUpSrc = '/assets/images/caret-up.svg';
const caretDownSrc = '/assets/images/CaretDown-black.svg'; const caretDownSrc = '/assets/images/CaretDown-black.svg';
const establishmentIconSrc = '/assets/images/Establishment.svg'; const establishmentIconSrc = '/assets/images/Establishment.svg';
@ -341,7 +342,41 @@ const ReviewSubmit = ({
quarter = 'Q1', quarter = 'Q1',
year = new Date().getFullYear() year = new Date().getFullYear()
}) => { }) => {
const [quarterPeriods, setQuarterPeriods] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [confirm, setConfirm] = React.useState(false); const [confirm, setConfirm] = React.useState(false);
useEffect(() => {
const fetchQuarterPeriods = async () => {
try {
setIsLoading(true);
const savedSurveyPeriod = localStorage.getItem('currentSurveyPeriod');
if (!savedSurveyPeriod) {
throw new Error('No survey period found in localStorage');
}
const { quarter, year } = JSON.parse(savedSurveyPeriod);
if (!quarter || !year) {
throw new Error('Incomplete survey period data');
}
const response = await getQuarterPeriods(year, quarter);
if (response.status === 'success') {
setQuarterPeriods(response.data);
} else {
throw new Error('Failed to fetch quarter periods');
}
} catch (err) {
console.error('Error fetching quarter periods:', err);
setError(err.message);
} finally {
setIsLoading(false);
}
};
fetchQuarterPeriods();
}, []);
const [remarks, setRemarks] = React.useState(() => { const [remarks, setRemarks] = React.useState(() => {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
return localStorage.getItem('surveyRemarks') || ''; return localStorage.getItem('surveyRemarks') || '';
@ -728,28 +763,71 @@ const ReviewSubmit = ({
<th rowSpan="2" className="border border-gray-300 py-2 px-3 text-left bg-[#F2ECCF] w-[140px]"> <th rowSpan="2" className="border border-gray-300 py-2 px-3 text-left bg-[#F2ECCF] w-[140px]">
Metric Metric
</th> </th>
{isLoading ? (
<th colSpan="9" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
Loading quarters...
</th>
) : error ? (
<th colSpan="9" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF] text-red-500">
{error}
</th>
) : (
<>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
Q4-2024 (Previous Quarter) {quarterPeriods?.previous_quarter}-{quarterPeriods?.previous_year} (Previous Quarter)
</th> </th>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
Q1-2025 (Current Quarter) {quarterPeriods?.current_quarter}-{quarterPeriods?.current_year} (Current Quarter)
</th> </th>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
Q2-2025 (Next Quarter) {quarterPeriods?.forecast_quarter}-{quarterPeriods?.forecast_year} (Next Quarter)
</th> </th>
</>
)}
</tr> </tr>
{/* Second header row */} {/* Second header row */}
<tr className="bg-white text-[13px] font-medium"> <tr className="bg-white text-[13px] font-medium">
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">Oct</th> {isLoading ? (
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">Nov</th> <th colSpan="9" className="py-2">Loading months...</th>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">Dec</th> ) : error ? (
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">Jan</th> <th colSpan="9" className="py-2 text-red-500">{error}</th>
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">Feb</th> ) : (
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">Mar</th> <>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">Apr</th> {/* Previous Quarter Months */}
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">May</th> <th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">Jun</th> {quarterPeriods?.previous_month?.previous_period_one}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{quarterPeriods?.previous_month?.previous_period_two}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{quarterPeriods?.previous_month?.previous_period_three}
</th>
{/* Current Quarter Months */}
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{quarterPeriods?.current_month?.current_period_one}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{quarterPeriods?.current_month?.current_period_two}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{quarterPeriods?.current_month?.current_period_three}
</th>
{/* Next Quarter Months */}
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{quarterPeriods?.forecast_month?.forecast_period_one}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{quarterPeriods?.forecast_month?.forecast_period_two}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{quarterPeriods?.forecast_month?.forecast_period_three}
</th>
</>
)}
</tr> </tr>
</thead> </thead>

View File

@ -80,15 +80,22 @@ const Survey = () => {
setStep(initialStepFromState); setStep(initialStepFromState);
}, [initialStepFromState]); }, [initialStepFromState]);
useEffect(() => { const initializeSurvey = React.useCallback(() => {
// First check if we have survey data in the navigation state // First check if we have survey data in the navigation state
if (locationState?.survey) { if (locationState?.survey) {
const { quarter, year, establishment } = locationState.survey; const { quarter, year, establishment } = locationState.survey;
setSurveyData(locationState.survey);
// Only update if the data has changed
setSurveyData(prevData => {
return JSON.stringify(prevData) === JSON.stringify(locationState.survey)
? prevData
: locationState.survey;
});
// If we have establishment data in the navigation state, use it // If we have establishment data in the navigation state, use it
if (establishment) { if (establishment) {
setEstablishmentData(prev => ({ setEstablishmentData(prev => {
const newData = {
...prev, ...prev,
quarter: quarter || '', quarter: quarter || '',
year: year || '', year: year || '',
@ -99,20 +106,25 @@ const Survey = () => {
isicCode: establishment.isicCode || prev.isicCode, isicCode: establishment.isicCode || prev.isicCode,
emirate: establishment.emirate || prev.emirate, emirate: establishment.emirate || prev.emirate,
employeeInfo: { employeeInfo: {
emiratiMale: establishment.employeeInfo?.emiratiMale || prev.employeeInfo.emiratiMale, emiratiMale: establishment.employeeInfo?.emiratiMale ?? prev.employeeInfo.emiratiMale,
emiratiFemale: establishment.employeeInfo?.emiratiFemale || prev.employeeInfo.emiratiFemale, emiratiFemale: establishment.employeeInfo?.emiratiFemale ?? prev.employeeInfo.emiratiFemale,
nonEmiratiMale: establishment.employeeInfo?.nonEmiratiMale || prev.employeeInfo.nonEmiratiMale, nonEmiratiMale: establishment.employeeInfo?.nonEmiratiMale ?? prev.employeeInfo.nonEmiratiMale,
nonEmiratiFemale: establishment.employeeInfo?.nonEmiratiFemale || prev.employeeInfo.nonEmiratiFemale, nonEmiratiFemale: establishment.employeeInfo?.nonEmiratiFemale ?? prev.employeeInfo.nonEmiratiFemale,
totalEmirati: establishment.employeeInfo?.totalEmirati || prev.employeeInfo.totalEmirati, totalEmirati: establishment.employeeInfo?.totalEmirati ?? prev.employeeInfo.totalEmirati,
totalEmployees: establishment.employeeInfo?.totalEmployees || prev.employeeInfo.totalEmployees totalEmployees: establishment.employeeInfo?.totalEmployees ?? prev.employeeInfo.totalEmployees
} }
})); };
return JSON.stringify(prev) === JSON.stringify(newData) ? prev : newData;
});
} else { } else {
setEstablishmentData(prev => ({ setEstablishmentData(prev => {
const newData = {
...prev, ...prev,
quarter: quarter || '', quarter: quarter || '',
year: year || '' year: year || ''
})); };
return JSON.stringify(prev) === JSON.stringify(newData) ? prev : newData;
});
} }
// Also save to localStorage for page refreshes // Also save to localStorage for page refreshes
@ -122,11 +134,16 @@ const Survey = () => {
const savedSurvey = localStorage.getItem('currentSurvey'); const savedSurvey = localStorage.getItem('currentSurvey');
if (savedSurvey) { if (savedSurvey) {
const surveyData = JSON.parse(savedSurvey); const surveyData = JSON.parse(savedSurvey);
setSurveyData(surveyData);
// Only update if the data has changed
setSurveyData(prevData => {
return JSON.stringify(prevData) === savedSurvey ? prevData : surveyData;
});
if (surveyData.establishment) { if (surveyData.establishment) {
const { establishment } = surveyData; const { establishment } = surveyData;
setEstablishmentData(prev => ({ setEstablishmentData(prev => {
const newData = {
...prev, ...prev,
quarter: surveyData.quarter || '', quarter: surveyData.quarter || '',
year: surveyData.year || '', year: surveyData.year || '',
@ -137,20 +154,25 @@ const Survey = () => {
isicCode: establishment.isicCode || prev.isicCode, isicCode: establishment.isicCode || prev.isicCode,
emirate: establishment.emirate || prev.emirate, emirate: establishment.emirate || prev.emirate,
employeeInfo: { employeeInfo: {
emiratiMale: establishment.employeeInfo?.emiratiMale || prev.employeeInfo.emiratiMale, emiratiMale: establishment.employeeInfo?.emiratiMale ?? prev.employeeInfo.emiratiMale,
emiratiFemale: establishment.employeeInfo?.emiratiFemale || prev.employeeInfo.emiratiFemale, emiratiFemale: establishment.employeeInfo?.emiratiFemale ?? prev.employeeInfo.emiratiFemale,
nonEmiratiMale: establishment.employeeInfo?.nonEmiratiMale || prev.employeeInfo.nonEmiratiMale, nonEmiratiMale: establishment.employeeInfo?.nonEmiratiMale ?? prev.employeeInfo.nonEmiratiMale,
nonEmiratiFemale: establishment.employeeInfo?.nonEmiratiFemale || prev.employeeInfo.nonEmiratiFemale, nonEmiratiFemale: establishment.employeeInfo?.nonEmiratiFemale ?? prev.employeeInfo.nonEmiratiFemale,
totalEmirati: establishment.employeeInfo?.totalEmirati || prev.employeeInfo.totalEmirati, totalEmirati: establishment.employeeInfo?.totalEmirati ?? prev.employeeInfo.totalEmirati,
totalEmployees: establishment.employeeInfo?.totalEmployees || prev.employeeInfo.totalEmployees totalEmployees: establishment.employeeInfo?.totalEmployees ?? prev.employeeInfo.totalEmployees
} }
})); };
return JSON.stringify(prev) === JSON.stringify(newData) ? prev : newData;
});
} else { } else {
setEstablishmentData(prev => ({ setEstablishmentData(prev => {
const newData = {
...prev, ...prev,
quarter: surveyData.quarter || '', quarter: surveyData.quarter || '',
year: surveyData.year || '' year: surveyData.year || ''
})); };
return JSON.stringify(prev) === JSON.stringify(newData) ? prev : newData;
});
} }
} }
} }
@ -346,12 +368,47 @@ const Survey = () => {
const mapProducts = (detailProducts = []) => { const mapProducts = (detailProducts = []) => {
if (!Array.isArray(detailProducts)) return []; if (!Array.isArray(detailProducts)) return [];
return detailProducts.map((product, index) => ({ return detailProducts.map((product, index) => {
// Extract product and unit information
const productId = product?.product_id || product?.product?.id || '';
const productName = ensureString(product?.product?.product_name) ||
ensureString(product?.product?.name) ||
ensureString(product?.product_name) ||
'';
const hsCode = ensureString(product?.product?.hs_code) ||
ensureString(product?.hs_code) ||
'';
// Combine HS Code and Product Name for display
const displayName = (hsCode && productName)
? `${hsCode} - ${productName}`
: productName || `Product ${index + 1}`;
const unitId = product?.unit_id || product?.unit?.id || '';
const unitName = ensureString(product?.unit?.uom) ||
ensureString(product?.unit?.name) ||
ensureString(unitId) || '';
console.log('Product mapping:', {
id: productId,
productName,
hsCode,
displayName,
unitId,
unitName,
originalProduct: product
});
return {
id: product?.id ?? index + 1, id: product?.id ?? index + 1,
productId: product?.product_id || product?.product?.id || '', productId: productId,
product: ensureString(product?.product?.product_name) || ensureString(product?.product_id) || '', product: productId, // This should match the value in productOptions
unit: ensureString(product?.unit?.uom) || ensureString(product?.unit?.name) || ensureString(product?.unit_id) || '', productName: productName,
unitId: product?.unit_id || product?.unit?.id || '', hsCode: hsCode, // Store HS code separately
name: displayName, // This will be used for display
unit: unitId, // This should match the value in unitOptions
unitName: unitName,
unitId: unitId,
capacity: ensureString(product?.annual_installed_capacity), capacity: ensureString(product?.annual_installed_capacity),
// Previous Quarter (Q4) - October, November, December // Previous Quarter (Q4) - October, November, December
@ -392,7 +449,44 @@ const Survey = () => {
zeroTargetReason: ensureString(product?.zero_target_reason_master_id || ''), zeroTargetReason: ensureString(product?.zero_target_reason_master_id || ''),
otherZeroTargetReason: ensureString(product?.other_zero_target_reason || ''), otherZeroTargetReason: ensureString(product?.other_zero_target_reason || ''),
remarks: ensureString(product?.remarks || '') remarks: ensureString(product?.remarks || '')
})); };
});
// decQuantity: ensureString(product?.previous_quantity_period_three || ''),
// octCost: ensureString(product?.previous_cost_period_one || ''),
// novCost: ensureString(product?.previous_cost_period_two || ''),
// decCost: ensureString(product?.previous_cost_period_three || ''),
// // Current Quarter (Q1) - January, February, March
// janQuantity: ensureString(product?.current_quantity_period_one || ''),
// febQuantity: ensureString(product?.current_quantity_period_two || ''),
// marQuantity: ensureString(product?.current_quantity_period_three || ''),
// janCost: ensureString(product?.current_cost_period_one || ''),
// febCost: ensureString(product?.current_cost_period_two || ''),
// marCost: ensureString(product?.current_cost_period_three || ''),
// // Forecast Quarter (Q2) - April, May, June
// aprQuantity: ensureString(product?.forecast_quantity_period_one || ''),
// mayQuantity: ensureString(product?.forecast_quantity_period_two || ''),
// junQuantity: ensureString(product?.forecast_quantity_period_three || ''),
// aprCost: ensureString(product?.forecast_cost_period_one || ''),
// mayCost: ensureString(product?.forecast_cost_period_two || ''),
// junCost: ensureString(product?.forecast_cost_period_three || ''),
// // Totals (for backward compatibility)
// previousQuantity: ensureString(product?.previous_quantity || ''),
// previousCost: ensureString(product?.previous_cost || ''),
// currentQuantity: ensureString(product?.current_quantity || ''),
// currentCost: ensureString(product?.current_cost || ''),
// forecastQuantity: ensureString(product?.forecast_quantity || ''),
// forecastCost: ensureString(product?.forecast_cost || ''),
// // Reasons and remarks
// variationReason: ensureString(product?.variation_reason_master_id || ''),
// otherVariationReason: ensureString(product?.other_variation_reason || ''),
// zeroTargetReason: ensureString(product?.zero_target_reason_master_id || ''),
// otherZeroTargetReason: ensureString(product?.other_zero_target_reason || ''),
// remarks: ensureString(product?.remarks || '')
// }));
}; };
const loadDetail = async () => { const loadDetail = async () => {
@ -466,10 +560,29 @@ const Survey = () => {
const buildSubmissionPayload = React.useCallback((isResubmitFlow = false) => { const buildSubmissionPayload = React.useCallback((isResubmitFlow = false) => {
const info = establishmentData?.employeeInfo ?? {}; const info = establishmentData?.employeeInfo ?? {};
// Check for resubmission data in localStorage // First try to get quarter and year from currentSurveyPeriod in localStorage
let quarter = surveyData?.quarter || ''; let quarter = '';
let year = surveyData?.year || ''; let year = '';
// Check for currentSurveyPeriod in localStorage
const currentSurveyPeriod = localStorage.getItem('currentSurveyPeriod');
if (currentSurveyPeriod) {
try {
const { quarter: storedQuarter, year: storedYear } = JSON.parse(currentSurveyPeriod);
quarter = storedQuarter || '';
year = storedYear || '';
} catch (e) {
console.error('Error parsing currentSurveyPeriod:', e);
}
}
// Fall back to surveyData if currentSurveyPeriod is not available
if (!quarter || !year) {
quarter = surveyData?.quarter || '';
year = surveyData?.year || '';
}
// For resubmission, check resubmission data last (highest priority)
if (isResubmitFlow) { if (isResubmitFlow) {
const resubmitData = localStorage.getItem('resubmissionData'); const resubmitData = localStorage.getItem('resubmissionData');
if (resubmitData) { if (resubmitData) {
@ -616,13 +729,14 @@ const Survey = () => {
const payload = buildSubmissionPayload(); const payload = buildSubmissionPayload();
const response = await submitSurvey(payload); const response = await submitSurvey(payload);
// Navigate to overview page after successful submission // Show success message and popup
// navigate('/overview');
showToast('success', response?.message || 'You have successfully submitted the survey.'); showToast('success', response?.message || 'You have successfully submitted the survey.');
setShowSuccessPopup(true); setShowSuccessPopup(true);
setHasSubmitted(true); setHasSubmitted(true);
// Clear the stored survey data after successful submission // Clear the stored survey data after successful submission
localStorage.removeItem('currentSurvey'); localStorage.removeItem('currentSurvey');
// Remove currentSurveyPeriod from localStorage
localStorage.removeItem('currentSurveyPeriod');
} catch (error) { } catch (error) {
console.error('Failed to submit survey', error); console.error('Failed to submit survey', error);
const message = error?.response?.data?.message || error?.message || 'Failed to submit survey.'; const message = error?.response?.data?.message || error?.message || 'Failed to submit survey.';
@ -643,6 +757,16 @@ const Survey = () => {
id: submissionId // Include submission ID in the payload id: submissionId // Include submission ID in the payload
}; };
// Remove currentSurveyPeriod from localStorage for resubmission
localStorage.removeItem('currentSurveyPeriod');
// Store resubmission data in localStorage
const resubmissionData = {
...payload,
resubmittedAt: new Date().toISOString()
};
localStorage.setItem('resubmissionData', JSON.stringify(resubmissionData));
// Use the resubmitSurvey API with the submission ID and payload // Use the resubmitSurvey API with the submission ID and payload
await resubmitSurvey(submissionId, payload); await resubmitSurvey(submissionId, payload);
@ -680,6 +804,8 @@ const Survey = () => {
localStorage.removeItem('surveyRemarks'); localStorage.removeItem('surveyRemarks');
// Clear the stored survey data after successful submission // Clear the stored survey data after successful submission
localStorage.removeItem('currentSurvey'); localStorage.removeItem('currentSurvey');
// Remove currentSurveyPeriod from localStorage
localStorage.removeItem('currentSurveyPeriod');
} catch (error) { } catch (error) {
const message = error?.response?.data?.message || error?.message || 'Failed to submit survey. Please try again.'; const message = error?.response?.data?.message || error?.message || 'Failed to submit survey. Please try again.';
console.error('Submission Error:', error); console.error('Submission Error:', error);
@ -939,7 +1065,20 @@ const Survey = () => {
{/* Message */} {/* Message */}
<p className="text-sm text-gray-700"> <p className="text-sm text-gray-700">
Thank you. Your IP Quarterly Survey for <span className="font-semibold text-gray-900"> Thank you. Your IP Quarterly Survey for <span className="font-semibold text-gray-900">
{surveyData?.quarter} {surveyData?.year} {(() => {
// Try to get quarter and year from currentSurveyPeriod in localStorage first
try {
const currentSurveyPeriod = localStorage.getItem('currentSurveyPeriod');
if (currentSurveyPeriod) {
const { quarter, year } = JSON.parse(currentSurveyPeriod);
if (quarter && year) return `${quarter} ${year}`;
}
} catch (e) {
console.error('Error parsing currentSurveyPeriod:', e);
}
// Fall back to surveyData if currentSurveyPeriod is not available
return `${surveyData?.quarter || ''} ${surveyData?.year || ''}`.trim();
})()}
</span> has been {isResubmit ? 'resubmitted' : 'submitted'}. </span> has been {isResubmit ? 'resubmitted' : 'submitted'}.
</p> </p>