From 318d35235d2e09742d86632d11975c38d250b404 Mon Sep 17 00:00:00 2001 From: Malini Date: Sat, 22 Nov 2025 17:34:44 +0530 Subject: [PATCH] added flag for products --- ipi-survey-platform/package-lock.json | 10 ++ ipi-survey-platform/package.json | 1 + .../survey/ProductData/ProductData.jsx | 2 +- .../Admin/configuration/CompanyProfile.jsx | 134 ++++++++++++++---- .../configuration/EditCompanyProfile.jsx | 90 +++++++++--- 5 files changed, 183 insertions(+), 54 deletions(-) diff --git a/ipi-survey-platform/package-lock.json b/ipi-survey-platform/package-lock.json index 7f6674b..84c0e49 100644 --- a/ipi-survey-platform/package-lock.json +++ b/ipi-survey-platform/package-lock.json @@ -13,6 +13,7 @@ "react": "^19.1.1", "react-dom": "^19.1.1", "react-google-recaptcha": "^3.1.0", + "react-icons": "^5.5.0", "react-router-dom": "^7.9.4", "react-toastify": "^11.0.5" }, @@ -3568,6 +3569,15 @@ "react": ">=16.4.1" } }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/ipi-survey-platform/package.json b/ipi-survey-platform/package.json index a310338..62e3856 100644 --- a/ipi-survey-platform/package.json +++ b/ipi-survey-platform/package.json @@ -15,6 +15,7 @@ "react": "^19.1.1", "react-dom": "^19.1.1", "react-google-recaptcha": "^3.1.0", + "react-icons": "^5.5.0", "react-router-dom": "^7.9.4", "react-toastify": "^11.0.5" }, diff --git a/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx b/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx index 445af95..9ba8da9 100644 --- a/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx +++ b/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx @@ -1389,7 +1389,7 @@ const location = useLocation(); }} loading={isLoadingUnits} error={!!formErrors[`unit_${idx}`]} - disabled={!!p.unitName} // Disable if unit is auto-filled from product + // disabled={!!p.unitName} // Disable if unit is auto-filled from product />
{formErrors[`unit_${idx}`] && ( diff --git a/ipi-survey-platform/src/pages/Admin/configuration/CompanyProfile.jsx b/ipi-survey-platform/src/pages/Admin/configuration/CompanyProfile.jsx index 16b588b..92bf19b 100644 --- a/ipi-survey-platform/src/pages/Admin/configuration/CompanyProfile.jsx +++ b/ipi-survey-platform/src/pages/Admin/configuration/CompanyProfile.jsx @@ -159,6 +159,7 @@ const createEmptyProfile = () => ({ industryCodeBusiness: '', industryCodeProduction: '', industryCodeCurrent: '', + industryCodeMismatchRemarks: '', industryDescription: '', // Establishment contact details contactName: '', @@ -816,6 +817,10 @@ const CompanyProfile = () => { }; const renderStepContent = () => { + const fieldProps = (fieldName) => ({ + disabled: modalMode === 'view', + error: fieldErrors[fieldName] + }); switch (activeStep) { case 0: return ( @@ -831,6 +836,8 @@ const CompanyProfile = () => { width="100%" required error={fieldErrors.userProfileName} + {...fieldProps('userProfileName')} + /> {
+ {/*
+ +
*/}
)} @@ -1449,7 +1468,7 @@ const CompanyProfile = () => { showToast('success', `Establishment ${newStatus ? 'activated' : 'deactivated'} successfully`); } catch (error) { console.error('Error updating status:', error); - const message = error?.response?.data?.message || 'Failed to update status. Please try again.'; + const message = error?.response?.data?.message || error?.message || 'Failed to update status. Please try again.'; showToast('error', message); } }; @@ -1805,6 +1824,7 @@ const displayedRows = filteredProfiles.map((item) => { industryCodeBusiness: item?.industry_code, industryCodeProduction: item?.industry_code_production, industryCodeCurrent: item?.industryCodeCurrent, + industryCodeMismatchRemarks: item?.industry_code_mismatch_remarks ?? '', industryDescription: item?.description ?? base.industryDescription, establishmentId: item?.establishment_code ?? '', contactAddress: item?.establishment_address ?? base.contactAddress, @@ -2116,13 +2136,47 @@ const displayedRows = filteredProfiles.map((item) => { } }; - const handleView = async (id) => { +// 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 handleView = async (id) => { try { setIsLoading(true); const response = await fetchEstablishmentDetail(id); const establishment = mapApiEstablishmentToProfile(response.data); setForm(establishment); - setSelectedProducts(establishment.products || []); + + // Format products data before setting to state + const formattedProducts = (response.data.establishment_products || []).map(item => { + const product = item.product || {}; + const productName = product.product_name || 'Unnamed Product'; + const hsCode = product.hs_code || ''; + + return { + ...item, + ...product, + product_name: productName, + hs_code: hsCode, + label: `${productName}${hsCode ? ` (${hsCode})` : ''}`, + value: item.product_id ? String(item.product_id) : '', + }; + }); + + setSelectedProducts(formattedProducts); setModalMode('view'); setIsViewMode(true); setEditingRow(id); @@ -2133,7 +2187,6 @@ const displayedRows = filteredProfiles.map((item) => { setIsLoading(false); } }; - const handleDelete = (establishmentId) => { if (!establishmentId) return; const originalIndex = profiles.findIndex((item) => { @@ -2507,6 +2560,7 @@ const displayedRows = filteredProfiles.map((item) => { permanent_factory_code: form.permanentFactoryCode || '', industry_code: form.industryCodeBusiness || '', industry_code_production: form.industryCodeProduction || form.industryCodeCurrent || '', + industry_code_mismatch_remarks: form.industryCodeMismatchRemarks || '', license_number: form.uniqueLicenseNumber || '', isic_code: form.industryCodeProduction || '', description: form.industryDescription || '', @@ -2548,7 +2602,8 @@ const displayedRows = filteredProfiles.map((item) => { password: form.userProfilePassword || '' }, establishment_products: Array.isArray(selectedProducts) && selectedProducts.length > 0 - ? selectedProducts.map(p => ({ product_id: p.id || p.product_id || 0 })) + ? selectedProducts.map(p => ({ product_id: p.id || p.product_id || 0 + })) : [], }; @@ -2612,6 +2667,7 @@ const displayedRows = filteredProfiles.map((item) => { permanent_factory_code: form.permanentFactoryCode || '', industry_code: form.industryCodeBusiness || '', industry_code_production: form.industryCodeProduction || form.industryCodeCurrent || '', + industry_code_mismatch_remarks: form.industryCodeMismatchRemarks || '', license_number: form.uniqueLicenseNumber || '', isic_code: form.industryCodeProduction || '', description: form.industryDescription || '', @@ -2650,7 +2706,10 @@ const displayedRows = filteredProfiles.map((item) => { // Enhanced product handling for updates - only send product IDs that exist establishment_products: Array.isArray(selectedProducts) && selectedProducts.length > 0 ? selectedProducts.map(p => ({ - product_id: p.product_id || p.id || 0 + product_id: p.product_id || p.id || 0, + action_done_by: "admin_user" , + created_by: currentUserId?.id + })) : [] }; @@ -2784,7 +2843,7 @@ const displayedRows = filteredProfiles.map((item) => { }; React.useEffect(() => { - if (!modalMode) return undefined; + if (!modalMode || isViewMode) return undefined; const handleBeforeUnload = (event) => { if (isDirty) { event.preventDefault(); @@ -2795,7 +2854,7 @@ const displayedRows = filteredProfiles.map((item) => { return () => { window.removeEventListener('beforeunload', handleBeforeUnload); }; - }, [isDirty, modalMode]); + }, [isDirty, modalMode, isViewMode]); const deletingProfile = React.useMemo(() => { if (deletingRow === null || deletingRow < 0 || deletingRow >= profiles.length) return null; @@ -3070,7 +3129,8 @@ const handleImport = async () => { >

- {modalMode === 'edit' ? 'Edit Company Profile' : 'Add Profile'} + {/* {modalMode === 'edit' ? 'Edit Company Profile' : 'Add Profile'} */} + {isViewMode ? 'View Profile' : modalMode === 'edit' ? 'Edit Profile' : 'Add Profile'}

{activeStep === formSteps.length - 1 ? ( -
- - -
+ isViewMode ? ( +
+ +
+ ) : ( +
+ + +
+ ) ) : (
{activeStep > 0 && ( diff --git a/ipi-survey-platform/src/pages/Admin/configuration/EditCompanyProfile.jsx b/ipi-survey-platform/src/pages/Admin/configuration/EditCompanyProfile.jsx index 00bbf48..22262bd 100644 --- a/ipi-survey-platform/src/pages/Admin/configuration/EditCompanyProfile.jsx +++ b/ipi-survey-platform/src/pages/Admin/configuration/EditCompanyProfile.jsx @@ -1,5 +1,7 @@ import React, { useState, useMemo, useCallback, useEffect, useRef } from "react"; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; +import { FaBuilding } from 'react-icons/fa6'; +import { MdAdminPanelSettings } from "react-icons/md"; import { TextField, SelectField, PhoneField } from "@/components/common/FormControls"; import Loader from "@/components/common/Loader"; import { fetchEstablishmentDetail, updateEstablishment } from '@/services/establishments/establishmentService'; @@ -14,6 +16,7 @@ const createEmptyProfile = () => ({ uniqueLicenseNumber: '', industryCodeBusiness: '', industryCodeCurrent: '', + industryCodeMismatchRemarks: '', contactName: '', contactAddress: '', contactCityTown: '', @@ -39,8 +42,9 @@ const mapApiEstablishmentToProfile = (apiData) => { userProfileEmail: data.users?.[0]?.email || '', permanentFactoryCode: data.permanent_factory_code || '', uniqueLicenseNumber: data.license_number || '', - industryCodeBusiness: data.isic_code || '', - industryCodeCurrent: data.isic_code || '', + industryCodeBusiness: data.industry_code_production || '', + industryCodeCurrent: data.industry_code || '', + industryCodeMismatchRemarks: data.industry_code_mismatch_remarks || '', contactName: data.factory_name || '', contactAddress: data.establishment_address || '', contactCityTown: data.establishment_city?.name || '', @@ -77,8 +81,6 @@ const computeEmploymentTotals = (data) => { const EditCompanyProfile = () => { const navigate = useNavigate(); const { id: establishmentId } = useParams(); - console.log('EditCompanyProfile mounted, establishmentId from params:', establishmentId); - const [loading, setLoading] = useState(false); const [form, setForm] = useState(createEmptyProfile()); const [activeStep, setActiveStep] = useState(0); @@ -412,12 +414,15 @@ const EditCompanyProfile = () => { // Find the product in the loaded products to get the proper format const foundProduct = allProducts.find(p => p.value === String(productId)); - return foundProduct || { - value: String(productId), - label: productData.product_name || productData.name || 'Unnamed Product', - hs_code: productData.hs_code || '', - product_name: productData.product_name || productData.name || 'Unnamed Product', - isExisting: true // Mark as existing product + return { + ...(foundProduct || { + value: String(productId), + label: productData.product_name || productData.name || 'Unnamed Product', + hs_code: productData.hs_code || '', + product_name: productData.product_name || productData.name || 'Unnamed Product', + isExisting: true // Mark as existing product + }), + action_done_by: ep.action_done_by // Add the action_done_by field from the API response }; }); @@ -503,7 +508,7 @@ const EditCompanyProfile = () => { permanent_factory_code: form.permanentFactoryCode || "", industry_code: form.industryCodeBusiness || "", license_number: form.uniqueLicenseNumber || "", - isic_code: form.industryCodeCurrent || "", + industry_code_production: form.industryCodeCurrent || "", description: form.industryDescription || "", establishment_address: form.contactAddress || "", establishment_city_town_id: selectedCity ? Number(selectedCity.value) : null, @@ -531,7 +536,10 @@ const EditCompanyProfile = () => { updated_by: 1, establishment_products: Array.isArray(selectedProducts) && selectedProducts.length > 0 ? selectedProducts.map(p => ({ - product_id: Number(p.value) || 0 + product_id: Number(p.value) || 0, + action_done_by: p.action_done_by || "establishment_users", + created_by: p.created_by || establishmentId + })) : [], }; @@ -655,6 +663,21 @@ const EditCompanyProfile = () => { rows={3} />
+{form.industryCodeCurrent && form.industryCodeBusiness !== form.industryCodeCurrent && ( +
+ handleFormChange('industryCodeMismatchRemarks', e.target.value)} + placeholder="Enter remarks for industry code mismatch" + width="100%" + multiline + rows={3} + /> +
+)} + +
@@ -785,8 +808,24 @@ const EditCompanyProfile = () => { case 3: return (
-
-

Products

+
+ {/* Left side: Products Header */} +

Products

+ + {/* Right side: Icons */} +
+
+ + Admin User +
+ +
+ + Establishment User +
+
+ {/*
*/} + {productError && (

{productError}

)} @@ -865,15 +904,22 @@ const EditCompanyProfile = () => { const isNewlyAdded = newlyAddedProductIds.has(product.value); return (
  • -
    -
    - {product.label} -
    - {product.hs_code && ( -
    - HS Code: {product.hs_code} -
    +
    + {product.action_done_by === "admin_user" ? ( + + ) : ( + )} +
    +
    + {product.label} +
    + {product.hs_code && ( +
    + HS Code: {product.hs_code} +
    + )} +
    {isNewlyAdded && (