From f2ba68dd77584fbd832b19fcad457d803c1d7b45 Mon Sep 17 00:00:00 2001 From: Malini Date: Tue, 2 Dec 2025 09:54:42 +0530 Subject: [PATCH] added download sample --- .../EstablishmentInfo/EstablishmentInfo.jsx | 3 - .../survey/ProductData/ProductData.jsx | 2 - .../survey/ReviewSubmit/ReviewSubmit.jsx | 1 - .../AdminUsers/ListAdminUsers.jsx | 150 ++++++++- .../Admin/configuration/CompanyProfile.jsx | 288 +++++++++++++----- .../configuration/EditCompanyProfile.jsx | 239 ++++++++------- .../pages/Admin/configuration/IsicHsCodes.jsx | 69 +++-- .../pages/Admin/configuration/UnitMaster.jsx | 66 ++-- .../services/configuration/productService.js | 18 +- .../src/services/configuration/unitService.js | 20 +- .../establishments/establishmentService.js | 13 +- 11 files changed, 619 insertions(+), 250 deletions(-) diff --git a/ipi-survey-platform/src/components/survey/EstablishmentInfo/EstablishmentInfo.jsx b/ipi-survey-platform/src/components/survey/EstablishmentInfo/EstablishmentInfo.jsx index ffc3e39..5451ece 100644 --- a/ipi-survey-platform/src/components/survey/EstablishmentInfo/EstablishmentInfo.jsx +++ b/ipi-survey-platform/src/components/survey/EstablishmentInfo/EstablishmentInfo.jsx @@ -116,7 +116,6 @@ const EstablishmentInfo = ({ 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'); @@ -149,7 +148,6 @@ const EstablishmentInfo = ({ } // Or use current quarter/year as fallback const current = getCurrentQuarterAndYear(); - console.log('Using current quarter/year as fallback:', current); // Save to localStorage const surveyPeriod = { @@ -168,7 +166,6 @@ const EstablishmentInfo = ({ // Log when surveyData changes React.useEffect(() => { - console.log('surveyData updated:', surveyData); }, [surveyData]); // Update the ref whenever surveyData changes diff --git a/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx b/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx index d308512..93942fa 100644 --- a/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx +++ b/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx @@ -391,7 +391,6 @@ const ProductData = ({ setIsLoadingPeriods(true); const quarterNumber = periodQuarter.replace('Q', ''); // Convert 'Q3' to '3' - console.log('Fetching quarter periods with:', { year: periodYear, quarter: `Q${quarterNumber}` }); const response = await getQuarterPeriods(parseInt(periodYear), `Q${quarterNumber}`); setQuarterPeriods(response.data); } catch (error) { @@ -577,7 +576,6 @@ const location = useLocation(); year: year || '' })); }, [quarter, year]); - console.log("surveyDatatest", surveyData); const requiredMessage = 'Required'; const getAvailableProducts = (currentProductId) => { diff --git a/ipi-survey-platform/src/components/survey/ReviewSubmit/ReviewSubmit.jsx b/ipi-survey-platform/src/components/survey/ReviewSubmit/ReviewSubmit.jsx index b86d32e..251340a 100644 --- a/ipi-survey-platform/src/components/survey/ReviewSubmit/ReviewSubmit.jsx +++ b/ipi-survey-platform/src/components/survey/ReviewSubmit/ReviewSubmit.jsx @@ -236,7 +236,6 @@ const buildProductRows = (products = [], options = {}) => { _raw: { ...product } }; - // console.log(`Processed product ${index + 1}:`, row); // Debug log return row; } catch (error) { console.error(`Error processing product at index ${index}:`, error, product); diff --git a/ipi-survey-platform/src/pages/Admin/configuration/AdminUsers/ListAdminUsers.jsx b/ipi-survey-platform/src/pages/Admin/configuration/AdminUsers/ListAdminUsers.jsx index 34c9b01..326c364 100644 --- a/ipi-survey-platform/src/pages/Admin/configuration/AdminUsers/ListAdminUsers.jsx +++ b/ipi-survey-platform/src/pages/Admin/configuration/AdminUsers/ListAdminUsers.jsx @@ -93,6 +93,11 @@ const AdminUsers = () => { const [resettingPassword, setResettingPassword] = useState(false); const [resetErrors, setResetErrors] = useState({}); const [pageSize, setPageSize] = React.useState(10); + const [searchTerm, setSearchTerm] = useState(''); + const [sortConfig, setSortConfig] = useState({ + key: null, + direction: 'asc' + }); // Helper: show toast const showToast = (message, type = 'success') => { @@ -193,10 +198,127 @@ const AdminUsers = () => { }, ]; - const headers = ['Name', 'Email', 'Last Login', 'Status', 'Actions']; - const columnWidths = [100, 130, 150, 100, 130]; + const columnWidths = ['150px', '250px', '200px', '120px', '150px']; - const rows = users.map((user) => [ + const handleSort = (key) => { + let direction = 'asc'; + if (sortConfig.key === key && sortConfig.direction === 'asc') { + direction = 'desc'; + } + setSortConfig({ key, direction }); + }; + + const getSortedData = (data) => { + if (!sortConfig.key) return data; + + return [...data].sort((a, b) => { + // Handle different data types for sorting + let aValue = a[sortConfig.key]; + let bValue = b[sortConfig.key]; + + // For status, sort by the active/inactive state + if (sortConfig.key === 'status') { + aValue = a.is_active ? 1 : 0; + bValue = b.is_active ? 1 : 0; + } + + // For dates (lastLogin) + if (sortConfig.key === 'lastLogin' && aValue !== 'Never logged in' && bValue !== 'Never logged in') { + aValue = new Date(a.raw.updatedAt || a.raw.last_login || 0).getTime(); + bValue = new Date(b.raw.updatedAt || b.raw.last_login || 0).getTime(); + } + + // For string comparison + if (typeof aValue === 'string' && typeof bValue === 'string') { + aValue = aValue.toLowerCase(); + bValue = bValue.toLowerCase(); + } + + if (aValue < bValue) { + return sortConfig.direction === 'asc' ? -1 : 1; + } + if (aValue > bValue) { + return sortConfig.direction === 'asc' ? 1 : -1; + } + return 0; + }); + }; + + const headers = [ + { + name: 'Name', + key: 'name', + sortable: true + }, + { + name: 'Email', + key: 'email', + sortable: false + }, + { + name: 'Last Login', + key: 'lastLogin', + sortable: false + }, + { + name: 'Status', + key: 'status', + sortable: false + }, + { + name: 'Actions', + key: 'actions', + sortable: false + } + ].map(header => { + const baseClasses = "text-sm font-medium text-gray-700"; + + if (!header.sortable) { + return { + name: header.name, + className: 'text-left pl-6 pr-4 py-3', + style: { textAlign: 'left' } + }; + } + + return { + name: ( +
handleSort(header.key)} + > + {header.name} + Sort +
+ ), + className: 'text-left pl-6 pr-4 py-3', + style: { textAlign: 'left' } + }; + }); + + // Filter users based on search term + const filteredUsers = searchTerm + ? users.filter( + (user) => + user.name.toLowerCase().includes(searchTerm.toLowerCase()) || + user.email.toLowerCase().includes(searchTerm.toLowerCase()) + ) + : users; + + // Apply sorting to filtered users + const sortedUsers = getSortedData(filteredUsers); + + const rows = sortedUsers.map((user) => [ user.name, user.email, user.lastLogin, @@ -569,21 +691,23 @@ const AdminUsers = () => { const tableToolbar = (
-

