From 50bb4dd59b6d75a73d3bd133147dca4b678a4dd3 Mon Sep 17 00:00:00 2001 From: Malini Date: Tue, 30 Dec 2025 13:21:53 +0530 Subject: [PATCH] added iip calculations --- ipi-survey-platform/package-lock.json | 671 ++++++++++++- ipi-survey-platform/package.json | 4 + ipi-survey-platform/src/App.jsx | 10 + .../survey/ProductData/ProductData.jsx | 5 +- .../src/pages/Admin/Validations.jsx | 5 +- .../ManufacturingIndex/ManufacturingIndex.jsx | 898 ++++++++++++------ .../ManufacturingIndexPopup/ISIC2Digit.jsx | 230 +++++ .../ManufacturingIndexPopup/ISIC3Digit.jsx | 209 ++++ .../ManufacturingIndexPopup/ISIC4Digit.jsx | 195 ++++ .../ManufacturingTotal.jsx | 115 +++ .../manufacturingIndex/ManufacturingIndex.js | 40 + .../services/submissions/submissionService.js | 2 +- 12 files changed, 2057 insertions(+), 327 deletions(-) create mode 100644 ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC2Digit.jsx create mode 100644 ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC3Digit.jsx create mode 100644 ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC4Digit.jsx create mode 100644 ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ManufacturingTotal.jsx create mode 100644 ipi-survey-platform/src/services/manufacturingIndex/ManufacturingIndex.js diff --git a/ipi-survey-platform/package-lock.json b/ipi-survey-platform/package-lock.json index 6649592..e036884 100644 --- a/ipi-survey-platform/package-lock.json +++ b/ipi-survey-platform/package-lock.json @@ -8,6 +8,10 @@ "name": "ipi-survey-platform", "version": "0.0.0", "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.3.6", + "@mui/material": "^7.3.6", "axios": "^1.12.2", "chart.js": "^4.5.1", "lucide-react": "^0.548.0", @@ -53,7 +57,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -109,7 +112,6 @@ "version": "7.28.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.3", @@ -143,7 +145,6 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -153,7 +154,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -195,7 +195,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -205,7 +204,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -239,7 +237,6 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.28.4" @@ -283,11 +280,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -302,7 +307,6 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -321,7 +325,6 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -331,6 +334,158 @@ "node": ">=6.9.0" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.11", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", @@ -984,7 +1139,6 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1006,7 +1160,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1016,14 +1169,12 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1036,6 +1187,261 @@ "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", "license": "MIT" }, + "node_modules/@mui/core-downloads-tracker": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.6.tgz", + "integrity": "sha512-QaYtTHlr8kDFN5mE1wbvVARRKH7Fdw1ZuOjBJcFdVpfNfRYKF3QLT4rt+WaB6CKJvpqxRsmEo0kpYinhH5GeHg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.6.tgz", + "integrity": "sha512-0FfkXEj22ysIq5pa41A2NbcAhJSvmcZQ/vcTIbjDsd6hlslG82k5BEBqqS0ZJprxwIL3B45qpJ+bPHwJPlF7uQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^7.3.6", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.6.tgz", + "integrity": "sha512-R4DaYF3dgCQCUAkr4wW1w26GHXcf5rCmBRHVBuuvJvaGLmZdD8EjatP80Nz5JCw0KxORAzwftnHzXVnjR8HnFw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/core-downloads-tracker": "^7.3.6", + "@mui/system": "^7.3.6", + "@mui/types": "^7.4.9", + "@mui/utils": "^7.3.6", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^7.3.6", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz", + "integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==", + "license": "MIT" + }, + "node_modules/@mui/private-theming": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.6.tgz", + "integrity": "sha512-Ws9wZpqM+FlnbZXaY/7yvyvWQo1+02Tbx50mVdNmzWEi51C51y56KAbaDCYyulOOBL6BJxuaqG8rNNuj7ivVyw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/utils": "^7.3.6", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.6.tgz", + "integrity": "sha512-+wiYbtvj+zyUkmDB+ysH6zRjuQIJ+CM56w0fEXV+VDNdvOuSywG+/8kpjddvvlfMLsaWdQe5oTuYGBcodmqGzQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.6.tgz", + "integrity": "sha512-8fehAazkHNP1imMrdD2m2hbA9sl7Ur6jfuNweh5o4l9YPty4iaZzRXqYvBCWQNwFaSHmMEj2KPbyXGp7Bt73Rg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/private-theming": "^7.3.6", + "@mui/styled-engine": "^7.3.6", + "@mui/types": "^7.4.9", + "@mui/utils": "^7.3.6", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.4.9", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.9.tgz", + "integrity": "sha512-dNO8Z9T2cujkSIaCnWwprfeKmTWh97cnjkgmpFJ2sbfXLx8SMZijCYHOtP/y5nnUb/Rm2omxbDMmtUoSaUtKaw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.6.tgz", + "integrity": "sha512-jn+Ba02O6PiFs7nKva8R2aJJ9kJC+3kQ2R0BbKNY3KQQ36Qng98GnPRFTlbwYTdMD6hLEBKaMLUktyg/rTfd2w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/types": "^7.4.9", + "@types/prop-types": "^15.7.15", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz", + "integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==", + "license": "MIT" + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@reduxjs/toolkit": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.0.tgz", @@ -1795,11 +2201,22 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.2.2", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", - "devOptional": true, "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -1815,6 +2232,15 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@types/use-sync-external-store": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", @@ -1955,6 +2381,21 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2157,6 +2598,31 @@ "node": ">=18" } }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2175,7 +2641,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, "license": "MIT" }, "node_modules/d3-array": { @@ -2347,6 +2812,16 @@ "node": ">=8" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2382,6 +2857,15 @@ "node": ">=10.13.0" } }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -2737,6 +3221,12 @@ "node": ">=16.0.0" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3047,6 +3537,27 @@ "node": ">=12" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3106,7 +3617,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -3121,6 +3631,12 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3407,6 +3923,12 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3650,6 +4172,24 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3668,11 +4208,25 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -3915,6 +4469,22 @@ "react-dom": "^18 || ^19" } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/recharts": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.5.0.tgz", @@ -3967,6 +4537,26 @@ "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", "license": "MIT" }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4061,6 +4651,15 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -4083,6 +4682,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4095,6 +4700,18 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tailwindcss": { "version": "4.1.14", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", @@ -4355,6 +4972,24 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/ipi-survey-platform/package.json b/ipi-survey-platform/package.json index a9327d2..8e2a7c0 100644 --- a/ipi-survey-platform/package.json +++ b/ipi-survey-platform/package.json @@ -10,6 +10,10 @@ "preview": "vite preview" }, "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.3.6", + "@mui/material": "^7.3.6", "axios": "^1.12.2", "chart.js": "^4.5.1", "lucide-react": "^0.548.0", diff --git a/ipi-survey-platform/src/App.jsx b/ipi-survey-platform/src/App.jsx index 8ff7aed..01bd53c 100644 --- a/ipi-survey-platform/src/App.jsx +++ b/ipi-survey-platform/src/App.jsx @@ -15,6 +15,8 @@ import ForgotPassword from '@/pages/ForgotPassword/ForgotPassword'; import PublicContactForm from '@/pages/PublicContactForm'; import EditCompanyProfile from '@/pages/Admin/configuration/EditCompanyProfile'; import Navbar from './pages/LandingPage/component/Navbar'; +import ManufacturingIndex from '@/pages/ManufacturingIndex/ManufacturingIndex'; + const RequireRole = ({ allowedRoles = [], children }) => { let role; @@ -241,6 +243,14 @@ function App() { } /> {/* /> */} {/* */} + + + + } + /> { const variant = STATUS_VARIANTS[status] || { background: '#F2F4F7', text: '#475467', border: '#EAECF0' }; return ( {children} diff --git a/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndex.jsx b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndex.jsx index f107005..e2fce52 100644 --- a/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndex.jsx +++ b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndex.jsx @@ -1,340 +1,626 @@ -import React, { useState } from 'react'; -import { - TextField, - MenuItem, - Button, +import React, { useState, useMemo, useEffect } from 'react'; +import { IconButton, - Chip, - Divider, - ToggleButtonGroup, - ToggleButton, - Avatar, - Menu, - MenuItem as MuiMenuItem, - ListItemIcon, - Typography + Dialog, + DialogTitle, + DialogContent } from '@mui/material'; -import { - ArrowRightAlt as ArrowRightAltIcon, - FileDownload as FileDownloadIcon, +import { SelectField as BaseSelectField } from '@/components/common/FormControls'; +import Table from '@/components/common/Table'; +import { FiberManualRecord as FiberManualRecordIcon, - NotificationsNone as NotificationsIcon, - HelpOutline as HelpIcon, - Settings as SettingsIcon, - Logout as LogoutIcon, - Person as PersonIcon, - KeyboardArrowDown as KeyboardArrowDownIcon + KeyboardArrowRight as KeyboardArrowRightIcon } from '@mui/icons-material'; import Card from '@/components/common/Card'; +import { getManufacturingIndex, getManufacturingMonthlyOverview } from '@/services/manufacturingIndex/ManufacturingIndex'; + +// Import popup components +import ManufacturingTotal from './ManufacturingIndexPopup/ManufacturingTotal'; +import ISIC2Digit from './ManufacturingIndexPopup/ISIC2Digit'; +import ISIC3Digit from './ManufacturingIndexPopup/ISIC3Digit'; +import ISIC4Digit from './ManufacturingIndexPopup/ISIC4Digit'; + +// Custom components +const SelectField = (props) => ( + +); const ManufacturingIndex = () => { + // State management const [year, setYear] = useState('2025'); - const [selectedMonth, setSelectedMonth] = useState('Oct 2025'); - const [view, setView] = useState('manufacturing'); + const [searchMonth, setSearchMonth] = useState(''); + const [selectedMonth, setSelectedMonth] = useState(null); + const [filteredMonths, setFilteredMonths] = useState([]); + const [activeTab, setActiveTab] = useState('manufacturing'); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + const [monthlyOverviewData, setMonthlyOverviewData] = useState(null); + const [isPopupOpen, setIsPopupOpen] = useState(false); + const [apiLoading, setApiLoading] = useState(false); - const years = ['2025', '2024', '2023']; - const months = [ - { month: 'Oct 2025', index: '114.8', mom: '+0.9', yoy: '+3.2', generated: '12 Nov 2025, 09:15', status: 'Completed' }, - { month: 'Sep 2025', index: '113.9', mom: '-0.2', yoy: '+2.8', generated: '11 Oct 2025, 09:15', status: 'Completed' }, - { month: 'Aug 2025', index: '114.1', mom: '+0.5', yoy: '+3.0', generated: '11 Sep 2025, 09:15', status: 'Completed' }, - { month: 'Jul 2025', index: '113.6', mom: '+0.3', yoy: '+2.9', generated: '11 Aug 2025, 09:15', status: 'Completed' }, - { month: 'Jun 2025', index: '113.3', mom: '+0.7', yoy: '+2.8', generated: '11 Jul 2025, 09:15', status: 'Completed' }, - ]; + const [pagination, setPagination] = useState({ + currentPage: 1, + pageSize: 20, + totalItems: 0 + }); - const handleViewChange = (event, newView) => { - if (newView !== null) { - setView(newView); + // Month name to number mapping + const monthMap = { + 'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, + 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8, + 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12 + }; + + // Fetch data from API +useEffect(() => { + const fetchData = async () => { + try { + setIsLoading(true); + console.log('Fetching manufacturing index data...'); + + const response = await getManufacturingIndex(); + + console.log('RAW API RESPONSE:', response); + console.log('Response type:', typeof response); + console.log('Response keys:', Object.keys(response || {})); + + // Handle different response structures + let dataArray = []; + + // Case 1: Response is already an array + if (Array.isArray(response)) { + console.log('Response is array directly'); + dataArray = response; + } + // Case 2: Response has data property which is array + else if (response && response.data && Array.isArray(response.data)) { + console.log('Response.data is array'); + dataArray = response.data; + } + // Case 3: Response.data is object with nested data + else if (response && response.data && typeof response.data === 'object') { + console.log('Response.data is object'); + // Try to extract array from common structures + if (Array.isArray(response.data.manufacturingIndex) || Array.isArray(response.data.data)) { + dataArray = response.data.manufacturingIndex || response.data.data || []; + } else { + // Convert object values to array + dataArray = Object.values(response.data); + } + } + // Case 4: Response has nested structure + else if (response && response.data && response.data.data && Array.isArray(response.data.data)) { + console.log('Response.data.data is array'); + dataArray = response.data.data; + } + else { + console.error('Unexpected API response structure:', response); + // Try to extract any array from response + const findArray = (obj) => { + if (Array.isArray(obj)) return obj; + if (typeof obj === 'object' && obj !== null) { + for (const key in obj) { + if (Array.isArray(obj[key])) { + return obj[key]; + } + } + } + return []; + }; + dataArray = findArray(response); + } + + console.log('Final dataArray:', dataArray); + + // If no data found + if (!dataArray || dataArray.length === 0) { + console.warn('No data array found, using empty array'); + dataArray = []; + } + + // Format the data + const formattedData = dataArray.map((item, index) => { + // Create a date object from reference_date or other date fields + let dateObj = new Date(); + let year = 2025; + let monthNumber = 1; + + if (item.reference_date) { + dateObj = new Date(item.reference_date); + } else if (item.date) { + dateObj = new Date(item.date); + } else if (item.referenceDate) { + dateObj = new Date(item.referenceDate); + } else if (item.year && item.month) { + // If year and month are separate fields + year = item.year; + monthNumber = item.month; + dateObj = new Date(year, monthNumber - 1, 1); + } + + const monthName = dateObj.toLocaleString('en-US', { month: 'short' }); + year = item.year || dateObj.getFullYear() || 2025; + monthNumber = item.month || (dateObj.getMonth() + 1) || 1; + + return { + id: item.id || `${year}-${monthNumber}` || `item-${index}`, + month: `${monthName} ${year}`, + monthName: monthName, + year: year, + monthNumber: monthNumber, + index: item.manufacturing_index?.toString() || item.index?.toString() || item.manufacturingIndex?.toString() || 'N/A', + mom: item.mom_change || item.mom || item.momChange ? + (parseFloat(item.mom_change || item.mom || item.momChange) > 0 ? + `+${item.mom_change || item.mom || item.momChange}` : + (item.mom_change || item.mom || item.momChange).toString()) : + 'N/A', + yoy: item.yoy_change || item.yoy || item.yoyChange ? + (parseFloat(item.yoy_change || item.yoy || item.yoyChange) > 0 ? + `+${item.yoy_change || item.yoy || item.yoyChange}` : + (item.yoy_change || item.yoy || item.yoyChange).toString()) : + 'N/A', + generated: item.generated_on || item.generatedOn || item.generated_at ? + new Date(item.generated_on || item.generatedOn || item.generated_at).toLocaleString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + timeZone: 'Asia/Dubai', + timeZoneName: 'short' + }) : 'N/A', + status: item.status || 'Completed', + rawData: item + }; + }); + + console.log('Formatted Data:', formattedData); + + setFilteredMonths(formattedData); + setPagination(prev => ({ + ...prev, + totalItems: formattedData.length + })); + + if (formattedData.length > 0) { + setSelectedMonth(formattedData[0]); + } + } catch (err) { + console.error('Error fetching manufacturing index:', err); + console.error('Error details:', { + message: err.message, + stack: err.stack, + response: err.response + }); + setError('Failed to load manufacturing data. Please try again later.'); + } finally { + setIsLoading(false); } }; - return ( -
- {/* Header with logo only */} -
-
-
- FCSC IPI -
-
-
+ fetchData(); +}, []); - {/* Main content */} -
- {/* Header */} -
-
-

