Enhancement version 1

This commit is contained in:
seranjivi 2026-04-28 18:33:54 +05:30
parent 95a3578d80
commit 5f37883a3b
5 changed files with 627 additions and 369 deletions

View File

@ -127,6 +127,29 @@ const ProductDetails = ({
// Use provided quarterPeriods or fall back to defaults
const periods = quarterPeriods || product?.quarterPeriods || defaultQuarterPeriods;
// Determine if we should hide PREVIOUS QUARTER section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHidePreviousQuarter = React.useMemo(() => {
const effectiveYear = (periods?.current_year || new Date().getFullYear()).toString();
const rawQuarter = periods?.current_quarter || 'Q1';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return (effectiveYear === '2022' && normalizedQuarter === 'Q1') ||
(effectiveYear === '2025' && normalizedQuarter === 'Q1');
}, [periods]);
// Determine if we should hide FORECAST section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHideForecast = React.useMemo(() => {
const effectiveYear = (periods?.current_year || new Date().getFullYear()).toString();
const rawQuarter = periods?.current_quarter || 'Q1';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return effectiveYear === '2022' && normalizedQuarter === 'Q4';
}, [periods]);
const navigate = useNavigate();
// Function to save resubmission data to localStorage
@ -460,28 +483,36 @@ const ProductDetails = ({
<th rowSpan="2" className="border border-gray-300 py-2 px-3 text-left bg-[#F2ECCF] w-[140px]">
Metric
</th>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#E9F6FF]">
{periods.previous_quarter}-{periods.previous_year} (Previous Quarter)
</th>
{!shouldHidePreviousQuarter && (
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#E9F6FF]">
{periods.previous_quarter}-{periods.previous_year} (Previous Quarter)
</th>
)}
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F3FAF4]">
{periods.current_quarter}-{periods.current_year} (Current Quarter)
</th>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#FFF7E9]">
{periods.forecast_quarter}-{periods.forecast_year} (Next Quarter)
</th>
{!shouldHideForecast && (
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#FFF7E9]">
{periods.forecast_quarter}-{periods.forecast_year} (Next Quarter)
</th>
)}
</tr>
{/* Second header row */}
<tr className="bg-white text-[13px] font-medium">
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{periods.previous_month.previous_period_one}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{periods.previous_month.previous_period_two}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{periods.previous_month.previous_period_three}
</th>
{!shouldHidePreviousQuarter && (
<>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{periods.previous_month.previous_period_one}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{periods.previous_month.previous_period_two}
</th>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{periods.previous_month.previous_period_three}
</th>
</>
)}
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{periods.current_month.current_period_one}
</th>
@ -491,15 +522,19 @@ const ProductDetails = ({
<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>
{!shouldHideForecast && (
<>
<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>
</thead>
@ -509,15 +544,23 @@ const ProductDetails = ({
<td className="border border-gray-300 py-2 px-3 text-left font-medium">
Quantity ({formattedProduct.unit})
</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_oct_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_nov_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_dec_quantity}</td>
{!shouldHidePreviousQuarter && (
<>
<td className="border border-gray-300 py-2">{formattedProduct.q4_oct_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_nov_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_dec_quantity}</td>
</>
)}
<td className="border border-gray-300 py-2">{formattedProduct.q1_jan_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q1_feb_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q1_mar_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_apr_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_may_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_jun_quantity}</td>
{!shouldHideForecast && (
<>
<td className="border border-gray-300 py-2">{formattedProduct.q2_apr_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_may_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_jun_quantity}</td>
</>
)}
</tr>
{/* Cost Row */}
@ -525,15 +568,23 @@ const ProductDetails = ({
<td className="border border-gray-300 py-2 px-3 text-left font-medium">
Value (AED)
</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_oct_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_nov_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_dec_cost}</td>
{!shouldHidePreviousQuarter && (
<>
<td className="border border-gray-300 py-2">{formattedProduct.q4_oct_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_nov_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_dec_cost}</td>
</>
)}
<td className="border border-gray-300 py-2">{formattedProduct.q1_jan_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q1_feb_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q1_mar_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_apr_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_may_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_jun_cost}</td>
{!shouldHideForecast && (
<>
<td className="border border-gray-300 py-2">{formattedProduct.q2_apr_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_may_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_jun_cost}</td>
</>
)}
</tr>
{/* Reason Current */}
@ -541,15 +592,19 @@ const ProductDetails = ({
<td className="border border-gray-300 py-2 px-3 text-left font-medium">
Reason (Current)
</td>
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
)}
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#F3FAF4] text-[#2F663C]">
{formattedProduct.variationReason}
</td>
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
{!shouldHideForecast && (
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
)}
</tr>
{/* Reason Forecast */}
@ -557,12 +612,19 @@ const ProductDetails = ({
<td className="border border-gray-300 py-2 px-3 text-left font-medium">
Reason (Forecast)
</td>
<td colSpan="6" className="border border-gray-300 py-2 text-center">
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
)}
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]">
{formattedProduct.zeroTargetReason}
</td>
{!shouldHideForecast && (
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]">
{formattedProduct.zeroTargetReason}
</td>
)}
</tr>
</tbody>
</table>

View File

@ -501,6 +501,29 @@ const ProductData = ({
const [isInitialLoad, setIsInitialLoad] = React.useState(true);
const [quarterPeriods, setQuarterPeriods] = React.useState(null);
const [isLoadingPeriods, setIsLoadingPeriods] = React.useState(false);
// Determine if we should hide PREVIOUS QUARTER section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHidePreviousQuarter = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || year || '').toString();
const rawQuarter = quarterPeriods?.current_quarter || quarter || '';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return (effectiveYear === '2022' && normalizedQuarter === 'Q1') ||
(effectiveYear === '2025' && normalizedQuarter === 'Q1');
}, [quarterPeriods, year, quarter]);
// Determine if we should hide FORECAST section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHideForecast = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || year || '').toString();
const rawQuarter = quarterPeriods?.current_quarter || quarter || '';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return effectiveYear === '2022' && normalizedQuarter === 'Q4';
}, [quarterPeriods, year, quarter]);
const [showOtherVariationReason, setShowOtherVariationReason] = React.useState({});
const [showOtherZeroTargetReason, setShowOtherZeroTargetReason] = React.useState({});
const [formErrors, setFormErrors] = React.useState({});
@ -2648,7 +2671,7 @@ useEffect(() => {
<h3 className="font-semibold mb-4 text-base">Data definitions</h3>
<p className="mb-3"><strong>Product (HS Code Name):</strong> Standard trade classification. Start typing to search by code or name.</p>
<p className="mb-3"><strong>Quantity (Qty):</strong> Physical output produced in the month, measured in the selected unit.</p>
<p className="mb-3"><strong>Value (AED <img src={uae_currency} alt="AED" className="inline-block w-5 h-5 -mt-0.5" />):</strong> The net monthly sales value of a single product excluding VAT and any applicable duties. Do not include sales margins.<br /><em><strong>Formula:</strong></em> Sales Value (VAT, Duties, etc)</p>
<p className="mb-3"><strong>Value (AED <img src={uae_currency} alt="AED" className="inline-block w-5 h-5 -mt-0.5" />):</strong> The net monthly gross sales value of a single product excluding VAT and any applicable duties. Do not include sales margins.<br /><em><strong>Formula:</strong></em> Gross Sales Value (VAT, Duties, etc)</p>
<p className="mb-0"><strong>Annual Installed Capacity:</strong> Maximum achievable annual output under normal operating conditions with existing equipment; do not include extraordinary overtime.</p>
</div>
)}
@ -2908,7 +2931,12 @@ useEffect(() => {
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className={`grid grid-cols-1 gap-4 ${
(shouldHidePreviousQuarter && shouldHideForecast) ? 'md:grid-cols-1' :
(shouldHidePreviousQuarter || shouldHideForecast) ? 'md:grid-cols-2' :
'md:grid-cols-3'
}`}>
{!shouldHidePreviousQuarter && (
<SectionBox
title={quarterPeriods ? `PREVIOUS QUARTER (${quarterPeriods.previous_quarter}-${quarterPeriods.previous_year})` : 'PREVIOUS QUARTER (Q-YYYY)'}
badgeBg="#E7F5FF"
@ -3015,6 +3043,7 @@ useEffect(() => {
</div>
</div>
</SectionBox>
)}
<SectionBox
title={quarterPeriods ? `CURRENT QUARTER (${quarterPeriods.current_quarter} ${quarterPeriods.current_year})` : `CURRENT QUARTER (${quarter}-${year})`}
@ -3176,6 +3205,7 @@ useEffect(() => {
</div>
</SectionBox>
{!shouldHideForecast && (
<SectionBox
title={`NEXT QUARTER FORECAST (${quarterPeriods?.forecast_quarter || 'Q'}-${quarterPeriods?.forecast_year || '2025'})`}
badgeBg="#FFF7E9"
@ -3320,6 +3350,7 @@ useEffect(() => {
</div>
</div>
</SectionBox>
)}
</div>
</div>
</Card>

View File

@ -375,6 +375,29 @@ const ReviewSubmit = ({
return '';
});
// Determine if we should hide PREVIOUS QUARTER section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHidePreviousQuarter = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || year || '').toString();
const rawQuarter = quarterPeriods?.current_quarter || quarter || '';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return (effectiveYear === '2022' && normalizedQuarter === 'Q1') ||
(effectiveYear === '2025' && normalizedQuarter === 'Q1');
}, [quarterPeriods, year, quarter]);
// Determine if we should hide FORECAST section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHideForecast = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || year || '').toString();
const rawQuarter = quarterPeriods?.current_quarter || quarter || '';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return effectiveYear === '2022' && normalizedQuarter === 'Q4';
}, [quarterPeriods, year, quarter]);
useEffect(() => {
const fetchEmiratesData = async () => {
try {
@ -1021,24 +1044,28 @@ if (!establishment) {
Metric
</th>
{isLoading ? (
<th colSpan="9" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
<th colSpan={shouldHidePreviousQuarter && shouldHideForecast ? "3" : (shouldHidePreviousQuarter || shouldHideForecast ? "6" : "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">
<th colSpan={shouldHidePreviousQuarter && shouldHideForecast ? "3" : (shouldHidePreviousQuarter || shouldHideForecast ? "6" : "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]">
{quarterPeriods?.previous_quarter}-{quarterPeriods?.previous_year} (Previous Quarter)
</th>
{!shouldHidePreviousQuarter && (
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
{quarterPeriods?.previous_quarter}-{quarterPeriods?.previous_year} (Previous Quarter)
</th>
)}
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
{quarterPeriods?.current_quarter}-{quarterPeriods?.current_year} (Current Quarter)
</th>
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
{quarterPeriods?.forecast_quarter}-{quarterPeriods?.forecast_year} (Next Quarter)
</th>
{!shouldHideForecast && (
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
{quarterPeriods?.forecast_quarter}-{quarterPeriods?.forecast_year} (Next Quarter)
</th>
)}
</>
)}
</tr>
@ -1046,21 +1073,25 @@ if (!establishment) {
{/* Second header row */}
<tr className="bg-white text-[13px] font-medium">
{isLoading ? (
<th colSpan="9" className="py-2">Loading months...</th>
<th colSpan={shouldHidePreviousQuarter && shouldHideForecast ? "3" : (shouldHidePreviousQuarter || shouldHideForecast ? "6" : "9")} className="py-2">Loading months...</th>
) : error ? (
<th colSpan="9" className="py-2 text-red-500">{error}</th>
<th colSpan={shouldHidePreviousQuarter && shouldHideForecast ? "3" : (shouldHidePreviousQuarter || shouldHideForecast ? "6" : "9")} className="py-2 text-red-500">{error}</th>
) : (
<>
{/* Previous Quarter Months */}
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{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>
{!shouldHidePreviousQuarter && (
<>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{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]">
@ -1074,15 +1105,19 @@ if (!establishment) {
</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>
{!shouldHideForecast && (
<>
<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>
@ -1094,15 +1129,23 @@ if (!establishment) {
<td className="border border-gray-300 py-2 px-3 text-left font-medium">
Quantity ({product.unit || 'units'})
</td>
<td className="border border-gray-300 py-2">{product.q4_oct_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_nov_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_dec_quantity || '—'}</td>
{!shouldHidePreviousQuarter && (
<>
<td className="border border-gray-300 py-2">{product.q4_oct_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_nov_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_dec_quantity || '—'}</td>
</>
)}
<td className="border border-gray-300 py-2">{product.q1_jan_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q1_feb_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q1_mar_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_apr_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_may_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_jun_quantity || '—'}</td>
{!shouldHideForecast && (
<>
<td className="border border-gray-300 py-2">{product.q2_apr_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_may_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_jun_quantity || '—'}</td>
</>
)}
</tr>
{/* Cost Row */}
@ -1110,15 +1153,23 @@ if (!establishment) {
<td className="border border-gray-300 py-2 px-3 text-left font-medium">
Value (AED)
</td>
<td className="border border-gray-300 py-2">{product.q4_oct_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_nov_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_dec_cost || '—'}</td>
{!shouldHidePreviousQuarter && (
<>
<td className="border border-gray-300 py-2">{product.q4_oct_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_nov_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_dec_cost || '—'}</td>
</>
)}
<td className="border border-gray-300 py-2">{product.q1_jan_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q1_feb_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q1_mar_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_apr_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_may_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_jun_cost || '—'}</td>
{!shouldHideForecast && (
<>
<td className="border border-gray-300 py-2">{product.q2_apr_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_may_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_jun_cost || '—'}</td>
</>
)}
</tr>
{/* Reason Current */}
@ -1126,9 +1177,11 @@ if (!establishment) {
<td className="border border-gray-300 py-2 px-3 text-left font-medium">
Reason (Current)
</td>
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
)}
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#F3FAF4] text-[#2F663C]">
<div className="flex flex-col items-center">
{product.otherVariationReason ? (
@ -1138,9 +1191,11 @@ if (!establishment) {
)}
</div>
</td>
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
{!shouldHideForecast && (
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
)}
</tr>
{/* Reason Forecast */}
@ -1148,18 +1203,25 @@ if (!establishment) {
<td className="border border-gray-300 py-2 px-3 text-left font-medium">
Reason (Forecast)
</td>
<td colSpan="6" className="border border-gray-300 py-2 text-center">
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
)}
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]">
<div className="flex flex-col items-center">
{product.otherZeroTargetReason ? (
<div className="text-sm">{product.otherZeroTargetReason}</div>
) : (
<div>{product.zeroTargetReasonName?.replace('Others: ', '') || product.zeroTargetReason?.replace('Others: ', '') || '—'}</div>
)}
</div>
</td>
{!shouldHideForecast && (
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]">
<div className="flex flex-col items-center">
{product.otherZeroTargetReason ? (
<div className="text-sm">{product.otherZeroTargetReason}</div>
) : (
<div>{product.zeroTargetReasonName?.replace('Others: ', '') || product.zeroTargetReason?.replace('Others: ', '') || '—'}</div>
)}
</div>
</td>
)}
</tr>
</tbody>
</table>

View File

@ -393,6 +393,29 @@ const ValidationReview = () => {
const [additionalForecastMonths, setAdditionalForecastMonths] = React.useState(['', '', '']);
const [emirates, setEmirates] = useState([]);
// Determine if we should hide PREVIOUS QUARTER section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHidePreviousQuarter = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || new Date().getFullYear()).toString();
const rawQuarter = quarterPeriods?.current_quarter || 'Q1';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return (effectiveYear === '2022' && normalizedQuarter === 'Q1') ||
(effectiveYear === '2025' && normalizedQuarter === 'Q1');
}, [quarterPeriods]);
// Determine if we should hide FORECAST section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHideForecast = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || new Date().getFullYear()).toString();
const rawQuarter = quarterPeriods?.current_quarter || 'Q1';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return effectiveYear === '2022' && normalizedQuarter === 'Q4';
}, [quarterPeriods]);
React.useEffect(() => {
const fetchSubmission = async () => {
if (!id) {
@ -1160,31 +1183,39 @@ setAdditionalForecastMonths([
{showPreviousNext ? (
<>
{/* 12 columns when showPreviousNext is true */}
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{previousLabel || 'Q1 2024'} (PREVIOUS QUARTER)
</th>
{!shouldHidePreviousQuarter && (
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{previousLabel || 'Q1 2024'} (PREVIOUS QUARTER)
</th>
)}
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{currentLabel || 'Q2 2024'} (CURRENT QUARTER)
</th>
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{additionalForecastLabel || ''} (PREVIOUS FORECAST)
</th>
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{forecastLabel || 'Q3 2024'} (NEXT YEAR FORECAST)
</th>
{!shouldHideForecast && (
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{forecastLabel || 'Q3 2024'} (NEXT YEAR FORECAST)
</th>
)}
</>
) : (
<>
{/* 9 columns when showPreviousNext is false */}
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{previousLabel || 'Q1 2024'} (PREVIOUS QUARTER)
</th>
{!shouldHidePreviousQuarter && (
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{previousLabel || 'Q1 2024'} (PREVIOUS QUARTER)
</th>
)}
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{currentLabel || 'Q2 2024'} (CURRENT QUARTER)
</th>
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{forecastLabel || 'Q3 2024'} (NEXT YEAR FORECAST)
</th>
{!shouldHideForecast && (
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{forecastLabel || 'Q3 2024'} (NEXT YEAR FORECAST)
</th>
)}
</>
)}
</tr>
@ -1193,15 +1224,19 @@ setAdditionalForecastMonths([
{showPreviousNext ? (
<>
{/* Previous Quarter Months */}
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_one || 'Jan'}
</th>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_two || 'Feb'}
</th>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_three || 'Mar'}
</th>
{!shouldHidePreviousQuarter && (
<>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_one || 'Jan'}
</th>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_two || 'Feb'}
</th>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_three || 'Mar'}
</th>
</>
)}
{/* Current Quarter Months */}
<th className="bg-[#F3FAF4] px-3 py-2 font-medium text-[#2F663C] border border-[#E5E7EB] text-center min-w-[100px]">
@ -1226,28 +1261,36 @@ setAdditionalForecastMonths([
</th>
{/* Next Year Forecast Months */}
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_one || 'Oct'}
</th>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_two || 'Nov'}
</th>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_three || 'Dec'}
</th>
{!shouldHideForecast && (
<>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_one || 'Oct'}
</th>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_two || 'Nov'}
</th>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_three || 'Dec'}
</th>
</>
)}
</>
) : (
<>
{/* Previous Quarter Months */}
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_one || 'Jan'}
</th>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_two || 'Feb'}
</th>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_three || 'Mar'}
</th>
{!shouldHidePreviousQuarter && (
<>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_one || 'Jan'}
</th>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_two || 'Feb'}
</th>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_three || 'Mar'}
</th>
</>
)}
{/* Current Quarter Months */}
<th className="bg-[#F3FAF4] px-3 py-2 font-medium text-[#2F663C] border border-[#E5E7EB] text-center min-w-[100px]">
@ -1261,15 +1304,19 @@ setAdditionalForecastMonths([
</th>
{/* Next Year Forecast Months */}
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_one || 'Jul'}
</th>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_two || 'Aug'}
</th>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_three || 'Sep'}
</th>
{!shouldHideForecast && (
<>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_one || 'Jul'}
</th>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_two || 'Aug'}
</th>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_three || 'Sep'}
</th>
</>
)}
</>
)}
</tr>
@ -1284,50 +1331,54 @@ setAdditionalForecastMonths([
{showPreviousNext ? (
<>
{/* Previous Quarter Month 1 (BASE) - NO VARIANCE */}
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_quantity_period_one || "0"}
</span>
</div>
</td>
{!shouldHidePreviousQuarter && (
<>
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_quantity_period_one || "0"}
</span>
</div>
</td>
{/* Previous Quarter Month 2 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)} ${getBorderClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_quantity_period_two || "0"}
</span>
{/* If previous quarter has values, show variance from 2nd column */}
{!isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_one,
product.previous_quantity_period_two
)}
</div>
</td>
{/* Previous Quarter Month 2 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)} ${getBorderClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_quantity_period_two || "0"}
</span>
{/* If previous quarter has values, show variance from 2nd column */}
{!isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_one,
product.previous_quantity_period_two
)}
</div>
</td>
{/* Previous Quarter Month 3 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_quantity_period_three || "0"}
</span>
{/* If previous quarter has values, show variance */}
{!isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_two,
product.previous_quantity_period_three
)}
</div>
</td>
{/* Previous Quarter Month 3 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_quantity_period_three || "0"}
</span>
{/* If previous quarter has values, show variance */}
{!isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_two,
product.previous_quantity_period_three
)}
</div>
</td>
</>
)}
{/* Current Quarter Month 1 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_three, product.current_quantity_period_one, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_three, product.current_quantity_period_one, isPreviousQuarterAllZeros)}`}>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(shouldHidePreviousQuarter ? null : product.previous_quantity_period_three, product.current_quantity_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterAllZeros)} ${getBorderClass(shouldHidePreviousQuarter ? null : product.previous_quantity_period_three, product.current_quantity_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.current_quantity_period_one || "0"}
</span>
{/* If previous quarter is all zeros, treat this as FIRST month */}
{!isPreviousQuarterAllZeros && getVarianceDisplay(
{!shouldHidePreviousQuarter && !isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_three,
product.current_quantity_period_one
)}
@ -1390,61 +1441,71 @@ setAdditionalForecastMonths([
})()}
{/* NEXT YEAR FORECAST Data (original from submission) */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_three, product.forecast_quantity_period_one, false)} ${getBorderClass(product.current_quantity_period_three, product.forecast_quantity_period_one, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_quantity_period_one || '0'}</span>
{getVarianceDisplay(product.current_quantity_period_three, product.forecast_quantity_period_one)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two, false)} ${getBorderClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_quantity_period_two || '0'}</span>
{getVarianceDisplay(product.forecast_quantity_period_one, product.forecast_quantity_period_two)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three, false)} ${getBorderClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_quantity_period_three || '0'}</span>
{getVarianceDisplay(product.forecast_quantity_period_two, product.forecast_quantity_period_three)}
</div>
</td>
{!shouldHideForecast && (
<>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_three, product.forecast_quantity_period_one, false)} ${getBorderClass(product.current_quantity_period_three, product.forecast_quantity_period_one, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_quantity_period_one || '0'}</span>
{getVarianceDisplay(product.current_quantity_period_three, product.forecast_quantity_period_one)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two, false)} ${getBorderClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_quantity_period_two || '0'}</span>
{getVarianceDisplay(product.forecast_quantity_period_one, product.forecast_quantity_period_two)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three, false)} ${getBorderClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_quantity_period_three || '0'}</span>
{getVarianceDisplay(product.forecast_quantity_period_two, product.forecast_quantity_period_three)}
</div>
</td>
</>
)}
</>
) : (
<>
{/* Previous Quarter Month 1 */}
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_quantity_period_one || '0'}</span>
</div>
</td>
{!shouldHidePreviousQuarter && (
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_quantity_period_one || '0'}</span>
</div>
</td>
)}
{/* Previous Quarter Month 2 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)} ${getBorderClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_quantity_period_two || '0'}</span>
{!isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_one,
product.previous_quantity_period_two
)}
</div>
</td>
{!shouldHidePreviousQuarter && (
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)} ${getBorderClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_quantity_period_two || '0'}</span>
{!isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_one,
product.previous_quantity_period_two
)}
</div>
</td>
)}
{/* Previous Quarter Month 3 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_quantity_period_three || '0'}</span>
{!isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_two,
product.previous_quantity_period_three
)}
</div>
</td>
{!shouldHidePreviousQuarter && (
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_quantity_period_three || '0'}</span>
{!isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_two,
product.previous_quantity_period_three
)}
</div>
</td>
)}
{/* Current Quarter Month 1 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_three, product.current_quantity_period_one, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_three, product.current_quantity_period_one, isPreviousQuarterAllZeros)}`}>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(shouldHidePreviousQuarter ? null : product.previous_quantity_period_three, product.current_quantity_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterAllZeros)} ${getBorderClass(shouldHidePreviousQuarter ? null : product.previous_quantity_period_three, product.current_quantity_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.current_quantity_period_one || '0'}</span>
{!isPreviousQuarterAllZeros && getVarianceDisplay(
{!shouldHidePreviousQuarter && !isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_three,
product.current_quantity_period_one
)}
@ -1517,45 +1578,49 @@ setAdditionalForecastMonths([
{showPreviousNext ? (
<>
{/* Previous Cost Month 1 (BASE) - NO VARIANCE */}
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_cost_period_one || "0"}
</span>
</div>
</td>
{!shouldHidePreviousQuarter && (
<>
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_cost_period_one || "0"}
</span>
</div>
</td>
{/* Previous Cost Month 2 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_one, product.previous_cost_period_two, true)} ${getBorderClass(product.previous_cost_period_one, product.previous_cost_period_two, true)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_cost_period_two || "0"}
</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_one,
product.previous_cost_period_two
)}
</div>
</td>
{/* Previous Cost Month 2 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_one, product.previous_cost_period_two, true)} ${getBorderClass(product.previous_cost_period_one, product.previous_cost_period_two, true)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_cost_period_two || "0"}
</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_one,
product.previous_cost_period_two
)}
</div>
</td>
{/* Previous Cost Month 3 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_cost_period_three || "0"}
</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_two,
product.previous_cost_period_three
)}
</div>
</td>
{/* Previous Cost Month 3 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">
{product.previous_cost_period_three || "0"}
</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_two,
product.previous_cost_period_three
)}
</div>
</td>
</>
)}
{/* Current Quarter Cost Month 1 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_three, product.current_cost_period_one, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_three, product.current_cost_period_one, isPreviousQuarterCostAllZeros)}`}>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(shouldHidePreviousQuarter ? null : product.previous_cost_period_three, product.current_cost_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterCostAllZeros)} ${getBorderClass(shouldHidePreviousQuarter ? null : product.previous_cost_period_three, product.current_cost_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterCostAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.current_cost_period_one || '0'}</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(product.previous_cost_period_three, product.current_cost_period_one)}
{!shouldHidePreviousQuarter && !isPreviousQuarterCostAllZeros && getVarianceDisplay(product.previous_cost_period_three, product.current_cost_period_one)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_one, product.current_cost_period_two, false)} ${getBorderClass(product.current_cost_period_one, product.current_cost_period_two, false)}`}>
@ -1599,61 +1664,71 @@ setAdditionalForecastMonths([
})()}
{/* NEXT YEAR FORECAST Cost (original from submission) */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, product.forecast_cost_period_one, false)} ${getBorderClass(product.current_cost_period_three, product.forecast_cost_period_one, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_one || '0'}</span>
{getVarianceDisplay(product.current_cost_period_three, product.forecast_cost_period_one)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)} ${getBorderClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_two || '0'}</span>
{getVarianceDisplay(product.forecast_cost_period_one, product.forecast_cost_period_two)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)} ${getBorderClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_three || '0'}</span>
{getVarianceDisplay(product.forecast_cost_period_two, product.forecast_cost_period_three)}
</div>
</td>
{!shouldHideForecast && (
<>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, product.forecast_cost_period_one, false)} ${getBorderClass(product.current_cost_period_three, product.forecast_cost_period_one, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_one || '0'}</span>
{getVarianceDisplay(product.current_cost_period_three, product.forecast_cost_period_one)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)} ${getBorderClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_two || '0'}</span>
{getVarianceDisplay(product.forecast_cost_period_one, product.forecast_cost_period_two)}
</div>
</td>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)} ${getBorderClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_three || '0'}</span>
{getVarianceDisplay(product.forecast_cost_period_two, product.forecast_cost_period_three)}
</div>
</td>
</>
)}
</>
) : (
<>
{/* Previous Cost Month 1 */}
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_cost_period_one || '0'}</span>
</div>
</td>
{!shouldHidePreviousQuarter && (
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_cost_period_one || '0'}</span>
</div>
</td>
)}
{/* Previous Cost Month 2 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_one, product.previous_cost_period_two, true)} ${getBorderClass(product.previous_cost_period_one, product.previous_cost_period_two, true)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_cost_period_two || '0'}</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_one,
product.previous_cost_period_two
)}
</div>
</td>
{!shouldHidePreviousQuarter && (
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_one, product.previous_cost_period_two, true)} ${getBorderClass(product.previous_cost_period_one, product.previous_cost_period_two, true)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_cost_period_two || '0'}</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_one,
product.previous_cost_period_two
)}
</div>
</td>
)}
{/* Previous Cost Month 3 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_cost_period_three || '0'}</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_two,
product.previous_cost_period_three
)}
</div>
</td>
{!shouldHidePreviousQuarter && (
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.previous_cost_period_three || '0'}</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_two,
product.previous_cost_period_three
)}
</div>
</td>
)}
{/* Current Cost Month 1 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_three, product.current_cost_period_one, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_three, product.current_cost_period_one, isPreviousQuarterCostAllZeros)}`}>
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(shouldHidePreviousQuarter ? null : product.previous_cost_period_three, product.current_cost_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterCostAllZeros)} ${getBorderClass(shouldHidePreviousQuarter ? null : product.previous_cost_period_three, product.current_cost_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterCostAllZeros)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.current_cost_period_one || '0'}</span>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
{!shouldHidePreviousQuarter && !isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_three,
product.current_cost_period_one
)}
@ -1683,37 +1758,43 @@ setAdditionalForecastMonths([
</td>
{/* Forecast Cost Month 1 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, product.forecast_cost_period_one, false)} ${getBorderClass(product.current_cost_period_three, product.forecast_cost_period_one, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_one || '0'}</span>
{getVarianceDisplay(
product.current_cost_period_three,
product.forecast_cost_period_one
)}
</div>
</td>
{!shouldHideForecast && (
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, product.forecast_cost_period_one, false)} ${getBorderClass(product.current_cost_period_three, product.forecast_cost_period_one, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_one || '0'}</span>
{getVarianceDisplay(
product.current_cost_period_three,
product.forecast_cost_period_one
)}
</div>
</td>
)}
{/* Forecast Cost Month 2 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)} ${getBorderClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_two || '0'}</span>
{getVarianceDisplay(
product.forecast_cost_period_one,
product.forecast_cost_period_two
)}
</div>
</td>
{!shouldHideForecast && (
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)} ${getBorderClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_two || '0'}</span>
{getVarianceDisplay(
product.forecast_cost_period_one,
product.forecast_cost_period_two
)}
</div>
</td>
)}
{/* Forecast Cost Month 3 */}
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)} ${getBorderClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_three || '0'}</span>
{getVarianceDisplay(
product.forecast_cost_period_two,
product.forecast_cost_period_three
)}
</div>
</td>
{!shouldHideForecast && (
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)} ${getBorderClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)}`}>
<div className="flex flex-col items-center justify-center">
<span className="font-medium">{product.forecast_cost_period_three || '0'}</span>
{getVarianceDisplay(
product.forecast_cost_period_two,
product.forecast_cost_period_three
)}
</div>
</td>
)}
</>
)}
</tr>
@ -1724,9 +1805,11 @@ setAdditionalForecastMonths([
</td>
{showPreviousNext ? (
<>
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
)}
<td colSpan="3" className="px-4 py-3 text-center bg-[#E9F6EC] text-[#1E7C34] font-medium border border-[#E5E7EB]">
{product.other_variation_reason ||
(product?.variation_reason?.reason ?
@ -1738,18 +1821,19 @@ setAdditionalForecastMonths([
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
{/* Next Year Forecast (colSpan 3) */}
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
{!shouldHideForecast && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
)}
</>
) : (
<>
{/* Previous Quarter (colSpan 3) */}
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
{/* Current Quarter (colSpan 3) */}
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
)}
<td colSpan="3" className="px-4 py-3 text-center bg-[#E9F6EC] text-[#1E7C34] font-medium border border-[#E5E7EB]">
{product.other_variation_reason ||
(product?.variation_reason?.reason ?
@ -1757,10 +1841,11 @@ setAdditionalForecastMonths([
: 'No reason provided')
}
</td>
{/* Next Year Forecast (colSpan 3) */}
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
{!shouldHideForecast && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
)}
</>
)}
</tr>
@ -1771,38 +1856,46 @@ setAdditionalForecastMonths([
</td>
{showPreviousNext ? (
<>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
)}
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
<td colSpan="3" className="px-4 py-3 text-center bg-[#FFF2E0] text-[#D97706] font-medium border border-[#E5E7EB]">
{product.other_zero_target_reason ||
(product?.zero_target_reason?.reason ?
(product.zero_target_reason.reason.startsWith('Other (specify)') ? '' : product.zero_target_reason.reason)
: 'No reason provided')
}
</td>
{!shouldHideForecast && (
<td colSpan="3" className="px-4 py-3 text-center bg-[#FFF2E0] text-[#D97706] font-medium border border-[#E5E7EB]">
{product.other_zero_target_reason ||
(product?.zero_target_reason?.reason ?
(product.zero_target_reason.reason.startsWith('Other (specify)') ? '' : product.zero_target_reason.reason)
: 'No reason provided')
}
</td>
)}
</>
) : (
<>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
)}
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
<td colSpan="3" className="px-4 py-3 text-center bg-[#FFF2E0] text-[#D97706] font-medium border border-[#E5E7EB]">
{product.other_zero_target_reason ||
(product?.zero_target_reason?.reason ?
(product.zero_target_reason.reason.startsWith('Other (specify)') ? '' : product.zero_target_reason.reason)
: 'No reason provided')
}
</td>
{!shouldHideForecast && (
<td colSpan="3" className="px-4 py-3 text-center bg-[#FFF2E0] text-[#D97706] font-medium border border-[#E5E7EB]">
{product.other_zero_target_reason ||
(product?.zero_target_reason?.reason ?
(product.zero_target_reason.reason.startsWith('Other (specify)') ? '' : product.zero_target_reason.reason)
: 'No reason provided')
}
</td>
)}
</>
)}
</tr>

View File

@ -2567,6 +2567,16 @@ const handleView = async (id) => {
}
}
// ISIC code validation for industryCodeBusiness field
if (field === 'industryCodeBusiness' && value) {
if (!/^\d+$/.test(value)) {
return 'ISIC code must contain only digits';
}
if (value.length < 10 || value.length > 32) {
return 'Industry Code must be between 10 and 32 digits';
}
}
const numericFields = [
'employmentEmiratiMale',
'employmentEmiratiFemale',