Admin Users

-
-
- +

Admin Users

+
+
Search + setSearchTerm(e.target.value)} />
-
+
- {/* 🟡 Show Remarks ONLY IF Current Production code is filled AND different from Business Register */} + {/* Show Remarks ONLY IF Current Production code is filled AND different from Business Register */} {form.industryCodeProduction && form.industryCodeBusiness !== form.industryCodeProduction && (
{ setProducts(formattedProducts); - // Filter out already selected products + // Filter out already selected products - Updated comparison logic const available = formattedProducts.filter(p => - !selectedProducts.some(sp => sp.id === p.id || sp.product_id === p.product_id) + !selectedProducts.some(sp => + (sp.id && (sp.id === p.id || sp.id === p.product_id)) || + (sp.product_id && (sp.product_id === p.id || sp.product_id === p.product_id)) || + (sp.value && (sp.value === p.id || sp.value === p.product_id)) + ) ); - setAvailableProducts(available); - - + setAvailableProducts(available); } catch (error) { console.error('Error loading products:', error); showToast('error', 'Failed to load products'); @@ -1430,7 +1486,11 @@ const CompanyProfile = () => { if (!searchTerm) { setAvailableProducts(products.filter(p => - !selectedProducts.some(sp => sp.id === p.id) + !selectedProducts.some(sp => + (sp.id && (sp.id === p.id || sp.id === p.product_id)) || + (sp.product_id && (sp.product_id === p.id || sp.product_id === p.product_id)) || + (sp.value && (sp.value === p.id || sp.value === p.product_id)) + ) )); return; } @@ -1439,8 +1499,14 @@ const CompanyProfile = () => { const productName = (product.productName || product.label || product.product_name || '').toLowerCase(); const hsCode = (product.hsCode || product.hs_code || '').toLowerCase(); - return (productName.includes(searchTerm) || hsCode.includes(searchTerm)) && - !selectedProducts.some(sp => sp.id === product.id); + const isMatch = productName.includes(searchTerm) || hsCode.includes(searchTerm); + const isSelected = selectedProducts.some(sp => + (sp.id && (sp.id === product.id || sp.id === product.product_id)) || + (sp.product_id && (sp.product_id === product.id || sp.product_id === product.product_id)) || + (sp.value && (sp.value === product.id || sp.value === product.product_id)) + ); + + return isMatch && !isSelected; }); setAvailableProducts(filtered); @@ -1584,7 +1650,9 @@ const CompanyProfile = () => { ); }; -const displayedRows = filteredProfiles.map((item) => { +const sortedProfiles = getSortedData(filteredProfiles); +const displayedRows = sortedProfiles.map((item) => { + return [ // Establishment Name item.establishmentName || "-", @@ -3013,6 +3081,8 @@ const handleImport = async () => { + + return (
{toast && ( @@ -3142,34 +3212,58 @@ const handleImport = async () => {
) : ( { + const isSortable = header.sortable; + const isActive = sortConfig.key === header.key; + const isAsc = sortConfig.direction === 'asc'; + + return { + name: ( +
handleSort(header.key) : undefined} + > + {header.name} + {isSortable ? ( + Sort + ) : ( + // Invisible placeholder to maintain alignment + )} +
+ ) + }; + })} rows={displayedRows} columnWidths={[ - 250, // Establishment Name (250px) - 150, // Contact Name (150px) - 120, // Emirate (120px) - 120, // ISIC Code (120px) - 150, // Establishment ID (150px) - 100, // Products (100px) - 130, // Total Employees (120px) - 120, // Created By (120px) - 120, // Created On (120px) - 120, // Last Updated (120px) - 100, // Status (100px) - 150, // Actions (150px) + 300, // Establishment Name (increased from 250) + 180, // Contact Name (increased from 150) + 150, // Emirate (increased from 120) + 150, // ISIC Code (increased from 120) + 200, // Establishment ID (increased from 150) + 150, // Products (increased from 100) + 180, // Total Employees (increased from 150) + 180, // Created By (increased from 120) + 150, // Created On (increased from 120) + 180, // Last Updated (increased from 120) + 120, // Status (increased from 100) + 150 // Actions (increased from 100) ]} pagination={{ currentPage, @@ -3425,7 +3519,7 @@ const handleImport = async () => {
{/* Header */} -
+

Import Company Profiles

{/* Content */} -
- {/* File Upload Area */} +
{/* File Upload Area */}
{ onDrop={handleDrop} onClick={() => fileInputRef.current?.click()} > -
+
Upload
@@ -3461,7 +3555,7 @@ const handleImport = async () => {

{file ? file.name : 'Drop your CSV file here or browse'}

-

+

Supports .csv files only (Max 10MB)

{file && validationResults && ( @@ -3472,7 +3566,7 @@ const handleImport = async () => {
+ {/* Mandatory Fields Note */} + +
+
+ + {/* Note Title */} +
+ + + + Note: +
+ + {/* Everything below becomes same font size */} +
+ +

The following fields are mandatory for bulk import and must be filled in:

+ +
+
+
+ •Establishment ID +
+
+ •Factory Name +
+
+ •User Name +
+
+ +
+
+ •Email +
+
+ •Emirate +
+
+ •HS Code +
+
+
+ +

+ If any of these fields are missing, the application will return an error. + Please review your data carefully before uploading. +

+
+
+
+ + + {/* Error Message */} {importError && (
@@ -3502,8 +3650,10 @@ const handleImport = async () => {
)} - {/* Sample CSV Link */} -
+ +
+ {/* Sample CSV Link */} +
-
- {/* Footer */} -
+