IIP Manufacturing Index - Monthly Overview

- {/* */} + Retry +
- - -
-
-
- {/* } - /> */} -

- Manufacturing Index — Monthly overview -

+
+ ); + } + + return ( +
+ {/* Popup Dialog */} + + + Manufacturing Details - {selectedMonth?.month} + + + + + + + +
+ {apiLoading ? ( +
+
+ Loading detailed data...
-

- Monthly manufacturing indices are generated automatically on the 11th of each month using the finalized Laspeyres item indices. - Use this view to monitor trends and drill down into ISIC groups. -

-
- -
-
- - Next scheduled run: 11 Nov 2025, 02:00 GST + ) : ( +
+ {/* Tabs Header */} +
+
+
+ {['manufacturing', 'isic2', 'isic3', 'isic4'].map((tab) => ( + + ))} +
+
+
+
+ + {/* Tab Content */} +
+ {activeTab === 'manufacturing' && ( + + )} + + {activeTab === 'isic2' && ( + + )} + + {activeTab === 'isic3' && ( + + )} + + {activeTab === 'isic4' && ( + + )} +
-

- Formula: Manufacturing index = Σ (sector weightᵢ × group indexᵢ) -

-
+ )}
- -
+ + -
- {/* Left Column */} -
- -

Manufacturing index — by reference month

-

- Filter by year and quickly jump to a month to see its ISIC breakdown. -

- -
- - -
- -
- setYear(e.target.value)} - size="small" - className="min-w-[120px]" - InputLabelProps={{ className: 'text-gray-700' }} - > - {years.map((y) => ( - - {y} - - ))} - - - - - - ), - }} - /> -
- -
-

