From 236743053e28ec0d4e35232bd4a4374099fcea4c Mon Sep 17 00:00:00 2001 From: Malini Date: Fri, 21 Nov 2025 20:39:59 +0530 Subject: [PATCH] fcsc bug fix --- .../src/components/dashboard/SurveyStatus.jsx | 2 +- .../EstablishmentInfo/EstablishmentInfo.jsx | 217 +++++++--- .../survey/ProductData/ProductData.jsx | 2 +- .../AdminUsers/ListAdminUsers.jsx | 9 +- .../Admin/configuration/CompanyProfile.jsx | 402 ++++++++++++------ .../configuration/EditCompanyProfile.jsx | 54 ++- .../pages/Admin/configuration/IsicHsCodes.jsx | 51 ++- .../pages/Admin/configuration/UnitMaster.jsx | 10 +- .../pages/LandingPage/component/Banner.jsx | 2 +- .../LandingPage/component/Industrial.jsx | 4 +- .../pages/LandingPage/component/Navbar.jsx | 4 +- .../pages/LandingPage/component/Survey.jsx | 2 +- ipi-survey-platform/src/pages/Login/Login.jsx | 2 +- 13 files changed, 535 insertions(+), 226 deletions(-) diff --git a/ipi-survey-platform/src/components/dashboard/SurveyStatus.jsx b/ipi-survey-platform/src/components/dashboard/SurveyStatus.jsx index c1622ff..d8bb5e3 100644 --- a/ipi-survey-platform/src/components/dashboard/SurveyStatus.jsx +++ b/ipi-survey-platform/src/components/dashboard/SurveyStatus.jsx @@ -119,7 +119,7 @@ export const SurveyStatus = () => { return { title: `${quarter} ${year} Survey`, - subtitle: 'Complete your quarterly Industrial Production Index (IPI) data submission', + subtitle: 'Complete your quarterly Index of Industrial Production (IIP) data submission', dueDate: formatDate(end_date), relativeDue: formatRelativeDays(end_date), estTime: '15–20 minutes', diff --git a/ipi-survey-platform/src/components/survey/EstablishmentInfo/EstablishmentInfo.jsx b/ipi-survey-platform/src/components/survey/EstablishmentInfo/EstablishmentInfo.jsx index 1fe541b..ffc3e39 100644 --- a/ipi-survey-platform/src/components/survey/EstablishmentInfo/EstablishmentInfo.jsx +++ b/ipi-survey-platform/src/components/survey/EstablishmentInfo/EstablishmentInfo.jsx @@ -1,4 +1,8 @@ -import React from 'react'; +import React, { useEffect, useState, useMemo } from 'react'; +import { useNavigate, useLocation } from 'react-router-dom'; +import { getEstablishmentProducts } from '../../../services/submissions/submissionService'; +import Table from '@/components/common/Table'; + const caretDownSrc = '/assets/images/CaretDown.svg'; const backVectorSrc = '/assets/images/BackVector.svg'; const mailIconSrc = '/assets/images/material-symbols_mail-outline.svg'; @@ -6,7 +10,6 @@ const phoneIconSrc = '/assets/images/line-md_phone.svg'; const calendarIcon = '/assets/images/Duedate.svg'; const clockIcon = '/assets/images/mingcute_time-line.svg'; const nextIcon = '/assets/images/mdi_page-next-outline.svg'; -import { useNavigate, useLocation } from 'react-router-dom'; const Field = ({ label, placeholder = '', type = 'text', value = '', onChange = () => {}, disabled = true }) => (
@@ -95,11 +98,40 @@ const EstablishmentInfo = ({ isComplete = false, }) => { const [showInfoCard, setShowInfoCard] = React.useState(true); + const [products, setProducts] = React.useState([]); + const [loadingProducts, setLoadingProducts] = React.useState(false); + const [productsError, setProductsError] = React.useState(''); const navigate = useNavigate(); const location = useLocation(); // Use a ref to persist the survey data across re-renders const surveyDataRef = React.useRef(null); + // Fetch establishment products + React.useEffect(() => { + const fetchProducts = async () => { + const establishmentId = sessionStorage.getItem('establishment_id'); + if (!establishmentId) return; + + setLoadingProducts(true); + try { + const response = await getEstablishmentProducts(establishmentId); + if (response.status === 'success') { + console.log('Products data:', response.data); // Log the products data + setProducts(response.data || []); + } else { + setProductsError(response.message || 'Failed to load products'); + } + } catch (error) { + console.error('Error fetching products:', error); + setProductsError('Failed to load products. Please try again later.'); + } finally { + setLoadingProducts(false); + } + }; + + fetchProducts(); + }, []); + const [surveyData, setSurveyData] = React.useState(() => { // Initialize from location state if available, otherwise use defaults if (location.state?.survey) { @@ -280,7 +312,7 @@ const EstablishmentInfo = ({
)}

- Industrial Production Index (IPI) Survey: {surveyData.quarter} {surveyData.year} + IIP (Index of Industrial Production): {surveyData.quarter} {surveyData.year}

{/* Survey Information */} @@ -309,7 +341,7 @@ const EstablishmentInfo = ({

- You're completing the IPI Quarterly Survey for {surveyData.quarter} {surveyData.year}. This step shows establishment details already registered with us. Step 1 is read-only. To make corrections, update them in Profile → Edit Profile, then return to this survey. + You're completing the IIP Quarterly Survey for {surveyData.quarter} {surveyData.year}. This step shows establishment details already registered with us. Step 1 is read-only. To make corrections, update them in Profile → Edit Profile, then return to this survey.

@@ -365,54 +397,7 @@ const EstablishmentInfo = ({
)} - {/* Blue Info Box */} -
- - - - {/*

- Need to update details? Go to{' '} - Profile → Edit Profile. Changes saved there will appear{' '} - - here - . -

*/} - {/*

- Need to update details? Go to Profile →{' '} - - Edit Profile - - . Changes saved there will appear here. -

*/} -

- Need to update details? Go to Profile →{' '} - - Edit Profile - - - . Changes saved there will appear here. -

-
+

Step 1: Review Establishment Information

{isComplete && ( @@ -532,6 +517,31 @@ const EstablishmentInfo = ({
+ +

Products

+ {loadingProducts ? ( +
+
+
+ ) : productsError ? ( +
{productsError}
+ ) : products.length > 0 ? ( + [ + product['product.product_name'] || 'N/A', + product['product.hs_code'] || 'N/A', + product['product.hs_description'] || 'N/A' + ])} + columnWidths={['33.33%', '33.33%', '33.33%']} + separated={true} + className="w-full" + /> + ) : ( +
No products found for this establishment.
+ )} + +
{/* Employee Information */} @@ -588,6 +598,109 @@ const EstablishmentInfo = ({
+ {/* +

Products

+ {loadingProducts ? ( +
+
+
+ ) : productsError ? ( +
{productsError}
+ ) : products.length > 0 ? ( +
+
+ + + + + + + + + + {products.map((product, index) => ( + + + + + + + ))} + +
+ Product Name + + HS Code + + Unit + + UOM +
+ {product['product.product_name'] || 'N/A'} + + {product['product.hs_code'] || 'N/A'} + + {product['product.unit.uom_short_name'] || 'N/A'} + + {product['product.unit.uom'] || 'N/A'} +
+
+ ) : ( +
No products found for this establishment.
+ )} +
*/} + {/* Products Table */} + + + {/* Blue Info Box */} +
+ + + + {/*

+ Need to update details? Go to{' '} + Profile → Edit Profile. Changes saved there will appear{' '} + + here + . +

*/} + {/*

+ Need to update details? Go to Profile →{' '} + + Edit Profile + + . Changes saved there will appear here. +

*/} +

+ Need to update details? Go to Profile →{' '} + + Edit Profile + + + . Changes saved there will appear here. +

+
+ {/* Footer actions */}
- - ))} - + + ) : (
{productSearchTerm ? 'No matching products found' : 'No products available'} @@ -1257,6 +1312,8 @@ const CompanyProfile = () => { !selectedProducts.some(sp => sp.id === p.id || sp.product_id === p.product_id) ); setAvailableProducts(available); + + } catch (error) { console.error('Error loading products:', error); @@ -1433,53 +1490,112 @@ const CompanyProfile = () => { ); }; - const displayedRows = filteredProfiles.map((item) => { - return [ - item.establishmentName, - item.userProfileName || item.contactPersonName || item.createdBy || '', - item.emirate, - item.isicCode, - item.establishmentId, - item.productCount ?? '0', - item.totalEmployees, - item.createdBy, - item.createdOn, - item.updated_at ? formatDate(item.updated_at) : (item.lastUpdated || '-'), - renderStatusBadge(item.status), - ( -
- - -
- ), - ]; - }); +const displayedRows = filteredProfiles.map((item) => { + return [ + // Establishment Name + item.establishmentName || "-", + + // Contact Name (userProfileName → contactPersonName → createdBy → "-") + item.userProfileName || item.contactPersonName || "-", + + // Emirate + item.emirate || "-", + + // ISIC Code + item.isicCode || "-", + + // Establishment ID + item.establishmentId || "-", + + // Product Count + item.productCount ?? "0", + + // Total Employees + item.totalEmployees || "-", + + // Created By + item.createdBy || "-", + + // Created On + item.createdOn || "-", + + // Updated On (formatted or fallback) + item.updated_at + ? formatDate(item.updated_at) + : (item.lastUpdated || "-"), + + // Status + renderStatusBadge(item.status), + + // Action Buttons + ( +
+ {/* Edit */} + + + {/* View */} + + + {/* Toggle Status */} + +
+ ), + ]; +}); + React.useEffect(() => { const handle = setTimeout(() => { @@ -1670,13 +1786,13 @@ const CompanyProfile = () => { let creatorName = '-'; if (currentUser && item?.created_by && currentUser.id === item.created_by) { - const name = currentUser.name || currentUser.username || `User ${item.created_by}`; + const name = currentUser.name || currentUser.username || ` ${item.created_by_name}`; creatorName = name.replace(/([a-zA-Z])([A-Z])/g, '$1 $2'); } else if (item?.created_by) { const name = item?.created_by_name || item?.created_by_user?.name || item?.creator?.name || - `User ${item.created_by}`; + ` ${item.created_by_name}`; creatorName = name.replace(/([a-zA-Z])([A-Z])/g, '$1 $2'); } @@ -2000,6 +2116,24 @@ const CompanyProfile = () => { } }; + const handleView = async (id) => { + try { + setIsLoading(true); + const response = await fetchEstablishmentDetail(id); + const establishment = mapApiEstablishmentToProfile(response.data); + setForm(establishment); + setSelectedProducts(establishment.products || []); + setModalMode('view'); + setIsViewMode(true); + setEditingRow(id); + } catch (error) { + console.error('Error fetching establishment details:', error); + showToast('error', 'Failed to load establishment details'); + } finally { + setIsLoading(false); + } +}; + const handleDelete = (establishmentId) => { if (!establishmentId) return; const originalIndex = profiles.findIndex((item) => { @@ -2798,7 +2932,7 @@ const handleImport = async () => {
-
+
{ - - ))} + {isNewlyAdded && ( + + )} + + ); + })} ) : (
diff --git a/ipi-survey-platform/src/pages/Admin/configuration/IsicHsCodes.jsx b/ipi-survey-platform/src/pages/Admin/configuration/IsicHsCodes.jsx index 8613eed..b663158 100644 --- a/ipi-survey-platform/src/pages/Admin/configuration/IsicHsCodes.jsx +++ b/ipi-survey-platform/src/pages/Admin/configuration/IsicHsCodes.jsx @@ -350,7 +350,7 @@ const IsicHsCodes = () => { const [deletingRow, setDeletingRow] = React.useState(null); const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false); const [currentPage, setCurrentPage] = React.useState(1); - const pageSize = 10; + const [pageSize, setPageSize] = React.useState(10); const [modalMode, setModalMode] = React.useState(null); const [form, setForm] = React.useState(createEmptyCodeForm()); const [unitOptions, setUnitOptions] = React.useState([]); @@ -484,6 +484,7 @@ const IsicHsCodes = () => { const headers = [ 'HS Code', 'Product Name', + 'Description', 'Unit', 'Establishment Mapped', 'Created By', @@ -500,7 +501,8 @@ const IsicHsCodes = () => { const filtered = rowsData.filter( (item) => item.code.toLowerCase().includes(lowercasedSearch) || - item.product.toLowerCase().includes(lowercasedSearch) + item.product.toLowerCase().includes(lowercasedSearch) || + item.description.toLowerCase().includes(lowercasedSearch) ); setFilteredData(filtered); } @@ -526,6 +528,7 @@ const IsicHsCodes = () => { return [ item.code, item.product, + item.description || '-', item.unit, item.estimatedMapped, displayName, @@ -550,9 +553,9 @@ const IsicHsCodes = () => { setForm({ code: product.hs_code || '', product: product.product_name || '', + description: product.hs_description || '', unit: product.unit_id ? String(product.unit_id) : '', status: product.is_active ? 'Active' : 'Inactive', - description: product.hs_description || '', createdBy: selected.createdBy, createdOn: selected.createdOn || new Date(product.created_at).toLocaleDateString('en-GB'), updated: selected.updated || (product.updated_at ? new Date(product.updated_at).toLocaleDateString('en-GB') : '') @@ -599,9 +602,9 @@ const IsicHsCodes = () => { id: productData.id, code: productData.hs_code || '', product: productData.product_name || '', + description: productData.hs_description || '', unit: productData.unit_id ? String(productData.unit_id) : '', status: productData.is_active ? 'Active' : 'Inactive', - description: productData.hs_description || '' }; console.log('Mapped form data:', formData); @@ -801,6 +804,7 @@ const IsicHsCodes = () => { return [ item.code, item.product, + item.description || '-', item.unit, item.estimatedMapped, item.createdBy, @@ -854,6 +858,7 @@ const IsicHsCodes = () => { const productData = { hs_code: form.code, product_name: form.product, + hs_description: form.description || '', unit_id: form.unit ? parseInt(form.unit) : null, // Preserve the original created_by value for updates, or use current user for new records created_by: modalMode === 'edit' ? (existingProduct?.created_by || userProfile?.id) : (userProfile?.id || null) @@ -890,6 +895,7 @@ const IsicHsCodes = () => { // Only update these specific fields code: form.code, product: form.product, + description: form.description || '', unit: selectedUnit ? selectedUnit.label : existingProduct?.unit || 'N/A', unit_id: form.unit ? parseInt(form.unit) : existingProduct?.unit_id || null, updated: new Date().toLocaleDateString('en-GB'), @@ -940,6 +946,7 @@ const IsicHsCodes = () => { id: response.data?.id || Date.now(), code: form.code, product: form.product, + description: form.description || '', unit: selectedUnit ? selectedUnit.label : 'N/A', unit_id: form.unit ? parseInt(form.unit) : null, estimatedMapped: 0, @@ -1031,6 +1038,7 @@ const IsicHsCodes = () => { id: product.id, code: product.hs_code || 'N/A', product: product.product_name || 'N/A', + description: product.hs_description || '', unit: product.unit?.uom || 'N/A', estimatedMapped: 0, createdBy: creatorName, @@ -1188,17 +1196,17 @@ const IsicHsCodes = () => { headers={headers} rows={rows} renderCell={(value, rowIndex, colIndex) => { - // Handle product name column (index 1) with text wrapping - if (colIndex === 1) { + // Handle product name and description columns with text wrapping + if (colIndex === 1 || colIndex === 2) { return ( -
+
{value}
); } - // Handle action buttons column (index 6) - if (colIndex === 6) { + // Handle action buttons column (index 7) + if (colIndex === 7) { return (
@@ -1394,8 +1407,10 @@ const IsicHsCodes = () => { placeholder="Enter Product Name" />
+ +
-
+
- + +
+ +