Showing 5 months for 2025

-

Click a row to open its ISIC breakdown on the right.

-
- -
- - - - - - - - - - - - - - {months.map((row) => ( - setSelectedMonth(row.month)} - className={`cursor-pointer ${selectedMonth === row.month ? 'bg-primary-50' : 'hover:bg-gray-50'}`} - > - - - - - - - - - ))} - -
REFERENCE MONTHMANUFACTURING INDEXMOM CHANGEYOY CHANGEGENERATED ONSTATUSACTIONS
-
- {row.month} - {selectedMonth === row.month && ( - - Selected - - )} -
-
{row.index} (2022=100) - - {row.mom}% - - - - {row.yoy}% - - {row.generated} - - {row.status} - - - - - -
+ {/* Main UI */} +
+
+ +
+
+

+ Manufacturing Index - Monthly overview +

+

+ Monthly manufacturing indices are automatically generated on the 11th of each month using the finalized Laspeyres item indices. This view enables users to monitor trends and drill down into ISIC group–level details. +

+
+ +
+
+ + Next scheduled run: 11 Nov 2025, 02:00 GST +
+
- {/* Right Column */} -
- -
-

Monthly ISIC breakdown

- -
- -

- Start from the manufacturing total, then drill down into ISIC 2-digit and 3 & 4-digit groups for the selected month. -

- - - - Manufacturing total - - - ISIC 2-digit - - - ISIC 3 & 4-digit - - - -
-

MANUFACTURING INDEX (HEADLINE)

-

114.8 (2022=100)

-
-

MoM: +0.9%

-

YoY: +3.2%

+ {/* Main Table */} +
+ +
+
+ {/* Filters */} +
+
+
+

+ Manufacturing index — by reference month ({filteredMonths.length}) +

+

+ Filter by year and quickly jump to a month to see its ISIC breakdown. +

+
+
+
+
+
+ Search +
+ +
+
+
+ ({ value: y, label: y }))} + /> +
+ +
+
+
+ + {/* Table */} +
+
+ { + const isSelected = selectedMonth?.month === row.month; + return [ +
+ {row.month} +
, + + {row.index} (2022=100) + , + = 0 ? 'text-green-600' : 'text-red-600'} ${isSelected ? 'font-medium' : ''}`} key="mom"> + {row.mom}% + , + = 0 ? 'text-green-600' : 'text-red-600'} ${isSelected ? 'font-medium' : ''}`} key="yoy"> + {row.yoy}% + , + + {row.generated} + , + + + {row.status} + + , +
handleMonthSelect(row)} + > + +
+ ]; + })} + columnWidths={['180px', '190px', '130px', '130px', '200px', '120px', '80px']} + getRowClass={(index) => { + const isSelected = selectedMonth?.month === filteredMonths[index]?.month; + return isSelected ? 'bg-[#F5F0E1]' : 'hover:bg-gray-50'; + }} + pagination={{ + currentPage: pagination.currentPage, + onPageChange: (page) => setPagination(prev => ({ ...prev, currentPage: page })), + pageSize: pagination.pageSize, + totalItems: filteredMonths.length, + pageSizeOptions: [10, 20, 50, 100], + onPageSizeChange: (size) => { + setPagination(prev => ({ + ...prev, + pageSize: size, + currentPage: 1 + })); + } + }} + className="w-full" + /> + + -

- The manufacturing index increased by 0.9% compared to the previous month and 3.2% compared to the same month last year. + +

+ Note: Indices shown here are headline manufacturing totals. Use the drill-down actions to move from manufacturing total to ISIC 2-digit, then to ISIC 3 & 4-digit groups.

- - - -
-

KEY CONTRIBUTORS

- -
-
-

Food products (ISIC 10-12)

-

+0.24

-
-
-
-
-
- -
-
-

Chemicals (ISIC 20-21)

-

+0.18

-
-
-
-
-
- -
-
-

Basic metals (ISIC 24)

-

-0.12

-
-
-
-
-
-
- ); }; -export default ManufacturingIndex; +export default ManufacturingIndex; \ No newline at end of file diff --git a/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC2Digit.jsx b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC2Digit.jsx new file mode 100644 index 0000000..8b00d40 --- /dev/null +++ b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC2Digit.jsx @@ -0,0 +1,230 @@ +import React, { useState, useMemo } from 'react'; +import Table from '@/components/common/Table'; + +const ISIC2Digit = ({ setActiveTab, apiData }) => { + const [searchTerm, setSearchTerm] = useState(''); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + + + // Your API returns array of objects with: isic_2digit_code, isic_description, total_weight, weighted_index_sum, isic_2digit_index + const isicData = Array.isArray(apiData) ? apiData : []; + + // Filter ISIC 2-digit data based on search term + const filteredData = useMemo(() => { + if (!searchTerm.trim()) return isicData; + + const term = searchTerm.toLowerCase().trim(); + return isicData.filter(item => { + const code = item.isic_2digit_code || ''; + const name = item.isic_description || ''; + const index = item.isic_2digit_index || ''; + const weight = item.total_weight || ''; + + return ( + code.toString().toLowerCase().includes(term) || + name.toString().toLowerCase().includes(term) || + index.toString().toLowerCase().includes(term) || + weight.toString().toLowerCase().includes(term) + ); + }); + }, [searchTerm, isicData]); + + // Handle CSV export + const handleExport = () => { + if (filteredData.length === 0) return; + + // Create CSV content + const headers = ['ISIC Code', 'Sector', 'Index', 'Weight (%)']; + const csvRows = [ + headers.join(','), + ...filteredData.map(item => + [ + `"${item.isic_2digit_code || ''}"`, + `"${item.isic_description || ''}"`, + item.isic_2digit_index || '', + item.total_weight || '' + ].join(',') + ) + ]; + + // Create and trigger download + const csvContent = csvRows.join('\n'); + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.setAttribute('href', url); + link.setAttribute('download', `isic_2digit_${new Date().toISOString().split('T')[0]}.csv`); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; + + // Format number with 2 decimal places if needed + const formatNumber = (value) => { + if (value === null || value === undefined || value === '' || value === 'N/A') return 'N/A'; + + const num = parseFloat(value); + if (isNaN(num)) return value; + + // If it's a whole number, show as is, else show 2 decimal places + return num % 1 === 0 ? num.toString() : num.toFixed(2); + }; + + // Get total weight for display + const totalWeight = useMemo(() => { + return isicData.reduce((sum, item) => { + const weight = parseFloat(item.total_weight || 0); + return sum + (isNaN(weight) ? 0 : weight); + }, 0); + }, [isicData]); + + return ( +
+

ISIC 2-digit breakdown

+

+ The manufacturing index is calculated as a weighted average of ISIC 2-digit groups, + using their relative weights in the manufacturing sector. + {totalWeight > 0 && ` Total weight: ${formatNumber(totalWeight)}%`} +

+ + {/* Data Summary */} + {isicData.length === 0 ? ( +
+
+
+ + + +
+
+

No data available

+
+

No ISIC 2-digit data found for this month.

+
+
+
+
+ ) : ( + <> + {/* Search and Filter Bar */} +
+
+
+ + + +
+ setSearchTerm(e.target.value)} + /> +
+ +
+ +
+
[ + + {item.isic_2digit_code || 'N/A'} + , + + {item.isic_description || 'N/A'} + , + = 0 ? 'text-green-600' : 'text-red-600'} + > + {formatNumber(item.isic_2digit_index)} + , + + {formatNumber(item.total_weight)}% + + ])} + className="w-full" + columnWidths={['15%', '55%', '15%', '15%']} + getCellClass={(rowIndex, colIndex) => { + const baseClasses = 'px-6 py-4 whitespace-nowrap text-sm'; + return colIndex === 0 + ? `${baseClasses} text-gray-900 font-medium` + : baseClasses; + }} + getRowClass={(rowIndex) => { + const baseClasses = 'border-b border-gray-200'; + return rowIndex % 2 === 0 + ? `${baseClasses} bg-white` + : `${baseClasses} bg-gray-50`; + }} + pagination={{ + currentPage: currentPage, + onPageChange: setCurrentPage, + pageSize: pageSize, + totalItems: filteredData.length, + pageSizeOptions: [10, 25, 50, 100], + onPageSizeChange: setPageSize + }} + /> + + + {/* Data Stats */} + {filteredData.length > 0 && ( +
+ {/* Showing {filteredData.length} of {isicData.length} sectors */} + {/* {totalWeight > 0 && ( + Total weight: {formatNumber(totalWeight)}% + )} */} +
+ )} + + )} + + {/* Back and Next Buttons */} +
+ + +
+ + ); +}; + +export default ISIC2Digit; \ No newline at end of file diff --git a/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC3Digit.jsx b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC3Digit.jsx new file mode 100644 index 0000000..4db4d98 --- /dev/null +++ b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC3Digit.jsx @@ -0,0 +1,209 @@ +import React, { useState, useMemo } from 'react'; +import Table from '@/components/common/Table'; + +const ISIC3Digit = ({ setActiveTab, apiData }) => { + const [searchTerm, setSearchTerm] = useState(''); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + + // API-லிருந்து வந்த data-ஐ பயன்படுத்தவும் + const isicData = Array.isArray(apiData) ? apiData : []; + + // Filter data based on search term + const filteredData = useMemo(() => { + if (!searchTerm.trim()) return isicData; + + const term = searchTerm.toLowerCase().trim(); + return isicData.filter(item => { + const code = item.isic_3digit_code || ''; + const name = item.isic_description || ''; + const index = item.isic_3digit_index || ''; + const weight = item.total_weight || ''; + + return ( + code.toString().toLowerCase().includes(term) || + name.toString().toLowerCase().includes(term) || + index.toString().toLowerCase().includes(term) || + weight.toString().toLowerCase().includes(term) + ); + }); + }, [searchTerm, isicData]); + + // Handle CSV export + const handleExport = () => { + if (filteredData.length === 0) return; + + // Create CSV content + const headers = ['ISIC Code', 'Sector', 'Index', 'Weight (%)']; + const csvRows = [ + headers.join(','), + ...filteredData.map(item => + [ + `"${item.isic_3digit_code || ''}"`, + `"${item.isic_description || ''}"`, + item.isic_3digit_index || '', + item.total_weight || '' + ].join(',') + ) + ]; + + // Create and trigger download + const csvContent = csvRows.join('\n'); + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.setAttribute('href', url); + link.setAttribute('download', `isic_3digit_${new Date().toISOString().split('T')[0]}.csv`); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; + + // Format number with 2 decimal places if needed + const formatNumber = (value) => { + if (value === null || value === undefined || value === '' || value === 'N/A') return 'N/A'; + + const num = parseFloat(value); + if (isNaN(num)) return value; + + return num % 1 === 0 ? num.toString() : num.toFixed(2); + }; + + return ( +
+

ISIC 3-digit breakdown

+

+ Detailed breakdown of manufacturing index by ISIC 3-digit classification. +

+ + {/* Data Summary */} + {isicData.length === 0 ? ( +
+
+
+ + + +
+
+

No data available

+
+

No ISIC 3-digit data found for this month.

+
+
+
+
+ ) : ( + <> + {/* Search and Filter Bar */} +
+
+
+ + + +
+ setSearchTerm(e.target.value)} + /> +
+ +
+ +
+
[ + + {item.isic_3digit_code || 'N/A'} + , + + {item.isic_description || 'N/A'} + , + = 0 ? 'text-green-600' : 'text-red-600'} + > + {formatNumber(item.isic_3digit_index)} + , + + {formatNumber(item.total_weight)}% + + ])} + className="w-full" + columnWidths={['20%', '50%', '15%', '15%']} + getCellClass={(rowIndex, colIndex) => { + const baseClasses = 'px-6 py-4 whitespace-nowrap text-sm text-gray-900'; + return colIndex === 0 + ? `${baseClasses} font-medium` + : baseClasses; + }} + pagination={{ + currentPage: currentPage, + onPageChange: setCurrentPage, + pageSize: pageSize, + totalItems: filteredData.length, + pageSizeOptions: [10, 25, 50, 100], + onPageSizeChange: setPageSize + }} + /> + + + {/* Data Stats */} + {filteredData.length > 0 && ( +
+ {/* Showing {filteredData.length} of {isicData.length} sectors */} +
+ )} + + )} + + {/* Back and Next Buttons */} +
+ + +
+ + ); +}; + +export default ISIC3Digit; \ No newline at end of file diff --git a/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC4Digit.jsx b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC4Digit.jsx new file mode 100644 index 0000000..8e27da5 --- /dev/null +++ b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ISIC4Digit.jsx @@ -0,0 +1,195 @@ +import React, { useState, useMemo } from 'react'; +import Table from '@/components/common/Table'; + +const ISIC4Digit = ({ setActiveTab, apiData }) => { + const [searchTerm, setSearchTerm] = useState(''); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + + // API-லிருந்து வந்த data-ஐ பயன்படுத்தவும் + const isicData = Array.isArray(apiData) ? apiData : []; + + // Filter data based on search term + const filteredData = useMemo(() => { + if (!searchTerm.trim()) return isicData; + + const term = searchTerm.toLowerCase().trim(); + return isicData.filter(item => { + const code = item.isic_4digit_code || ''; + const name = item.isic_description || ''; + const index = item.isic_4digit_index || ''; + const weight = item.total_weight || ''; + + return ( + code.toString().toLowerCase().includes(term) || + name.toString().toLowerCase().includes(term) || + index.toString().toLowerCase().includes(term) || + weight.toString().toLowerCase().includes(term) + ); + }); + }, [searchTerm, isicData]); + + // Handle CSV export + const handleExport = () => { + if (filteredData.length === 0) return; + + // Create CSV content + const headers = ['ISIC Code', 'Sector', 'Index', 'Weight (%)']; + const csvRows = [ + headers.join(','), + ...filteredData.map(item => + [ + `"${item.isic_4digit_code || ''}"`, + `"${item.isic_description || ''}"`, + item.isic_4digit_index || '', + item.total_weight || '' + ].join(',') + ) + ]; + + // Create and trigger download + const csvContent = csvRows.join('\n'); + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.setAttribute('href', url); + link.setAttribute('download', `isic_4digit_${new Date().toISOString().split('T')[0]}.csv`); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; + + // Format number with 2 decimal places if needed + const formatNumber = (value) => { + if (value === null || value === undefined || value === '' || value === 'N/A') return 'N/A'; + + const num = parseFloat(value); + if (isNaN(num)) return value; + + return num % 1 === 0 ? num.toString() : num.toFixed(2); + }; + + return ( +
+

ISIC 4-digit breakdown

+

+ Detailed breakdown of manufacturing index by ISIC 4-digit classification. +

+ + {/* Data Summary */} + {isicData.length === 0 ? ( +
+
+
+ + + +
+
+

No data available

+
+

No ISIC 4-digit data found for this month.

+
+
+
+
+ ) : ( + <> + {/* Search and Filter Bar */} +
+
+
+ + + +
+ setSearchTerm(e.target.value)} + /> +
+ +
+ +
+
[ + + {item.isic_4digit_code || 'N/A'} + , + + {item.isic_description || 'N/A'} + , + = 0 ? 'text-green-600' : 'text-red-600'} + > + {formatNumber(item.isic_4digit_index)} + , + + {formatNumber(item.total_weight)}% + + ])} + className="w-full" + columnWidths={['20%', '50%', '15%', '15%']} + getCellClass={(rowIndex, colIndex) => { + const baseClasses = 'px-6 py-4 whitespace-nowrap text-sm text-gray-900'; + return colIndex === 0 + ? `${baseClasses} font-medium` + : baseClasses; + }} + pagination={{ + currentPage: currentPage, + onPageChange: setCurrentPage, + pageSize: pageSize, + totalItems: filteredData.length, + pageSizeOptions: [10, 25, 50, 100], + onPageSizeChange: setPageSize + }} + /> + + + {/* Data Stats */} + {filteredData.length > 0 && ( +
+ {/* Showing {filteredData.length} of {isicData.length} sectors */} +
+ )} + + )} + + {/* Only Back Button for ISIC 4-digit (no Next button) */} +
+ +
+ + ); +}; + +export default ISIC4Digit; \ No newline at end of file diff --git a/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ManufacturingTotal.jsx b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ManufacturingTotal.jsx new file mode 100644 index 0000000..28c3685 --- /dev/null +++ b/ipi-survey-platform/src/pages/ManufacturingIndex/ManufacturingIndexPopup/ManufacturingTotal.jsx @@ -0,0 +1,115 @@ +import React from 'react'; + +const ManufacturingTotal = ({ selectedMonthData, setActiveTab, monthlyOverviewData }) => { + // Use API data if available, otherwise use table data + const apiData = monthlyOverviewData?.manufacturing; + + // Determine which data source to use + const dataSource = apiData || selectedMonthData; + + if (!dataSource) { + return ( +
+

+ Manufacturing Index (Headline) +

+

No data available for this month.

+
+ ); + } + + // Extract values from the selected data source + const getValue = (key) => { + if (apiData) { + // API data has different structure + switch(key) { + case 'index': return apiData.index || apiData.manufacturing_index || 'N/A'; + case 'mom': + const momVal = apiData.mom || apiData.mom_change || 0; + return momVal > 0 ? `+${momVal}%` : `${momVal}%`; + case 'yoy': + const yoyVal = apiData.yoy || apiData.yoy_change || 0; + return yoyVal > 0 ? `+${yoyVal}%` : `${yoyVal}%`; + default: return 'N/A'; + } + } else { + // Table data + return dataSource[key] || 'N/A'; + } + }; + + const indexValue = getValue('index'); + const momValue = getValue('mom'); + const yoyValue = getValue('yoy'); + + // Parse numeric values for calculations + const momNumeric = parseFloat(momValue); + const yoyNumeric = parseFloat(yoyValue); + + return ( +
+

+ Manufacturing Index (Headline) +

+ +
+

+ {indexValue} +

+ (2022 = 100) +
+ +
+
+ MoM:{' '} + = 0 + ? 'text-green-600' + : 'text-red-600' + }`} + > + {momValue} + +
+ +
+ YoY:{' '} + = 0 + ? 'text-green-600' + : 'text-red-600' + }`} + > + {yoyValue} + +
+
+ +

+ The manufacturing index{' '} + {momNumeric >= 0 ? 'increased' : 'decreased'} by{' '} + {Math.abs(momNumeric)}% compared to + the previous month and{' '} + {yoyNumeric >= 0 ? 'increased' : 'decreased'} by{' '} + {Math.abs(yoyNumeric)}% compared to + the same month last year. +

+ +
+ +
+
+ ); +}; + +export default ManufacturingTotal; \ No newline at end of file diff --git a/ipi-survey-platform/src/services/manufacturingIndex/ManufacturingIndex.js b/ipi-survey-platform/src/services/manufacturingIndex/ManufacturingIndex.js new file mode 100644 index 0000000..1025a18 --- /dev/null +++ b/ipi-survey-platform/src/services/manufacturingIndex/ManufacturingIndex.js @@ -0,0 +1,40 @@ +import { getRequest } from '@/services/api/CommonService'; + +const MANUFACTURING_ENDPOINT = '/manufacturing'; + +export const getManufacturingIndex = async () => { + try { + const response = await getRequest(`${MANUFACTURING_ENDPOINT}/getManufacturingIndex`); + console.log('Manufacturing Index API Response:', response); + return response; + } catch (error) { + console.error('Error fetching manufacturing index:', error); + throw error; + } +}; + +export const getManufacturingMonthlyOverview = async (year, month) => { + try { + console.log('Monthly Overview API Call - Year:', year, 'Month:', month); + + const response = await getRequest( + `${MANUFACTURING_ENDPOINT}/getManufacturingMonthlyOverview`, + { + params: { + year: year.toString(), + month: month.toString(), + }, + } + ); + + console.log('API Response:', response); + + // Return the entire response + return response; + + } catch (error) { + console.error('Error fetching manufacturing monthly overview:', error); + throw error; + } +}; + \ No newline at end of file diff --git a/ipi-survey-platform/src/services/submissions/submissionService.js b/ipi-survey-platform/src/services/submissions/submissionService.js index fde59e7..bc884be 100644 --- a/ipi-survey-platform/src/services/submissions/submissionService.js +++ b/ipi-survey-platform/src/services/submissions/submissionService.js @@ -14,7 +14,7 @@ export const getSubmissions = async (page = 1, limit = 100, config = {}) => { params: { page, limit, - ...(config.params || {}) // Preserve any existing params + ...(config.params || {}) } }); return response.data;