Compare commits

...

41 Commits

Author SHA1 Message Date
Pradeeppon01 f29a3bab00 latest 2025-01-12 23:25:11 +05:30
Pradeeppon01 9e010d7f49 added verify button for part-c 2025-01-11 14:07:29 +05:30
Pradeeppon01 caf3eca000 modified edit container 2024-12-02 14:13:16 +05:30
Pradeeppon01 cbcbf33228 latest 2024-11-30 18:43:01 +05:30
Pradeeppon01 01234e9295 latest 2024-09-23 18:18:53 +05:30
Pradeeppon01 63831d050b latest 2024-08-13 20:55:39 +05:30
Pradeeppon01 6c80deec0d latest 2024-08-07 17:38:33 +05:30
Pradeeppon01 3ad4c9b51f latest 2024-08-07 17:34:26 +05:30
Pradeeppon01 72776c2008 latest 2024-08-07 17:26:22 +05:30
Pradeeppon01 878444d2a9 latest 2024-08-07 02:10:38 +05:30
Pradeeppon01 e28c9bce3d latest 2024-08-02 12:06:05 +05:30
Pradeeppon01 0f58d9967a latest 2024-08-02 11:47:52 +05:30
Pradeeppon01 3161bf2437 latest 2024-08-02 11:17:07 +05:30
Pradeeppon01 e12f9af402 latest 2024-08-01 16:02:22 +05:30
yokesh22 955070bab4 . 2024-07-24 14:54:18 +05:30
yokesh22 c06b37b28d part-a fixes in palyground 2024-07-24 14:31:16 +05:30
Pradeeppon01 d247442c8f latest 2024-07-24 03:30:46 +05:30
Pradeeppon01 56f3422a84 latest 2024-07-24 03:24:31 +05:30
Pradeeppon01 a832b7f172 latest 2024-07-24 03:22:56 +05:30
yokesh22 02a8ec95a9 . 2024-07-19 18:15:40 +05:30
yokesh22 48a01ac744 part-a fixes 2024-07-16 18:26:22 +05:30
yokesh22 c948502c26 . 2024-07-16 17:50:16 +05:30
Pradeeppon01 8701ee0fd4 latest 2024-07-14 22:47:11 +05:30
Pradeeppon01 24e413f6cf added changes in playground UI 2024-07-14 09:15:59 +05:30
Pradeeppon01 f43aa6c583 added changes in playground UI 2024-07-14 08:58:24 +05:30
Pradeeppon01 9024b77d1d latest 2024-07-13 19:38:57 +05:30
Pradeeppon01 aee9f5c534 latest 2024-07-13 19:29:10 +05:30
Pradeeppon01 c31458330b latest 2024-07-13 17:02:51 +05:30
Pradeeppon01 541654db01 latest 2024-07-13 17:02:36 +05:30
Pradeeppon01 e88604fdaf latest 2024-07-12 18:52:13 +05:30
Pradeeppon01 1a4c9538e5 latest 2024-07-12 18:39:19 +05:30
Pradeeppon01 1c731661f2 Merge branch 'part_a_playground' of https://github.com/Pradeeppon01/attendence_UI into part_a_playground 2024-07-12 18:26:40 +05:30
yokesh22 8778784530 . 2024-07-12 18:25:50 +05:30
Pradeeppon01 26532bf52d latest 2024-07-12 17:59:12 +05:30
Pradeeppon01 0d1c8f0101 latest 2024-07-12 17:58:01 +05:30
yokesh22 d535c3a05f part-a edit intergrated 2024-07-12 17:54:43 +05:30
Pradeeppon01 c49c08e655 latest 2024-07-11 18:26:24 +05:30
Pradeeppon01 c3f26d3e7b latest 2024-07-11 18:25:52 +05:30
Pradeeppon01 3c3ee38978 latest 2024-07-11 16:32:30 +05:30
Pradeeppon01 f010167bdb latest 2024-07-11 16:31:35 +05:30
yokesh22 42b39b6713 subject code added in part-c playground 2024-07-11 16:27:54 +05:30
54 changed files with 6854 additions and 360 deletions

3
.env
View File

@ -2,4 +2,5 @@
METABASE_BASE_URL="http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf" METABASE_BASE_URL="http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf"
# VITE_REACT_APP_BACKEND_URL="http://localhost:9999" # VITE_REACT_APP_BACKEND_URL="http://localhost:9999"
VITE_REACT_APP_BACKEND_URL="https://api.exampaper.vidh.ai" VITE_REACT_APP_BACKEND_URL="https://api.dev.exampaper.usln.in"
#VITE_REACT_APP_BACKEND_URL="https://api.exampaper.usln.in"

BIN
assets/Infinity_loader.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -1,11 +1,13 @@
#! /bin/bash #! /bin/bash
SOURCE_DIR=/home/neuu/attendence_UI/frontend SOURCE_DIR=/home/neuu/attendence_UI/attendence_UI
BRANCH=master BRANCH=part_a_playground
FRONTEND_DIR=/var/www/exampaper.vidh.ai FRONTEND_DIR=/var/www/exampaper.usln.in
SERVER_IP=52.66.73.43 #SERVER_IP=52.66.73.43
SERVER_IP=34.131.182.12
cd ~/$SOURCE_DIR
cd $SOURCE_DIR
echo "Changed into attendence UI frontend dir ....." echo "Changed into attendence UI frontend dir ....."
echo "Pulling $BRANCH ..." echo "Pulling $BRANCH ..."
@ -16,7 +18,7 @@ if [[ $? -eq 0 ]];then
npm run build npm run build
if [[ $? -eq 0 ]];then if [[ $? -eq 0 ]];then
echo "Build the latest file ....." echo "Build the latest file ....."
scp -r dist/* ubuntu@$SERVER_IP:$FRONTEND_DIR scp -r dist/* ponpradeeep@$SERVER_IP:$FRONTEND_DIR
if [[ $? -eq 0 ]];then if [[ $? -eq 0 ]];then
echo "Copying build file to $FRONTEND_DIR successfull ...." echo "Copying build file to $FRONTEND_DIR successfull ...."
else else

View File

@ -12,7 +12,7 @@
<title>exampaper.vidh.ai</title> <title>exampaper.vidh.ai</title>
</head> </head>
<body> <body>
<div id="root" class="w-100 vh-100"></div> <div id="root" class="w-100 vh-100 overflow-auto"></div>
<script type="module" src="/src/main.jsx"></script> <script type="module" src="/src/main.jsx"></script>
</body> </body>
</html> </html>

618
package-lock.json generated
View File

@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.4", "@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5", "@emotion/styled": "^11.11.5",
"@material-ui/core": "^4.12.4",
"@mui/icons-material": "^5.15.18", "@mui/icons-material": "^5.15.18",
"@mui/material": "^5.15.18", "@mui/material": "^5.15.18",
"antd": "^5.17.3", "antd": "^5.17.3",
@ -18,9 +19,13 @@
"html5-qrcode": "^2.1.5", "html5-qrcode": "^2.1.5",
"react": "^18.3.1", "react": "^18.3.1",
"react-bootstrap": "^2.10.2", "react-bootstrap": "^2.10.2",
"react-csv-reader": "^4.0.0",
"react-csv-viewer": "^1.0.4",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-lazy-load-image-component": "^1.6.0", "react-lazy-load-image-component": "^1.6.0",
"react-medium-image-zoom": "^5.2.4", "react-medium-image-zoom": "^5.2.4",
"react-notifications": "^1.7.4",
"react-notifications-component": "^4.0.1",
"react-qr-barcode-scanner": "^1.0.6", "react-qr-barcode-scanner": "^1.0.6",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"react-router-dom": "^6.23.1", "react-router-dom": "^6.23.1",
@ -1189,6 +1194,168 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@material-ui/core": {
"version": "4.12.4",
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.4.tgz",
"integrity": "sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==",
"deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.",
"dependencies": {
"@babel/runtime": "^7.4.4",
"@material-ui/styles": "^4.11.5",
"@material-ui/system": "^4.12.2",
"@material-ui/types": "5.1.0",
"@material-ui/utils": "^4.11.3",
"@types/react-transition-group": "^4.2.0",
"clsx": "^1.0.4",
"hoist-non-react-statics": "^3.3.2",
"popper.js": "1.16.1-lts",
"prop-types": "^15.7.2",
"react-is": "^16.8.0 || ^17.0.0",
"react-transition-group": "^4.4.0"
},
"engines": {
"node": ">=8.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/material-ui"
},
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.0",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@material-ui/core/node_modules/clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
"engines": {
"node": ">=6"
}
},
"node_modules/@material-ui/styles": {
"version": "4.11.5",
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.5.tgz",
"integrity": "sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==",
"deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.",
"dependencies": {
"@babel/runtime": "^7.4.4",
"@emotion/hash": "^0.8.0",
"@material-ui/types": "5.1.0",
"@material-ui/utils": "^4.11.3",
"clsx": "^1.0.4",
"csstype": "^2.5.2",
"hoist-non-react-statics": "^3.3.2",
"jss": "^10.5.1",
"jss-plugin-camel-case": "^10.5.1",
"jss-plugin-default-unit": "^10.5.1",
"jss-plugin-global": "^10.5.1",
"jss-plugin-nested": "^10.5.1",
"jss-plugin-props-sort": "^10.5.1",
"jss-plugin-rule-value-function": "^10.5.1",
"jss-plugin-vendor-prefixer": "^10.5.1",
"prop-types": "^15.7.2"
},
"engines": {
"node": ">=8.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/material-ui"
},
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.0",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@material-ui/styles/node_modules/clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
"engines": {
"node": ">=6"
}
},
"node_modules/@material-ui/styles/node_modules/csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
},
"node_modules/@material-ui/system": {
"version": "4.12.2",
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.2.tgz",
"integrity": "sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==",
"dependencies": {
"@babel/runtime": "^7.4.4",
"@material-ui/utils": "^4.11.3",
"csstype": "^2.5.2",
"prop-types": "^15.7.2"
},
"engines": {
"node": ">=8.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/material-ui"
},
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.0",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@material-ui/system/node_modules/csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
},
"node_modules/@material-ui/types": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
"integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
"peerDependencies": {
"@types/react": "*"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@material-ui/utils": {
"version": "4.11.3",
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.3.tgz",
"integrity": "sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==",
"dependencies": {
"@babel/runtime": "^7.4.4",
"prop-types": "^15.7.2",
"react-is": "^16.8.0 || ^17.0.0"
},
"engines": {
"node": ">=8.0.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
}
},
"node_modules/@mui/base": { "node_modules/@mui/base": {
"version": "5.0.0-beta.40", "version": "5.0.0-beta.40",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz",
@ -2552,6 +2719,15 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/css-vendor": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
"integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
"dependencies": {
"@babel/runtime": "^7.8.3",
"is-in-browser": "^1.0.2"
}
},
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@ -3598,6 +3774,11 @@
"resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.1.5.tgz", "resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.1.5.tgz",
"integrity": "sha512-3cOA0lPIcKtMd7Sz9BZm5ERAokv5uj35zT3o59LMVF6wLesYJ4WZaD28Z0OPnsfxe4dHGFgZ3RZ1si8f2AfOGw==" "integrity": "sha512-3cOA0lPIcKtMd7Sz9BZm5ERAokv5uj35zT3o59LMVF6wLesYJ4WZaD28Z0OPnsfxe4dHGFgZ3RZ1si8f2AfOGw=="
}, },
"node_modules/hyphenate-style-name": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
"integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="
},
"node_modules/ignore": { "node_modules/ignore": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
@ -3835,6 +4016,11 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/is-in-browser": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
"integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g=="
},
"node_modules/is-map": { "node_modules/is-map": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
@ -4108,6 +4294,88 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/jss": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
"integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/jss"
}
},
"node_modules/jss-plugin-camel-case": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz",
"integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"hyphenate-style-name": "^1.0.3",
"jss": "10.10.0"
}
},
"node_modules/jss-plugin-default-unit": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz",
"integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0"
}
},
"node_modules/jss-plugin-global": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz",
"integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0"
}
},
"node_modules/jss-plugin-nested": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz",
"integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0",
"tiny-warning": "^1.0.2"
}
},
"node_modules/jss-plugin-props-sort": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz",
"integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0"
}
},
"node_modules/jss-plugin-rule-value-function": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz",
"integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0",
"tiny-warning": "^1.0.2"
}
},
"node_modules/jss-plugin-vendor-prefixer": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz",
"integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"css-vendor": "^2.0.8",
"jss": "10.10.0"
}
},
"node_modules/jsx-ast-utils": { "node_modules/jsx-ast-utils": {
"version": "3.3.5", "version": "3.3.5",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
@ -4415,6 +4683,11 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/papaparse": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz",
"integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw=="
},
"node_modules/parent-module": { "node_modules/parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -4488,6 +4761,11 @@
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
}, },
"node_modules/popper.js": {
"version": "1.16.1-lts",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
},
"node_modules/possible-typed-array-names": { "node_modules/possible-typed-array-names": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
@ -5210,6 +5488,37 @@
} }
} }
}, },
"node_modules/react-csv-reader": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/react-csv-reader/-/react-csv-reader-4.0.0.tgz",
"integrity": "sha512-NRo27kv1YWYAJAR3H5ZZ5KREEw35avUtdGr4DwYel87QN3rwJf2wdAw97swNDO3cTW2i3cuXSNjfPqVIJm5xOg==",
"dependencies": {
"papaparse": "^5.3.0"
},
"peerDependencies": {
"prop-types": "^15.7.2",
"react": "^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-csv-viewer": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/react-csv-viewer/-/react-csv-viewer-1.0.4.tgz",
"integrity": "sha512-aA6WPI+AuEoLCFYiaeaBGavrl+CDmrBkCVcRhgyZySIp2n9Xlgga/b613CUphOBK27mNmgnnj7fiYS+FD1RzLw==",
"dependencies": {
"papaparse": "4.6.3",
"react-table": "6.9.2"
},
"peerDependencies": {
"react": "^16.8.2",
"react-dom": "^16.8.2"
}
},
"node_modules/react-csv-viewer/node_modules/papaparse": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-4.6.3.tgz",
"integrity": "sha512-LRq7BrHC2kHPBYSD50aKuw/B/dGcg29omyJbKWY3KsYUZU69RKwaBHu13jGmCYBtOc4odsLCrFyk6imfyNubJQ=="
},
"node_modules/react-dom": { "node_modules/react-dom": {
"version": "18.3.1", "version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
@ -5260,6 +5569,36 @@
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
} }
}, },
"node_modules/react-notifications": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/react-notifications/-/react-notifications-1.7.4.tgz",
"integrity": "sha512-dsR7mUQfe8YdFLqVsjT0GFd4n26UWkzefdjMELfEVygjuuyU6ZZ0LpZhFHdfmraGeBFLWHNxygpGlHHituUyjQ==",
"dependencies": {
"acorn": "6.4.1",
"classnames": "^2.1.1",
"prop-types": "^15.5.10",
"react-transition-group": "^4.4.1"
}
},
"node_modules/react-notifications-component": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/react-notifications-component/-/react-notifications-component-4.0.1.tgz",
"integrity": "sha512-NRBkWO19AsXmN0b8YQ0L12eoCAhrnmIZtGm77ATWSfQEXPL5PYSyeACpx7tePP+R2De9b0IP4yk9vY4TtzC02w==",
"peerDependencies": {
"react": "^18.0.1"
}
},
"node_modules/react-notifications/node_modules/acorn": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/react-qr-barcode-scanner": { "node_modules/react-qr-barcode-scanner": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/react-qr-barcode-scanner/-/react-qr-barcode-scanner-1.0.6.tgz", "resolved": "https://registry.npmjs.org/react-qr-barcode-scanner/-/react-qr-barcode-scanner-1.0.6.tgz",
@ -5354,6 +5693,19 @@
"react-dom": ">=16.8" "react-dom": ">=16.8"
} }
}, },
"node_modules/react-table": {
"version": "6.9.2",
"resolved": "https://registry.npmjs.org/react-table/-/react-table-6.9.2.tgz",
"integrity": "sha512-sTbNHU8Um0xRtmCd1js873HXnXaMWeBwZoiljuj0l1d44eaqjKyYPK/3HCBbJg1yeE2O5pQJ3Km0tlm9niNL9w==",
"dependencies": {
"classnames": "^2.2.5"
},
"peerDependencies": {
"prop-types": "^15.5.0",
"react": "^15.x.x || ^16.x.x",
"react-dom": "^15.x.x || ^16.x.x"
}
},
"node_modules/react-toastify": { "node_modules/react-toastify": {
"version": "10.0.5", "version": "10.0.5",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz",
@ -5859,6 +6211,11 @@
"node": ">=12.22" "node": ">=12.22"
} }
}, },
"node_modules/tiny-warning": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
"node_modules/to-fast-properties": { "node_modules/to-fast-properties": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@ -7022,6 +7379,100 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"@material-ui/core": {
"version": "4.12.4",
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.4.tgz",
"integrity": "sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==",
"requires": {
"@babel/runtime": "^7.4.4",
"@material-ui/styles": "^4.11.5",
"@material-ui/system": "^4.12.2",
"@material-ui/types": "5.1.0",
"@material-ui/utils": "^4.11.3",
"@types/react-transition-group": "^4.2.0",
"clsx": "^1.0.4",
"hoist-non-react-statics": "^3.3.2",
"popper.js": "1.16.1-lts",
"prop-types": "^15.7.2",
"react-is": "^16.8.0 || ^17.0.0",
"react-transition-group": "^4.4.0"
},
"dependencies": {
"clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="
}
}
},
"@material-ui/styles": {
"version": "4.11.5",
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.5.tgz",
"integrity": "sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==",
"requires": {
"@babel/runtime": "^7.4.4",
"@emotion/hash": "^0.8.0",
"@material-ui/types": "5.1.0",
"@material-ui/utils": "^4.11.3",
"clsx": "^1.0.4",
"csstype": "^2.5.2",
"hoist-non-react-statics": "^3.3.2",
"jss": "^10.5.1",
"jss-plugin-camel-case": "^10.5.1",
"jss-plugin-default-unit": "^10.5.1",
"jss-plugin-global": "^10.5.1",
"jss-plugin-nested": "^10.5.1",
"jss-plugin-props-sort": "^10.5.1",
"jss-plugin-rule-value-function": "^10.5.1",
"jss-plugin-vendor-prefixer": "^10.5.1",
"prop-types": "^15.7.2"
},
"dependencies": {
"clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="
},
"csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
}
}
},
"@material-ui/system": {
"version": "4.12.2",
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.2.tgz",
"integrity": "sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==",
"requires": {
"@babel/runtime": "^7.4.4",
"@material-ui/utils": "^4.11.3",
"csstype": "^2.5.2",
"prop-types": "^15.7.2"
},
"dependencies": {
"csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
}
}
},
"@material-ui/types": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
"integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A=="
},
"@material-ui/utils": {
"version": "4.11.3",
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.3.tgz",
"integrity": "sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==",
"requires": {
"@babel/runtime": "^7.4.4",
"prop-types": "^15.7.2",
"react-is": "^16.8.0 || ^17.0.0"
}
},
"@mui/base": { "@mui/base": {
"version": "5.0.0-beta.40", "version": "5.0.0-beta.40",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz",
@ -7918,6 +8369,15 @@
"which": "^2.0.1" "which": "^2.0.1"
} }
}, },
"css-vendor": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
"integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
"requires": {
"@babel/runtime": "^7.8.3",
"is-in-browser": "^1.0.2"
}
},
"csstype": { "csstype": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@ -8690,6 +9150,11 @@
"resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.1.5.tgz", "resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.1.5.tgz",
"integrity": "sha512-3cOA0lPIcKtMd7Sz9BZm5ERAokv5uj35zT3o59LMVF6wLesYJ4WZaD28Z0OPnsfxe4dHGFgZ3RZ1si8f2AfOGw==" "integrity": "sha512-3cOA0lPIcKtMd7Sz9BZm5ERAokv5uj35zT3o59LMVF6wLesYJ4WZaD28Z0OPnsfxe4dHGFgZ3RZ1si8f2AfOGw=="
}, },
"hyphenate-style-name": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
"integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="
},
"ignore": { "ignore": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
@ -8854,6 +9319,11 @@
"is-extglob": "^2.1.1" "is-extglob": "^2.1.1"
} }
}, },
"is-in-browser": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
"integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g=="
},
"is-map": { "is-map": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
@ -9040,6 +9510,84 @@
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true "dev": true
}, },
"jss": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
"integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"requires": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
},
"jss-plugin-camel-case": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz",
"integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==",
"requires": {
"@babel/runtime": "^7.3.1",
"hyphenate-style-name": "^1.0.3",
"jss": "10.10.0"
}
},
"jss-plugin-default-unit": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz",
"integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==",
"requires": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0"
}
},
"jss-plugin-global": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz",
"integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==",
"requires": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0"
}
},
"jss-plugin-nested": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz",
"integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==",
"requires": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0",
"tiny-warning": "^1.0.2"
}
},
"jss-plugin-props-sort": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz",
"integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==",
"requires": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0"
}
},
"jss-plugin-rule-value-function": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz",
"integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==",
"requires": {
"@babel/runtime": "^7.3.1",
"jss": "10.10.0",
"tiny-warning": "^1.0.2"
}
},
"jss-plugin-vendor-prefixer": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz",
"integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==",
"requires": {
"@babel/runtime": "^7.3.1",
"css-vendor": "^2.0.8",
"jss": "10.10.0"
}
},
"jsx-ast-utils": { "jsx-ast-utils": {
"version": "3.3.5", "version": "3.3.5",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
@ -9266,6 +9814,11 @@
"p-limit": "^3.0.2" "p-limit": "^3.0.2"
} }
}, },
"papaparse": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz",
"integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw=="
},
"parent-module": { "parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -9318,6 +9871,11 @@
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
}, },
"popper.js": {
"version": "1.16.1-lts",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
"integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
},
"possible-typed-array-names": { "possible-typed-array-names": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
@ -9796,6 +10354,30 @@
"warning": "^4.0.3" "warning": "^4.0.3"
} }
}, },
"react-csv-reader": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/react-csv-reader/-/react-csv-reader-4.0.0.tgz",
"integrity": "sha512-NRo27kv1YWYAJAR3H5ZZ5KREEw35avUtdGr4DwYel87QN3rwJf2wdAw97swNDO3cTW2i3cuXSNjfPqVIJm5xOg==",
"requires": {
"papaparse": "^5.3.0"
}
},
"react-csv-viewer": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/react-csv-viewer/-/react-csv-viewer-1.0.4.tgz",
"integrity": "sha512-aA6WPI+AuEoLCFYiaeaBGavrl+CDmrBkCVcRhgyZySIp2n9Xlgga/b613CUphOBK27mNmgnnj7fiYS+FD1RzLw==",
"requires": {
"papaparse": "4.6.3",
"react-table": "6.9.2"
},
"dependencies": {
"papaparse": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-4.6.3.tgz",
"integrity": "sha512-LRq7BrHC2kHPBYSD50aKuw/B/dGcg29omyJbKWY3KsYUZU69RKwaBHu13jGmCYBtOc4odsLCrFyk6imfyNubJQ=="
}
}
},
"react-dom": { "react-dom": {
"version": "18.3.1", "version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
@ -9829,6 +10411,29 @@
"resolved": "https://registry.npmjs.org/react-medium-image-zoom/-/react-medium-image-zoom-5.2.4.tgz", "resolved": "https://registry.npmjs.org/react-medium-image-zoom/-/react-medium-image-zoom-5.2.4.tgz",
"integrity": "sha512-XLu/fLqpbmhiDAGA6yie78tDv4kh8GxvS7kKQArSOvCvm5zvgItoh4h01NAAvnezQ60ovsTeedHiHG3eG9CcGg==" "integrity": "sha512-XLu/fLqpbmhiDAGA6yie78tDv4kh8GxvS7kKQArSOvCvm5zvgItoh4h01NAAvnezQ60ovsTeedHiHG3eG9CcGg=="
}, },
"react-notifications": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/react-notifications/-/react-notifications-1.7.4.tgz",
"integrity": "sha512-dsR7mUQfe8YdFLqVsjT0GFd4n26UWkzefdjMELfEVygjuuyU6ZZ0LpZhFHdfmraGeBFLWHNxygpGlHHituUyjQ==",
"requires": {
"acorn": "6.4.1",
"classnames": "^2.1.1",
"prop-types": "^15.5.10",
"react-transition-group": "^4.4.1"
},
"dependencies": {
"acorn": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA=="
}
}
},
"react-notifications-component": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/react-notifications-component/-/react-notifications-component-4.0.1.tgz",
"integrity": "sha512-NRBkWO19AsXmN0b8YQ0L12eoCAhrnmIZtGm77ATWSfQEXPL5PYSyeACpx7tePP+R2De9b0IP4yk9vY4TtzC02w=="
},
"react-qr-barcode-scanner": { "react-qr-barcode-scanner": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/react-qr-barcode-scanner/-/react-qr-barcode-scanner-1.0.6.tgz", "resolved": "https://registry.npmjs.org/react-qr-barcode-scanner/-/react-qr-barcode-scanner-1.0.6.tgz",
@ -9888,6 +10493,14 @@
"react-router": "6.23.1" "react-router": "6.23.1"
} }
}, },
"react-table": {
"version": "6.9.2",
"resolved": "https://registry.npmjs.org/react-table/-/react-table-6.9.2.tgz",
"integrity": "sha512-sTbNHU8Um0xRtmCd1js873HXnXaMWeBwZoiljuj0l1d44eaqjKyYPK/3HCBbJg1yeE2O5pQJ3Km0tlm9niNL9w==",
"requires": {
"classnames": "^2.2.5"
}
},
"react-toastify": { "react-toastify": {
"version": "10.0.5", "version": "10.0.5",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz",
@ -10237,6 +10850,11 @@
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz",
"integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==" "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg=="
}, },
"tiny-warning": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
"to-fast-properties": { "to-fast-properties": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",

View File

@ -12,6 +12,7 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.4", "@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5", "@emotion/styled": "^11.11.5",
"@material-ui/core": "^4.12.4",
"@mui/icons-material": "^5.15.18", "@mui/icons-material": "^5.15.18",
"@mui/material": "^5.15.18", "@mui/material": "^5.15.18",
"antd": "^5.17.3", "antd": "^5.17.3",
@ -20,9 +21,13 @@
"html5-qrcode": "^2.1.5", "html5-qrcode": "^2.1.5",
"react": "^18.3.1", "react": "^18.3.1",
"react-bootstrap": "^2.10.2", "react-bootstrap": "^2.10.2",
"react-csv-reader": "^4.0.0",
"react-csv-viewer": "^1.0.4",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-lazy-load-image-component": "^1.6.0", "react-lazy-load-image-component": "^1.6.0",
"react-medium-image-zoom": "^5.2.4", "react-medium-image-zoom": "^5.2.4",
"react-notifications": "^1.7.4",
"react-notifications-component": "^4.0.1",
"react-qr-barcode-scanner": "^1.0.6", "react-qr-barcode-scanner": "^1.0.6",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"react-router-dom": "^6.23.1", "react-router-dom": "^6.23.1",

View File

@ -40,3 +40,220 @@
.read-the-docs { .read-the-docs {
color: #888; color: #888;
} }
.completed{
background-color: green !important;
color: white !important;
}
.visited{
background-color:rgba(128, 128, 128, 0.5) !important;
}
/* Notification Styles */
.notification {
position: fixed;
font-size: 19px;
top: 20px;
right: 20px;
padding: 15px;
border-radius: 5px;
color: #fff;
z-index: 1000;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
.notification.show {
opacity: 1;
}
.notification.hide {
opacity: 0;
}
.notification.info {
background-color: #2196f3;
}
.notification.success {
background-color: green;
}
.notification.error {
background-color: #f44336;
}
.white-background{
background-color: white;
}
.grey-background{
/* background-color: rgba(128, 128, 128, 0.1); */
background-color: rgba(3, 133, 8, 0.1);
}
.notification {
opacity: 0;
transition: opacity 0.3s ease;
position: fixed;
top: 10px;
right: 10px;
padding: 10px;
z-index: 1000;
border-radius: 5px;
}
.notification.show {
opacity: 1;
}
.notification.hide {
opacity: 0;
}
.notification.info {
background-color: blue;
color: white;
}
.notification.success {
background-color: green;
color: white;
}
.notification.error {
background-color: red;
color: white;
}
*{
margin: 0;
padding: 0;
user-select: none;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
html,body{
height: 100%;
}
body{
display: grid;
place-items: center;
overflow: hidden;
}
button{
padding: 8px 16px;
font-size: 25px;
font-weight: 500;
border-radius: 4px;
border: none;
outline: none;
background: #e69100;
color: white;
letter-spacing: 1px;
cursor: pointer;
}
.alert{
background: #ffdb9b;
padding: 20px 40px;
min-width: 420px;
position: absolute;
right: 0;
top: 10px;
border-radius: 4px;
border-left: 8px solid #ffa502;
overflow: hidden;
opacity: 0;
pointer-events: none;
}
.alert.showAlert{
opacity: 1;
pointer-events: auto;
}
.alert.show{
animation: show_slide 1s ease forwards;
}
@keyframes show_slide {
0%{
transform: translateX(100%);
}
40%{
transform: translateX(-10%);
}
80%{
transform: translateX(0%);
}
100%{
transform: translateX(-10px);
}
}
.alert.hide{
animation: hide_slide 1s ease forwards;
}
@keyframes hide_slide {
0%{
transform: translateX(-10px);
}
40%{
transform: translateX(0%);
}
80%{
transform: translateX(-10%);
}
100%{
transform: translateX(100%);
}
}
.alert .fa-exclamation-circle{
position: absolute;
left: 20px;
top: 50%;
transform: translateY(-50%);
color: #ce8500;
font-size: 30px;
}
.alert .msg{
padding: 0 20px;
font-size: 18px;
color: #ce8500;
}
.alert .close-btn{
position: absolute;
right: 0px;
top: 50%;
transform: translateY(-50%);
background: #ffd080;
padding: 20px 18px;
cursor: pointer;
}
.alert .close-btn:hover{
background: #ffc766;
}
.alert .close-btn .fas{
color: #ce8500;
font-size: 22px;
line-height: 40px;
}
::selection {
background: blue;
color: white;
}
@font-face {
font-family: 'Bamini';
src: url('./assets/fonts/Bamini_0.TTF') format('truetype');
font-weight: normal;
font-style: normal;
}
/* Apply the font */
.font-bamini {
font-family: 'Bamini', sans-serif;
}

View File

@ -21,12 +21,26 @@ import RecordEditor from "./Components/RecordEditor";
import VerifyMarks from "./Components/VerifyMarks"; import VerifyMarks from "./Components/VerifyMarks";
import QueryCardEditor from "./Components/QueryCardEditor"; import QueryCardEditor from "./Components/QueryCardEditor";
import AnomolyPartC from "./Components/AnomolyPartC"; import AnomolyPartC from "./Components/AnomolyPartC";
import BarcodeScanner from "./Components/BarcodeScanner" import BarcodeScanner from "./Components/BarcodeScanner";
import EvQrcode from "./Components/EvQrcode"; import EvQrcode from "./Components/EvQrcode";
import QrcodeCardEditor from "./Components/QrCodeCardEditor"; import QrcodeCardEditor from "./Components/QrCodeCardEditor";
import StudentResultsData from "./Components/StudentsResultsData"; import StudentResultsData from "./Components/StudentsResultsData";
import PlayGrounds from "./Components/PlayGrounds"; import PlayGrounds from "./Components/PlayGrounds";
import PlayGround from "./Components/PlayGround"; import PlayGround from "./Components/PlayGround";
import Revaluation from "./Components/Revaluation";
import PlayGroundUpdated from "./Components/PlaygroundUpdated";
import DummyDuplicates from "./Components/DummyDuplicates";
import IndividualStudAttendence from "./Components/IndividualStudAttendence";
import PendingAttendenceCorrection from "./Components/PendingAttendenceCorrection";
import QrcodeFinder from "./Components/QrcodeFinder";
import IndividualMarksheetGen from "./Components/IndividualMarksheetGen";
import UploadMarksheetDataContainer from "./Components/UploadMarksheetDataContainer";
import DataInsertion from "./Components/DataInsertion";
import DataInsertionCsvViewer from "./Components/DataInsertionCsvViewer";
import Login from "./Components/Login";
import HomeSections from "./Components/HomeSections";
import CertificateTextVerification from "./Components/CertificateTextVerification";
import AttendenceNotShadedCorrection from "./Components/AttendenceNotShadedCorrection";
function App() { function App() {
return ( return (
@ -34,62 +48,142 @@ function App() {
<BrowserRouter> <BrowserRouter>
<Routes> <Routes>
<Route path="/" element={<Home />}></Route> <Route path="/" element={<Home />}></Route>
<Route path="/sqlPlayground" element={<QueryExecutor />}></Route>
<Route path="/sqlPlayground/edit" element={<QueryCardEditor/>}></Route>
<Route path="/evQrcode/edit" element={<QrcodeCardEditor/>}></Route>
<Route path="/studentsDetails" element={<StudentResultsData/>}></Route>
<Route path="/Playgrounds" element={<PlayGrounds/>}></Route>
<Route path="/Playground/:type" element={<PlayGround/>}></Route>
<Route <Route
path="/anomoly/attendence/reassigned" path="/sections/:year/sqlPlayground"
element={<QueryExecutor />}
></Route>
<Route
path="/sections/:year/data/insertion"
element={<DataInsertion />}
></Route>
<Route path="/sections/:year" element={<HomeSections />}></Route>
<Route
path="/sections/:year/data/insertion/validation"
element={<DataInsertionCsvViewer />}
></Route>
<Route
path="/sections/:year/certificate/gen"
element={<IndividualMarksheetGen />}
></Route>
<Route
path="/sections/:year/certificate/gen/upload"
element={<UploadMarksheetDataContainer />}
></Route>
<Route
path="/sections/:year/sqlPlayground/edit"
element={<QueryCardEditor />}
></Route>
<Route
path="/sections/:year/evQrcode/edit"
element={<QrcodeCardEditor />}
></Route>
<Route
path="/sections/:year/studentsDetails"
element={<StudentResultsData />}
></Route>
<Route
path="/sections/:year/Playgrounds"
element={<PlayGrounds />}
></Route>
<Route
path="/sections/:year/Playground/:type"
element={<PlayGround />}
></Route>
<Route
path="/sections/:year/revaluation"
element={<Revaluation />}
></Route>
<Route
path="/sections/:year/playground/updated/:type"
element={<PlayGroundUpdated />}
></Route>
<Route
path="/sections/:year/anomoly/attendence/reassigned"
element={<AnomolyReassigned />} element={<AnomolyReassigned />}
></Route> ></Route>
<Route <Route
path="/sqlPlayground/Editor" path="/sections/:year/anomoly/attendence/pending_stud_check"
element={<PendingAttendenceCorrection />}
/>
<Route
path="/sections/:year/DummyDuplicates/:type"
element={<DummyDuplicates />}
></Route>
<Route
path="/sections/:year/sqlPlayground/Editor"
element={<RecordEditor />} element={<RecordEditor />}
></Route> ></Route>
<Route <Route
path="/anomoly/attendence/additionalSheet" path="/sections/:year/anomoly/attendence/stud_check"
element={<IndividualStudAttendence />}
></Route>
<Route
path="/sections/:year/anomoly/attendence/additionalSheet"
element={<AttendanceAdditionalSheet />} element={<AttendanceAdditionalSheet />}
></Route> ></Route>
<Route path="/barcodeScanner" element={<BarcodeScanner/>}></Route>
<Route <Route
path="/anomoly/reassigned/booklet" path="/sections/:year/barcodeScanner"
element={<BarcodeScanner />}
></Route>
<Route
path="/sections/:year/anomoly/reassigned/booklet"
element={<AttendenceCorrection />} element={<AttendenceCorrection />}
></Route> ></Route>
<Route <Route
path="/anomoly/reassigned/stats" path="/sections/:year/anomoly/reassigned/stats"
element={<ReassignedStats />} element={<ReassignedStats />}
></Route> ></Route>
<Route <Route
path="/anomoly/attendence" path="/sections/:year/anomoly/attendence"
element={<AnomolyAttendencePage />} element={<AnomolyAttendencePage />}
></Route> ></Route>
<Route <Route
path="/anomoly/attendence/additionalRecord" path="/sections/:year/qrcodeFinder"
element={<QrcodeFinder />}
></Route>
<Route
path="/sections/:year/anomoly/attendence/additionalRecord"
element={<AttendenceAdditionalRecord />} element={<AttendenceAdditionalRecord />}
/> />
<Route <Route
path="/anomoly/attendence/additionalRecord/correction" path="/sections/:year/AttendenceNotShadedCorrection"
element={<AttendenceNotShadedCorrection />}
/>
<Route
path="/sections/:year/anomoly/attendence/additionalRecord/correction"
element={<AttendenceAdditionalRecordCorrection />} element={<AttendenceAdditionalRecordCorrection />}
/> />
<Route <Route
path="/anomoly/reassigned/stats/:exam_centre_code" path="/sections/:year/anomoly/reassigned/stats/:exam_centre_code"
element={<IndividualExamCentreStats />} element={<IndividualExamCentreStats />}
></Route> ></Route>
<Route path="/anomoly/PartA" element={<PartAReassigned />}></Route> <Route
path="/sections/:year/anomoly/PartA"
element={<PartAReassigned />}
></Route>
<Route
path="/sections/:year/CertificateTextVerification"
element={<CertificateTextVerification />}
></Route>
{/* <Route {/* <Route
path="/verification" path="/verification"
element={<Verification/>} element={<Verification/>}
> >
</Route> */} </Route> */}
<Route path="/statistics" element={<Statistics />}></Route>
<Route <Route
path="/anomoly/partA/booklet" path="/sections/:year/statistics"
element={<Statistics />}
></Route>
<Route
path="/sections/:year/anomoly/partA/booklet"
element={<PartACorrection />} element={<PartACorrection />}
></Route> ></Route>
<Route path="/anomoly/partC" element={<AnomolyPartC/>}></Route> <Route
<Route path="/evQrcode" element={<EvQrcode/>}></Route> path="/sections/:year/anomoly/partC"
element={<AnomolyPartC />}
></Route>
<Route path="/sections/:year/evQrcode" element={<EvQrcode />}></Route>
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>
</> </>

View File

@ -1,40 +1,46 @@
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import HomepageCard from "./HomepageCard"; import HomepageCard from "./HomepageCard";
import {useState,useEffect} from "react" import { useState, useEffect } from "react";
const AnomolyAttendencePage = () => {
const AnomolyAttendencePage = () =>{ const cards = [
const cards = [ {
{ title: "Reassigned Serial Number Updation",
title: "Reassigned Serial Number Updation", url: "/anomoly/attendence/reassigned",
url: "/anomoly/attendence/reassigned" },
}, // {
// { // title: "Additional Student Record Insertion",
// title: "Additional Student Record Insertion", // url: "/anomoly/attendence/additionalRecord",
// url: "/anomoly/attendence/additionalRecord", // },
// }, {
{ title: "Additional Sheet Insertion",
title: "Additional Sheet Insertion", url: "/anomoly/attendence/additionalSheet",
url: "/anomoly/attendence/additionalSheet", },
} {
] title: "Individual Attendence Sheet Check",
url: "/anomoly/attendence/stud_check",
return ( },
<> {
<Box> title: "Pending Attendence Correction",
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3"> url: "/anomoly/attendence/pending_stud_check",
<h1>Welcome to exampaper.vidh.ai</h1> },
</Box> ];
<Box className="p-3">
{cards.map((card) => (
<HomepageCard title={card?.title} url={card?.url} />
))}
</Box>
</Box>
</>
);
}
return (
<>
<Box>
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3">
<h1>Welcome to exampaper.vidh.ai</h1>
</Box>
<Box className="p-3">
{cards.map((card) => (
<HomepageCard title={card?.title} url={card?.url} />
))}
</Box>
</Box>
</>
);
};
export default AnomolyAttendencePage; export default AnomolyAttendencePage;

View File

@ -26,10 +26,13 @@ import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select"; import Select from "@mui/material/Select";
import { useSearchParams } from "react-router-dom"; import { useSearchParams } from "react-router-dom";
import { updatePartCDegreeType } from "../redux/actions/actions"; import { updatePartCDegreeType } from "../redux/actions/actions";
import { useParams } from "react-router-dom";
const { Content, Header } = Layout; const { Content, Header } = Layout;
function AnomalyPartC() { function AnomalyPartC() {
const { year } = useParams()
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [isLoading2, setIsLoading2] = useState(false); const [isLoading2, setIsLoading2] = useState(false);
@ -41,7 +44,7 @@ function AnomalyPartC() {
const [totalPages, setTotalPages] = useState(1); const [totalPages, setTotalPages] = useState(1);
const [showSystemNoContainer, setShowSystemNoContainer] = useState(false); const [showSystemNoContainer, setShowSystemNoContainer] = useState(false);
const [selectedIndex, setSelectedIndex] = useState(null); const [selectedIndex, setSelectedIndex] = useState(null);
const [selectedDegreeType, setSelectedDegreeType] = useState(null); const [selectedDegreeType, setSelectedDegreeType] = useState("0");
const [dataFetched, setDataFetched] = useState([]); const [dataFetched, setDataFetched] = useState([]);
const [counter, setCounter] = useState(0); const [counter, setCounter] = useState(0);
const degreeTypes = [ const degreeTypes = [
@ -56,7 +59,7 @@ function AnomalyPartC() {
if (reduxDegreeType) { if (reduxDegreeType) {
setSelectedDegreeType(reduxDegreeType); setSelectedDegreeType(reduxDegreeType);
} else { } else {
setSelectedDegreeType("2"); setSelectedDegreeType("0");
} }
}, [reduxDegreeType]); }, [reduxDegreeType]);
@ -140,6 +143,7 @@ function AnomalyPartC() {
const payload = { const payload = {
systemRecords, systemRecords,
sysNo: reduxSystemNo, sysNo: reduxSystemNo,
year,
}; };
try { try {
fetch( fetch(
@ -170,7 +174,7 @@ function AnomalyPartC() {
const response = await fetch( const response = await fetch(
`${ `${
import.meta.env.VITE_REACT_APP_BACKEND_URL import.meta.env.VITE_REACT_APP_BACKEND_URL
}/getpartcEv?degreeType=${selectedDegreeType}`, }/getpartcEv?degreeType=${selectedDegreeType}&year=${year}`,
{ {
method: "GET", method: "GET",
headers: { headers: {
@ -203,6 +207,7 @@ function AnomalyPartC() {
error_reason: errorReason, error_reason: errorReason,
sysno: reduxSystemNo, sysno: reduxSystemNo,
degreeType: selectedDegreeType, degreeType: selectedDegreeType,
year: year
}), }),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@ -368,7 +373,12 @@ function AnomalyPartC() {
<CardContent> <CardContent>
{item.error && ( {item.error && (
<Typography id="1" variant="body2"> <Typography id="1" variant="body2">
Code: {item.error} Error Code: {item.error}
</Typography>
)}
{item.error_reason && (
<Typography id="1" variant="body2">
Error Reason: {item.error_reason}
</Typography> </Typography>
)} )}
{item["count(*)"] && ( {item["count(*)"] && (

View File

@ -96,7 +96,7 @@ const AntdesignLayout = ({ children }) => {
<Button <Button
className="bg-primary rounded-circle p-3" className="bg-primary rounded-circle p-3"
onClick={() => { onClick={() => {
window.scrollTo(0, 0); document.getElementById("text-area-input").scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" })
}} }}
> >
<ArrowUpwardIcon className="text-white" /> <ArrowUpwardIcon className="text-white" />

View File

@ -13,6 +13,7 @@ import { useDispatch, useSelector } from "react-redux";
import TableComponentAdditionalSheet from "./TableComponentAdditionalSheet"; import TableComponentAdditionalSheet from "./TableComponentAdditionalSheet";
const { Header, Content, Footer, Sider } = Layout; const { Header, Content, Footer, Sider } = Layout;
function AttendanceAdditionalSheet() { function AttendanceAdditionalSheet() {
const [tableRowData, setTableRowData] = useState([]); const [tableRowData, setTableRowData] = useState([]);

View File

@ -0,0 +1,271 @@
import { useAsyncError } from "react-router-dom";
import AntdesignLayout from "./AntdesignLayout";
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { Box, Button } from "@mui/material";
import LoadingContainer from "./LoadingContainer";
import Notification from "./Notification";
import SystemNumberDialog from "./SystemNumberDialog";
import { useSelector, useDispatch } from "react-redux";
import { Layout, theme, Pagination } from "antd";
const { Content, Header } = Layout;
import { useNavigate } from "react-router-dom";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import HomeIcon from "@mui/icons-material/Home";
const AttendenceNotShadedCorrection = () => {
const { year } = useParams();
const navigate = useNavigate();
const [AttendenceData, setAttendenceData] = useState([]);
const [notification, setNotification] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [showSystemNoContainer, setShowSystemNoContainer] = useState(false);
const reduxSystemNo = useSelector((state) => state?.systemNumber);
console.log("systemno: ", reduxSystemNo);
const {
token: { colorBgContainer, borderRadiusLG },
} = theme.useToken();
const imageDomain =
year === "april2024"
? "https://docs.exampaper.vidh.ai"
: year === "november2024"
? "https://images.exampaper.usln.in"
: "https://docs.exampaper.vidh.ai";
const showNotification = (message, type) => {
setNotification({ message, type });
};
const FetchAttendenceNotShadedCorrection = (reduxSystemNo) => {
console.log("Fetching.......");
setIsLoading(true);
fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchAttendenceNotShaded?systemNo=${reduxSystemNo}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
)
.then((response) => {
console.log("Response fetched..");
return response.json();
})
.then((responseData) => {
console.log("Response Data is : ", responseData);
setIsLoading(false);
if (responseData.status === "success") {
setAttendenceData(responseData?.data);
}
})
.catch((error) => {
console.error("Error fetching data: ", error);
setIsLoading(false);
});
};
const updateStatus = (type, data, index) => {
console.log("Fetching.......");
setIsLoading(true);
const payload = {
year,
type,
data,
};
fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/updateAttendenceStatus`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
)
.then((response) => {
console.log("Response fetched..");
return response.json();
})
.then((responseData) => {
console.log("Response Data is : ", responseData);
setIsLoading(false);
if (responseData.status === "success") {
showNotification(
`Record Record as ${type} Successfully...`,
"success"
);
const newData = data;
const tmpDatas = AttendenceData;
newData.verified = 1;
if (type == "OMIT") {
newData.omitted = 1;
newData.absent_status = null;
newData.verified = 1;
} else if (type == "ABSENT") {
newData.omitted = null;
newData.absent_status = 1;
newData.verified = 1;
} else if (type == "PRESENT") {
newData.omitted = null;
newData.absent_status = 0;
newData.verified = 1;
}
tmpDatas[index] = newData;
setAttendenceData(tmpDatas);
const mainEle = document.getElementById(
`attendence_data_container_${index}`
);
if (mainEle) {
console.log("main Ele === ", mainEle);
mainEle.classList.add("grey-background");
}
}
})
.catch((error) => {
console.error("Error fetching data: ", error);
setIsLoading(false);
showNotification(`Something Went Wrong ...`, "error");
});
};
// useEffect(() => {
// FetchAttendenceNotShadedCorrection();
// }, []);
useEffect(() => {
if (!reduxSystemNo) {
setShowSystemNoContainer(true);
} else {
FetchAttendenceNotShadedCorrection(reduxSystemNo);
}
}, [reduxSystemNo]);
return (
<>
<Header style={{ padding: 0, background: colorBgContainer }}>
<Box className="d-flex justify-content-between h-100 py-1 px-2">
<Button
className="bg-primary p-1 text-light"
onClick={() => navigate(-1)}
>
<ArrowBackIcon />
</Button>
<Box className="d-flex justify-content-between gap-2">
{reduxSystemNo && (
<Box
className="h6 p-0 m-0 text-light bg-primary rounded h-100 d-flex align-items-center px-3"
style={{ cursor: "pointer" }}
>
<b>System No : </b> {reduxSystemNo}
</Box>
)}
<Button
className="bg-primary p-1 text-light"
onClick={() => navigate("/")}
>
<HomeIcon />
</Button>
</Box>
</Box>
</Header>
<Content
style={{
padding: "24px",
backgroundColor: "#5078f2",
backgroundImage: "linear-gradient(315deg, #5078f2 0%, #efe9f4 74%)",
}}
>
{AttendenceData.length > 0 && (
<div className="my-3 rounded d-flex flex-column">
{AttendenceData.map((data, index) => (
<div
className="d-flex justify-content-between my-3 rounded shadow white-background"
id={`attendence_data_container_${index}`}
>
<div className="w-50 text-left p-4">
<div className="h6">
<strong>Register Number</strong> : {data?.register_number}
</div>
<div className="h6">
<strong>Subject Code</strong> : {data?.subject_code}
</div>
<div className="h6">
<strong>Row Number</strong> : {data?.rownumber}
</div>
<div className="h6">
<strong>S3 Path</strong> : {data?.s3_path}
</div>
<div className="h6">
<strong>Absent Status</strong> :{" "}
{data?.absent_status || "NULL"}
</div>
<div className="h6">
<strong>Omitted</strong> : {data?.omitted || "NULL"}
</div>
<div className="h6">
<strong>Verified</strong> : {data?.verified}
</div>
<div className="d-flex flex-column gap-2 my-5 py-1">
<Button
className="m-0 bg-primary text-white p-3 rounded w-25"
onClick={() => {
updateStatus("OMIT", data, index);
}}
>
OMIT
</Button>
<Button
className="m-0 bg-primary text-white p-3 rounded w-25"
onClick={() => {
updateStatus("ABSENT", data, index);
}}
>
Mark As Absent
</Button>
<Button
className="m-0 bg-primary text-white p-3 rounded w-25"
onClick={() => {
updateStatus("PRESENT", data, index);
}}
>
Mark As Present
</Button>
</div>
</div>
<div className="w-50 p-4">
<img
src={`${imageDomain}/${data?.s3_path}`}
width="850px"
height="auto"
/>
</div>
</div>
))}
</div>
)}
</Content>
{isLoading && <LoadingContainer loadingText={"Loading"} />}
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
{showSystemNoContainer && (
<SystemNumberDialog
setShowSystemNoContainer={setShowSystemNoContainer}
showSystemNoContainer={showSystemNoContainer}
/>
)}
</>
);
};
export default AttendenceNotShadedCorrection;

View File

@ -8,6 +8,7 @@ const BarcodeScanner = () => {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [barcodeInfo, setBarcodeInfo] = useState([]); const [barcodeInfo, setBarcodeInfo] = useState([]);
const [marksData, setMarksData] = useState([]); const [marksData, setMarksData] = useState([]);
const [partAData, setPartAData] = useState([]);
const scannerRef = useRef(null); // Use ref to store the scanner instance const scannerRef = useRef(null); // Use ref to store the scanner instance
useEffect(() => { useEffect(() => {
@ -20,10 +21,15 @@ const BarcodeScanner = () => {
}); });
const fetchBarcodeData = () => { const fetchBarcodeData = () => {
if(!scanResult){ console.log("fetching barcode data ......",scanResult)
return if (!scanResult) {
return;
} }
console.log("fetching barcode data ......")
setIsLoading(true); setIsLoading(true);
setMarksData([])
setBarcodeInfo([])
setPartAData([])
try { try {
const payload = { const payload = {
qrcodeValue: scanResult, qrcodeValue: scanResult,
@ -43,9 +49,11 @@ const BarcodeScanner = () => {
.then((response) => response.json()) .then((response) => response.json())
.then((responseData) => { .then((responseData) => {
setIsLoading(false); setIsLoading(false);
console.log("fetchbarcodedata result ===== ",responseData)
if (responseData.status === "success") { if (responseData.status === "success") {
setBarcodeInfo(responseData.results); setBarcodeInfo(responseData.results);
setMarksData(responseData?.marks); setMarksData(responseData?.marks);
setPartAData(responseData?.partAResults);
} }
}); });
} catch (error) { } catch (error) {
@ -81,7 +89,8 @@ const BarcodeScanner = () => {
}, []); }, []);
const reinitializeScanner = () => { const reinitializeScanner = () => {
setScanResult(null); console.log("calling reinitialize scanner ......")
// setScanResult(null);
setBarcodeInfo([]); setBarcodeInfo([]);
setMarksData([]); setMarksData([]);
// if (document.getElementById("reader")) { // if (document.getElementById("reader")) {
@ -90,7 +99,15 @@ const BarcodeScanner = () => {
// } // }
}; };
useEffect(()=>{
console.log("scan result ========== ",scanResult)
console.log("barcode Info ======= ",barcodeInfo)
console.log("marksData ========= ",marksData)
},[scanResult,barcodeInfo,marksData])
useEffect(() => { useEffect(() => {
console.log("Calling the use effect ..... scan result changed ...",scanResult)
if (!scanResult) { if (!scanResult) {
const readerEle = document.getElementById("reader"); const readerEle = document.getElementById("reader");
console.log("Reader ELe ===== ", readerEle); console.log("Reader ELe ===== ", readerEle);
@ -110,20 +127,20 @@ const BarcodeScanner = () => {
<h1>Welcome to exampaper.vidh.ai</h1> <h1>Welcome to exampaper.vidh.ai</h1>
</Box> </Box>
<Box className="my-3"> <Box className="my-3">
<Box className="d-none d-md-flex justify-content-center align-items-center w-100"> <Box className="d-flex justify-content-center align-items-center w-100">
{scanResult ? ( {scanResult ? (
<h5>QR : {scanResult}</h5> <h5>QR : {scanResult}</h5>
) : ( ) : (
<div id="reader" style={{ width: "400px", height: "400px" }}></div> <div id="reader" style={{ width: "400px", height: "400px" }}></div>
)} )}
</Box> </Box>
<Box className="d-flex d-md-none justify-content-center align-items-center w-100"> {/* <Box className="d-flex d-md-none justify-content-center align-items-center w-100">
{scanResult ? ( {scanResult ? (
<h5>QR : {scanResult}</h5> <h5>QR : {scanResult}</h5>
) : ( ) : (
<div id="reader" style={{ width: "400px", height: "400px" }}></div> <div id="reader" style={{ width: "400px", height: "400px" }}></div>
)} )}
</Box> </Box> */}
</Box> </Box>
<Box className="w-100 d-flex justify-content-center"> <Box className="w-100 d-flex justify-content-center">
{barcodeInfo.length > 0 && ( {barcodeInfo.length > 0 && (
@ -135,6 +152,15 @@ const BarcodeScanner = () => {
<h5>Exam center : {barcodeInfo[0]?.exam_center}</h5> <h5>Exam center : {barcodeInfo[0]?.exam_center}</h5>
</Box> </Box>
)} )}
{partAData.length > 0 && (
<Box className="p-5 w-50 rounded shadow">
<h5>Barcode : {partAData[0]?.barcode}</h5>
<h5>QRcode : {partAData[0]?.qrcode}</h5>
<h5>S.NO : {barcodeInfo[0]?.slno}</h5>
<h5>Booklet No : {barcodeInfo[0]?.booklet_serial_no}</h5>
<img src={`https://docs.exampaper.vidh.ai/${partAData?.s3_path}`} alt="PartA Image" width="50%" height="auto"/>
</Box>
)}
</Box> </Box>
<Box className="w-100 d-flex justify-content-center"> <Box className="w-100 d-flex justify-content-center">
{scanResult ? ( {scanResult ? (
@ -145,6 +171,7 @@ const BarcodeScanner = () => {
<h5>Marks : {marksData[0]?.marks}</h5> <h5>Marks : {marksData[0]?.marks}</h5>
<h5>File Scanned Date : {marksData[0]?.file_scanned_date}</h5> <h5>File Scanned Date : {marksData[0]?.file_scanned_date}</h5>
<h5>Cover QR code : {marksData[0]?.cover_barcode}</h5> <h5>Cover QR code : {marksData[0]?.cover_barcode}</h5>
<img src={`https://docs.exampaper.vidh.ai/${marksData?.s3_path}`} alt="PartC Image" width="50%" height="auto"/>
</Box> </Box>
<Box> <Box>
<Button <Button
@ -164,7 +191,7 @@ const BarcodeScanner = () => {
<Box className="my-3"> <Box className="my-3">
<Button <Button
className="p-3 bg-primary text-light rounded" className="p-3 bg-primary text-light rounded"
onClick={reinitializeScanner} onClick={()=>window.location.reload()}
> >
Scan Again Scan Again
</Button> </Button>

View File

@ -0,0 +1,242 @@
import AntdesignLayout from "./AntdesignLayout";
import { Box, Button } from "@mui/material";
import { useState, useEffect, useRef } from "react";
import { useParams } from "react-router-dom";
import { Bamini_base64 } from "../assets/fonts/Bamini";
const CertificateTextVerification = () => {
const [certificateData, setCertificateData] = useState([]);
const [registerNumber, setRegisterNumber] = useState(null)
const { year } = useParams();
const certificateDataRef = useRef(null);
const [currentPage, setCurrentPage] = useState(1); // Track current page
const itemsPerPage = 30; // Number of items per page
// Fetch certificate data
const fetchCertificateTextVerificationData = async () => {
try {
const payload = {
year,
registerNumber
};
const certificateDataResponse = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchCertificateTextVerification`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await certificateDataResponse.json();
console.log("response data certificateDataResponse ==== ", responseData);
if (responseData?.status === "success") {
console.log("response status success ...");
setCertificateData(responseData?.data);
}
} catch (error) {
throw new Error(error);
}
};
// Download HTML function
const downloadHTML = () => {
const content = certificateDataRef.current.outerHTML;
// Base64 encoded font data (replace with your actual base64 string)
const base64Font = Bamini_base64; // Replace with the actual base64 string or import it
// Create the HTML template that includes the embedded font and table styles
const htmlContent = `
<html>
<head>
<style>
@font-face {
font-family: 'Bamini';
src: url('data:font/ttf;base64,${base64Font}');
font-weight: normal;
font-style: normal;
}
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.font-bamini {
font-family: 'Bamini', sans-serif;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
table, th, td {
border: 1px solid black;
}
th, td {
padding: 8px 12px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
</style>
</head>
<body>
<div>
${content}
</div>
</body>
</html>
`;
// Create a Blob object with the HTML content
const blob = new Blob([htmlContent], { type: "text/html" });
// Create a download link
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "certificate_data.html"; // The name of the downloaded file
// Trigger the download
link.click();
};
// Handle pagination
const totalItems = certificateData.length;
const totalPages = Math.ceil(totalItems / itemsPerPage);
const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
const currentData = certificateData.slice(indexOfFirstItem, indexOfLastItem);
const paginate = (pageNumber) => setCurrentPage(pageNumber);
useEffect(() => {
fetchCertificateTextVerificationData();
}, []);
return (
<AntdesignLayout>
<Box>
<h5>Certificate Tamil Text Verification</h5>
</Box>
<Box className="d-flex justify-content-center gap-3 align-items-center py-3">
<input
type="text"
style={{ width: "600px" }}
className="form-control p-3"
id="registerNumberFormControlInput1"
placeholder="Ex: 20212231103112"
value={registerNumber}
onChange={(e)=>{
setRegisterNumber(e.target.value)
}}
/>
<button type="button" className="btn btn-primary btn-sm px-4 h-75">
Submit
</button>
</Box>
{certificateData.length > 0 && (
<>
<Box className="w-75 mx-auto" id="certificateDataList">
<table className="table table-bordered">
<thead>
<tr>
<th className="h4">Register Number</th>
<th className="h4">Tamil Name</th>
<th className="h4">Tamil Degree</th>
<th className="h4">Tamil Class</th>
<th className="h4">Tamil Month Year</th>
</tr>
</thead>
<tbody>
{currentData.map((data, index) => (
<tr key={index}>
<td className="h5">{data?.register_number}</td>
<td className="font-bamini h5">{data?.tamil_name}</td>
<td className="font-bamini h5">{data?.tamil_degree}</td>
<td className="font-bamini h5">{data?.tamil_class_name}</td>
<td className="font-bamini h5">{data?.tamil_month_year}</td>
</tr>
))}
</tbody>
</table>
<Box className="w-100 d-flex justify-content-center py-2">
<button
type="button"
className="btn btn-primary btn-sm px-4 h-75"
onClick={downloadHTML}
>
Download Data
</button>
</Box>
{/* Pagination Controls (Will not be included in download) */}
<div className="d-flex justify-content-center mt-3">
<button
onClick={() => paginate(currentPage - 1)}
disabled={currentPage === 1}
className="btn btn-outline-secondary mx-2"
>
Previous
</button>
{[...Array(totalPages)].map((_, index) => (
<button
key={index}
onClick={() => paginate(index + 1)}
className={`btn btn-outline-secondary mx-2 ${
currentPage === index + 1 ? "active" : ""
}`}
>
{index + 1}
</button>
))}
<button
onClick={() => paginate(currentPage + 1)}
disabled={currentPage === totalPages}
className="btn btn-outline-secondary mx-2"
>
Next
</button>
</div>
</Box>
<Box
className="w-75 mx-auto d-none"
id="certificateDataList"
ref={certificateDataRef}
>
<table className="table table-bordered">
<thead>
<tr>
<th className="h4">Register Number</th>
<th className="h4">Tamil Name</th>
<th className="h4">Tamil Degree</th>
<th className="h4">Tamil Class</th>
<th className="h4">Tamil Month Year</th>
</tr>
</thead>
<tbody>
{certificateData.map((data, index) => (
<tr key={index}>
<td className="h5">{data?.register_number}</td>
<td className="font-bamini h5">{data?.tamil_name}</td>
<td className="font-bamini h5">{data?.tamil_degree}</td>
<td className="font-bamini h5">{data?.tamil_class_name}</td>
<td className="font-bamini h5">{data?.tamil_month_year}</td>
</tr>
))}
</tbody>
</table>
</Box>
</>
)}
</AntdesignLayout>
);
};
export default CertificateTextVerification;

View File

@ -0,0 +1,11 @@
const ConvocationCertificateTemplate = () => {
return (
<>
<div>
</div>
</>
);
};
export default ConvocationCertificateTemplate;

View File

@ -3,13 +3,17 @@ import DownloadIcon from "@mui/icons-material/Download";
import { LazyLoadImage } from "react-lazy-load-image-component"; import { LazyLoadImage } from "react-lazy-load-image-component";
import { Label, MoreHorizTwoTone, RotateRight } from "@mui/icons-material"; import { Label, MoreHorizTwoTone, RotateRight } from "@mui/icons-material";
import { useState, useEffect, useRef } from "react"; import { useState, useEffect, useRef } from "react";
// import { ToastContainer, toast } from "react-toastify"; import { ToastContainer, toast } from "react-toastify";
import LoadingContainer from "./LoadingContainer"; import LoadingContainer from "./LoadingContainer";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
// import "react-toastify/dist/ReactToastify.css"; // import "react-toastify/dist/ReactToastify.css";
import RotateLeftIcon from "@mui/icons-material/RotateLeft"; import RotateLeftIcon from "@mui/icons-material/RotateLeft";
import RotateRightIcon from "@mui/icons-material/RotateRight"; import RotateRightIcon from "@mui/icons-material/RotateRight";
import PlayGroundEditContainer from "./PlayGroundEditContainer" import PlayGroundEditContainer from "./PlayGroundEditContainer";
import saveRotatedImage from "./Utilities/PartCPlaygroundUtilities";
import markAsPartc from "./Utilities/PartAPlaygroundUtilities";
import { updateAttendenceBlank } from "./Utilities/AttendencePlaygroundUtilities";
import Notification from "./Notification";
const CustomQueryExecutorCard = ({ const CustomQueryExecutorCard = ({
data, data,
@ -21,11 +25,20 @@ const CustomQueryExecutorCard = ({
degreeType, degreeType,
type, type,
tableName, tableName,
year,
}) => { }) => {
// console.log("ERROR ============= ",error) // console.log("ERROR ============= ",error)
// console.log("ERROR REASON ============== ",error_reason) // console.log("ERROR REASON ============== ",error_reason)
// console.log("REDUX SYSTEM NO ================== ",reduxSystemNo) // console.log("REDUX SYSTEM NO ================== ",reduxSystemNo)
const navigate = useNavigate(); const navigate = useNavigate();
console.log("year in custom query executer card ====== ", year);
const imageDomain =
year === "april2024"
? "https://docs.exampaper.vidh.ai"
: year === "november2024"
? "https://images.exampaper.usln.in"
: "https://docs.exampaper.vidh.ai";
console.log("imageDomain ===== ", imageDomain);
const [dataValue, setDataValue] = useState({}); const [dataValue, setDataValue] = useState({});
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
// console.log("data in query executor Card : ", data); // console.log("data in query executor Card : ", data);
@ -35,7 +48,10 @@ const CustomQueryExecutorCard = ({
const [imageName, setImageName] = useState(null); const [imageName, setImageName] = useState(null);
const [tableNameData, setTableNameData] = useState(null); const [tableNameData, setTableNameData] = useState(null);
const imageEleRef = useRef(); const imageEleRef = useRef();
const [showEditContainer,setShowEditContainer] = useState(false) const [showEditContainer, setShowEditContainer] = useState(false);
const [editorType, setEditorType] = useState(null);
const [notification, setNotification] = useState(null);
console.log("data =================== ", data); console.log("data =================== ", data);
// console.log("image column ====== ", s3_image_column); // console.log("image column ====== ", s3_image_column);
// console.log("s3 image ======= ", data[s3_image_column]); // console.log("s3 image ======= ", data[s3_image_column]);
@ -50,8 +66,14 @@ const CustomQueryExecutorCard = ({
if (tableName) { if (tableName) {
setTableNameData(tableName); setTableNameData(tableName);
} }
if (data?.subject_code) {
}
}, [data]); }, [data]);
const showNotification = (message, type) => {
setNotification({ message, type });
};
const updatePartAInstructions = async () => { const updatePartAInstructions = async () => {
console.log("update instrunction"); console.log("update instrunction");
const payload = { const payload = {
@ -85,6 +107,39 @@ const CustomQueryExecutorCard = ({
} }
}; };
const markAsPartc = async () => {
console.log("update markAsPartc");
const payload = {
data,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/markAsPartc`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
console.log("Updation successfull ....");
const updatedData = { ...dataValue, is_backpage: 1 };
// console.log("Data ===== ", updatedData);
setDataValue(updatedData);
// toast.success("Record Marked as Backpage ! ....");
} else {
throw new Error(responseData?.message);
}
} catch (error) {
throw new Error(error);
}
};
const updatePartAFront = async () => { const updatePartAFront = async () => {
console.log("update front"); console.log("update front");
const payload = { const payload = {
@ -122,6 +177,7 @@ const CustomQueryExecutorCard = ({
console.log("update front"); console.log("update front");
const payload = { const payload = {
data, data,
year,
}; };
try { try {
setIsLoading(true); setIsLoading(true);
@ -142,8 +198,10 @@ const CustomQueryExecutorCard = ({
const updatedData = { ...dataValue, is_backpage: 1 }; const updatedData = { ...dataValue, is_backpage: 1 };
// console.log("Data ===== ", updatedData); // console.log("Data ===== ", updatedData);
setDataValue(updatedData); setDataValue(updatedData);
// toast.success("Record Marked as Backpage ! ...."); // toast.success("Record Marked as Frontpage ! ....");
} else { } else {
toast.error("Something Went Wrong !...");
setIsLoading(false);
throw new Error(responseData?.message); throw new Error(responseData?.message);
} }
} catch (error) { } catch (error) {
@ -151,11 +209,10 @@ const CustomQueryExecutorCard = ({
} }
}; };
const updateBack = async () => { const updateBack = async () => {
const payload = { const payload = {
data, data,
year,
}; };
try { try {
setIsLoading(true); setIsLoading(true);
@ -178,6 +235,8 @@ const CustomQueryExecutorCard = ({
setDataValue(updatedData); setDataValue(updatedData);
// toast.success("Record Marked as Backpage ! ...."); // toast.success("Record Marked as Backpage ! ....");
} else { } else {
setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(responseData?.message); throw new Error(responseData?.message);
} }
} catch (error) { } catch (error) {
@ -209,6 +268,7 @@ const CustomQueryExecutorCard = ({
const updateEvCover = async () => { const updateEvCover = async () => {
const payload = { const payload = {
data, data,
year,
}; };
try { try {
setIsLoading(true); setIsLoading(true);
@ -238,9 +298,43 @@ const CustomQueryExecutorCard = ({
} }
}; };
const markAsDummy = async () =>{ const markAsPart_A = async () => {
const payload = { const payload = {
data, data,
year,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/markAsPartA`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
const updatedData = { ...dataValue, is_cover: 1 };
// console.log("Data ===== ", updatedData);
setDataValue(updatedData);
console.log("Updation successfull ....");
// toast.success("Record Marked As Ev !...");
} else {
throw new Error(responseData?.message);
}
} catch (error) {
throw new Error(error);
}
};
const markAsDummy = async () => {
const payload = {
data,
year,
}; };
try { try {
setIsLoading(true); setIsLoading(true);
@ -263,32 +357,86 @@ const CustomQueryExecutorCard = ({
console.log("Updation successfull ...."); console.log("Updation successfull ....");
// toast.success("Record Marked As Ev !..."); // toast.success("Record Marked As Ev !...");
} else { } else {
setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(responseData?.message); throw new Error(responseData?.message);
} }
} catch (error) { } catch (error) {
setIsLoading(false) setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(error); throw new Error(error);
} }
} };
const showContainerAction = () =>{ const showContainerAction = () => {
setShowEditContainer(true) setShowEditContainer(true);
} console.log("type === ", type);
// setEditorType(type)
};
const verifyRecord = async () => {
const payload = {
data,
year,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/verifyRecord`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
const updatedData = { ...dataValue, is_cover: 1 };
// console.log("Data ===== ", updatedData);
console.log("Verification successfull ....");
showNotification("Record Verified Successfully ..", "success");
// toast.success("Record Marked As Ev !...");
} else {
setIsLoading(false);
showNotification("Something Went Wrong ..", "error");
throw new Error(responseData?.message);
}
} catch (error) {
setIsLoading(false);
showNotification("Something Went Wrong ..", "error");
throw new Error(error);
}
};
const updateAttendenceBlankAction = () => {
updateAttendenceBlank(setIsLoading, data, setShowEditContainer);
};
const buttonActions = { const buttonActions = {
PartC: [ PartC: [
{ btnLabel: "Mark As Front", action: updateFront }, { btnLabel: "Mark As Front", action: updateFront },
{ btnLabel: "Mark As Back", action: updateBack }, { btnLabel: "Mark As Back", action: updateBack },
{ btnLabel: "Mark As Ev", action: updateEvCover }, { btnLabel: "Mark As Ev", action: updateEvCover },
{ btnLabel: "Mark As Dummy",action: markAsDummy}, { btnLabel: "Mark As Dummy", action: markAsDummy },
{ btnLabel: "Edit",action: showContainerAction} { btnLabel: "Mark As Part-A", action: markAsPart_A },
{ btnLabel: "Edit", action: showContainerAction },
{ btnLabel: "Verify", action: verifyRecord },
], ],
PartA: [ PartA: [
{ btnLabel: "Mark As Front", action: updatePartAFront }, { btnLabel: "Mark As Front", action: updatePartAFront },
{ btnLabel: "Mark As Instruction", action: updatePartAInstructions }, { btnLabel: "Mark As Backpage", action: updatePartAInstructions },
{ btnLabel: "Initiate Process", action: initateProcess }, // { btnLabel: "Initiate Process", action: initateProcess },
{ btnLabel: "Mark As Dummy",action:markAsDummy }, { btnLabel: "Mark As Dummy", action: markAsDummy },
{ btnLabel: "Edit",action: showContainerAction} { btnLabel: "Mark As Part-C", action: markAsPartc },
{ btnLabel: "Edit", action: showContainerAction },
],
Attendence: [
{ btnLabel: "Mark As Blank", action: updateAttendenceBlankAction },
{ btnLabel: "Edit", action: showContainerAction },
], ],
}; };
@ -304,39 +452,6 @@ const CustomQueryExecutorCard = ({
setValues(Object.values(dataValue)); setValues(Object.values(dataValue));
}, [dataValue]); }, [dataValue]);
const saveRotatedImage = async () => {
try {
if (rotateAngle === 0) {
return;
}
const payload = {
imageName,
tableNameData,
rotateAngle,
s3_path: data[s3_image_column],
};
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/saveRotatedImage`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
// toast.success("Image Rotation Saved Successfully")
}
} catch (error) {
setIsLoading(false);
throw new Error(error);
}
};
const rotate_and_process = async () => { const rotate_and_process = async () => {
setIsLoading(true); setIsLoading(true);
try { try {
@ -364,8 +479,45 @@ const CustomQueryExecutorCard = ({
} }
}; };
const saveRotatedImage = async () => {
try {
if (rotateAngle === 0) {
return;
}
const payload = {
imageName,
tableNameData,
rotateAngle,
s3_path: data[s3_image_column],
};
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/saveRotatedImage`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
toast.success("Image Rotation Saved Successfully");
} else {
toast.error("Something Went Wrong !...");
}
} catch (error) {
setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(error);
}
};
return ( return (
<Box className="w-100 rounded shadow mb-5 bg-white"> <Box className="w-100 rounded shadow mb-5 white-background" id={imageName}>
<ToastContainer />
<Box className="p-4 d-flex justify-content-between align-items-start"> <Box className="p-4 d-flex justify-content-between align-items-start">
<Box className="p-1"> <Box className="p-1">
<Box className="p-2 d-flex justify-content-end gap-3 align-items-center"> <Box className="p-2 d-flex justify-content-end gap-3 align-items-center">
@ -415,7 +567,7 @@ const CustomQueryExecutorCard = ({
</Box> </Box>
<Box className="border border-dark" id={imageName}> <Box className="border border-dark" id={imageName}>
<img <img
src={`https://docs.exampaper.vidh.ai/${data[s3_image_column]}`} src={`${imageDomain}/${data[s3_image_column]}`}
width="800px" width="800px"
height="auto" height="auto"
alt="Image Alt" alt="Image Alt"
@ -423,7 +575,10 @@ const CustomQueryExecutorCard = ({
/> />
</Box> </Box>
</Box> </Box>
<Box className="d-flex flex-column gap-2 mx-2 py-3" style={{minWidth:"250px"}}> <Box
className="d-flex flex-column gap-2 mx-2 py-3"
style={{ minWidth: "250px" }}
>
{type && {type &&
buttonActions[type].map((action) => ( buttonActions[type].map((action) => (
<Button <Button
@ -438,18 +593,28 @@ const CustomQueryExecutorCard = ({
className="m-0 bg-primary text-white p-3 rounded" className="m-0 bg-primary text-white p-3 rounded"
onClick={rotateLeft} onClick={rotateLeft}
> >
Rotate left<RotateLeftIcon/> Rotate left
<RotateLeftIcon />
</Button> </Button>
<Button <Button
className="m-0 bg-primary text-white p-3 rounded" className="m-0 bg-primary text-white p-3 rounded"
onClick={rotateRight} onClick={rotateRight}
> >
Rotate Right<RotateRight/> Rotate Right
<RotateRight />
</Button> </Button>
<Button <Button
className="m-0 bg-primary text-white p-3 rounded" className="m-0 bg-primary text-white p-3 rounded"
onClick={saveRotatedImage} onClick={() =>
saveRotatedImage(
imageName,
tableNameData,
rotateAngle,
data,
setIsLoading
)
}
> >
Save Save
</Button> </Button>
@ -463,8 +628,27 @@ const CustomQueryExecutorCard = ({
))} ))}
</Box> </Box>
</Box> </Box>
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
{isLoading && <LoadingContainer loadingText={"Loading ..."} />} {isLoading && <LoadingContainer loadingText={"Loading ..."} />}
{showEditContainer && <PlayGroundEditContainer rotateAngle={rotateAngle} data={data} s3Path={data[s3_image_column]} tableName={tableName} imageName={data["image_name"]} setShowEditContainer={setShowEditContainer}/>} {showEditContainer && (
<PlayGroundEditContainer
type={type}
year={year}
imageDomain={imageDomain}
rotateAngle={rotateAngle}
data={data}
s3Path={data[s3_image_column]}
tableName={tableName}
imageName={data["image_name"]}
setShowEditContainer={setShowEditContainer}
/>
)}
</Box> </Box>
); );
}; };

View File

@ -0,0 +1,323 @@
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Box, Button } from "@mui/material";
import AntdesignLayout from "./AntdesignLayout";
import LoadingContainer from "./LoadingContainer";
import infinity_loader from "../../assets/Infinity_loader.gif";
import Notification from "./Notification"; // Import the Notification componentimport InputLabel from '@mui/material/InputLabel';
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
import InputLabel from "@mui/material/InputLabel";
import TextField from "@material-ui/core/TextField";
import CsvViewer from "react-csv-viewer";
import csvData from "/home/neuu/attendence_UI/backend/tmp/UG PENDING 17-09-2024.csv";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
} from "@mui/material";
const DataInsertion = () => {
const [isLoading, setIsLoading] = useState(null);
const [notification, setNotification] = useState(null);
const [degreeType, setDegreeType] = useState(null);
const [file, setFile] = React.useState(null);
const [wrongData, setWrongData] = useState({});
const [processList, setProcesList] = useState([]);
const handleFileChange = (event) => {
setFile(event.target.files[0]);
};
useEffect(() => {
fetchProcessList();
}, []);
const fetchProcessList = async () => {
setIsLoading(true)
try {
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchcsvDataValidationList`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const responseData = await response.json();
console.log("Response ==== ", responseData);
if (responseData?.status == "success") {
setProcesList(responseData?.data);
}
} catch (error) {
console.log(error);
}
setIsLoading(false)
};
const parseCreatedOn = (dateValue) => {
console.log("parse created on ....", typeof dateValue);
if (!dateValue) {
return null; // Handle invalid input
} else if (typeof dateValue == "number") {
dateValue = String(dateValue);
}
const year = parseInt(dateValue.substring(0, 4), 10);
console.log("year ===== ", year);
const month = parseInt(dateValue.substring(4, 6), 10) - 1; // Month is 0-based in JS
const day = parseInt(dateValue.substring(6, 8), 10);
const hours = parseInt(dateValue.substring(8, 10), 10);
const minutes = parseInt(dateValue.substring(10, 12), 10);
const seconds = parseInt(dateValue.substring(12, 14), 10);
const parsedDate = new Date(year, month, day, hours, minutes, seconds);
// Check if the date is valid
if (isNaN(parsedDate.getTime())) {
return null; // Invalid date
}
return parsedDate;
};
useEffect(() => {
setWrongData({
subject_data: [
{ column_index: 2, row_index: 74, wrong_data: "CYOG31" },
{ column_index: 2, row_index: 75, wrong_data: "CMPE11" },
{ column_index: 2, row_index: 76, wrong_data: "S2EN31" },
{ column_index: 2, row_index: 222, wrong_data: "CABA31" },
],
});
}, []);
const showStyle = () => {
if (wrongData) {
const subject_data = [
{ column_index: 2, row_index: 74, wrong_data: "CYOG31" },
{ column_index: 2, row_index: 75, wrong_data: "CMPE11" },
{ column_index: 2, row_index: 76, wrong_data: "S2EN31" },
{ column_index: 2, row_index: 222, wrong_data: "CABA31" },
];
console.log("Subject data ==== ", subject_data);
console.log("wrong data ===== ", wrongData);
for (const data of subject_data) {
// row_index and column_index to identify the cell
const { column_index, row_index } = data;
// Use document.querySelector to target the specific cell
// Assuming the table rows are in order, and each cell has the class 'rt-td'
const querySelectorClass = `.rt-tr-group:nth-child(${
row_index - 1
}) .rt-td:nth-child(${column_index + 1})`;
console.log("query selector classs ==== ", querySelectorClass);
const cell = document.querySelector(querySelectorClass);
console.log("cell ====== ", cell);
// Apply red color if the cell exists
if (cell) {
cell.style.backgroundColor = "red";
cell.style.color = "white";
}
}
}
};
const handleSubmit = async (event) => {
event.preventDefault(); // Prevent the default form submission
if (file) {
setIsLoading(true);
let formData = new FormData();
formData.append("file", file); // Append the file
formData.append("degreeType", degreeType); // Append additional data
// Correct usage of fetch with 'body'
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/validate/insertionData`,
{
method: "POST",
body: formData, // Use 'body' instead of 'data'
}
);
// Check if the response is ok
if (response.ok) {
const responseData = await response.json();
console.log("Response Data: ", responseData);
if (responseData?.status === "success") {
showNotification("File Added To Queue Successfully...", "success");
fetchProcessList();
} else {
showNotification("Something Went Wrong ...", "error");
}
} else {
console.error("Error in response: ", response.statusText);
}
setIsLoading(false);
} else {
setIsLoading(false);
console.log("No file selected");
}
};
const showNotification = (message, type) => {
setNotification({ message, type });
};
const [age, setAge] = React.useState("");
const handleChange = (event) => {
setDegreeType(event.target.value);
};
return (
<AntdesignLayout>
<Box className="d-flex justify-content-between flex-row gap-5 p-5 align-items-start w-100">
<Box>
<Box>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">Degree Type</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={degreeType}
className="bg-white"
label="Degree Type"
onChange={handleChange}
>
<MenuItem value={10}>UG</MenuItem>
<MenuItem value={20}>PG</MenuItem>
<MenuItem value={30}>UNIVERSITY</MenuItem>
<MenuItem value={30}>SUPLLEMENTRY</MenuItem>
<MenuItem value={30}>PHD</MenuItem>
</Select>
</FormControl>
</Box>
<Box>
<form onSubmit={handleSubmit}>
<TextField
type="file" // Set type to "file"
inputProps={{ accept: ".csv" }} // Accept specific file types
onChange={handleFileChange} // Handle file change
fullWidth // Make the input full width
margin="normal" // Set margin for spacing
variant="outlined" // Choose the variant (outlined, filled, standard)
/>
<Button
type="submit"
variant="contained"
color="primary"
className="w-100"
style={{ marginTop: "16px" }} // Optional: add some margin
>
validate
</Button>
</form>
</Box>
</Box>
<Box style={{ width: "70%", margin: "auto", textAlign: "center" }}>
{processList.length > 0 && (
<>
<Box className="pb-3">
<h5>
<strong>Validation Process List:</strong>
</h5>
</Box>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>
<strong>ID</strong>
</TableCell>
<TableCell>
<strong>File Name</strong>
</TableCell>
<TableCell>
<strong>Status</strong>
</TableCell>
<TableCell>
<strong>Created on</strong>
</TableCell>
<TableCell>
<strong>Validation Status</strong>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{processList.map((processData) => (
<TableRow key={processData.job_vidh_ms_solutions_id}>
<TableCell>
{processData?.validation_status === "FAILED" ? (
<a href={`/data/insertion/validation?id=${processData.job_vidh_ms_solutions_id}`}>
{processData?.job_vidh_ms_solutions_id}
</a>
) : (
processData?.job_vidh_ms_solutions_id
)}
</TableCell>
<TableCell>{processData?.file_name}</TableCell>
<TableCell style={{ textAlign: "center" }}>
<button
style={{
backgroundColor:
processData?.status_code === "JF"
? "red"
: "green",
color: "white",
borderRadius: "10px",
padding: "3px 10px",
}}
>
{processData?.status_code}
</button>
</TableCell>
<TableCell>
{processData?.created_on
? new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}).format(parseCreatedOn(processData?.created_on))
: "N/A"}
</TableCell>
<TableCell>{processData?.validation_status}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</>
)}
</Box>
</Box>
{isLoading && <LoadingContainer />}
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
</AntdesignLayout>
);
};
export default DataInsertion;

View File

@ -0,0 +1,35 @@
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Box, Button } from "@mui/material";
import AntdesignLayout from "./AntdesignLayout";
import LoadingContainer from "./LoadingContainer";
import infinity_loader from "../../assets/Infinity_loader.gif";
import Notification from "./Notification"; // Import the Notification componentimport InputLabel from '@mui/material/InputLabel';
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
import InputLabel from "@mui/material/InputLabel";
import TextField from "@material-ui/core/TextField";
import CsvViewer from "react-csv-viewer";
import csvData from "/home/neuu/attendence_UI/backend/tmp/UG PENDING 17-09-2024.csv";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
} from "@mui/material";
const DataInsertionCsvViewer = () => {
const [isLoading, setIsLoading] = useState(false);
return (
<AntdesignLayout>
<CsvViewer />
{isLoading && <LoadingContainer />}
</AntdesignLayout>
);
};
export default DataInsertionCsvViewer;

View File

@ -0,0 +1,138 @@
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { styled } from "@mui/system";
import {
TablePagination,
tablePaginationClasses as classes,
} from "@mui/base/TablePagination";
import { Link } from "react-router-dom";
import TextField from "@mui/material/TextField";
import { Box } from "@mui/material";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
import Backdrop from "@mui/material/Backdrop";
import CircularProgress from "@mui/material/CircularProgress";
import Snackbar from "@mui/material/Snackbar";
import ImageDialog from "./ImageDialog";
import { ToastContainer, toast } from "react-toastify";
import DummyDuplicatesPreview from "./DummyDuplicatesPreview";
import LoadingContainer from "./LoadingContainer";
import AntdesignLayout from "./AntdesignLayout";
const DummyDuplicates = () => {
const [dummyDuplicatesData, setDummyDuplicatesData] = useState([]);
const [duplicateBarcodes, setDuplicateBarcodes] = useState([]);
const [isDialogOpen, setIsDialogOpen] = useState(false);
const [currentImagePath, setCurrentImagePath] = useState("");
const [barcode, SetBarcode] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [isUpdated,setIsUpdated] = useState(false)
const { type } = useParams();
console.log("Type ======= ", type);
useEffect(() => {
console.log("Dummy Duplicates data ======= ", dummyDuplicatesData);
}, [dummyDuplicatesData]);
useEffect(() => {
const fetchDuplicateBarcodes = async () => {
setIsLoading(true);
try {
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchDummyDuplicatesData`,
{
method: "POST",
body: JSON.stringify({
type,
}),
headers: {
"Content-Type": "application/json",
},
}
);
const responseData = await response.json();
setIsLoading(false);
console.log("Response Data ==== ", responseData);
if (responseData?.status == "success") {
console.log("The fetch Dumplicate records is success ....");
setDummyDuplicatesData(responseData?.data);
setDuplicateBarcodes(responseData?.duplicate_barcodes);
}
} catch (error) {
setIsLoading(false);
throw new Error(error);
}
};
fetchDuplicateBarcodes();
}, []);
const handleImagePreview = (e) => {
console.log("clicking barcode ...");
setIsDialogOpen(true);
console.log("e ========== ", e.target);
const ele = e.target;
console.log("ele ==== ", ele);
console.log("e.dataset ==== ", e.dataset);
console.log("barcode ==== ", ele.dataset.barcode);
const barcodeFromEle = ele.dataset.barcode;
if (barcodeFromEle) {
SetBarcode(barcodeFromEle);
}
};
const [openLoader, setOpenLoader] = useState(false);
const handleCloseLoader = () => {
setOpenLoader(false);
};
const handleOpenLoader = () => {
setOpenLoader(true);
};
return (
<AntdesignLayout>
{dummyDuplicatesData?.length > 0 && (
<Box className="my-3 px-2 w-100 text-left">
<h5>Duplicate Barcodes : {dummyDuplicatesData?.length}</h5>
</Box>
)}
{dummyDuplicatesData?.length > 0 &&
duplicateBarcodes.map((barcode) => (
<Box
className="p-3 rounded my-2 w-100 m-3 cursor-pointer overflow-auto"
style={{ cursor: "pointer",background:"white" }}
onClick={handleImagePreview}
data-barcode={barcode}
id = {barcode}
>
<h5 data-barcode={barcode}>{barcode}</h5>
</Box>
))}
{isDialogOpen && (
<>
<DummyDuplicatesPreview
type={type}
barcode={barcode}
setIsDialogOpen={setIsDialogOpen}
dummyDuplicatesData={dummyDuplicatesData}
/>
</>
)}
<Backdrop
sx={{ color: "#fff", zIndex: (theme) => theme.zIndex.drawer + 1 }}
open={openLoader}
>
<CircularProgress color="inherit" />
</Backdrop>
{isLoading && <LoadingContainer />}
</AntdesignLayout>
);
};
export default DummyDuplicates;

View File

@ -0,0 +1,478 @@
import * as React from "react";
import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import AppBar from "@mui/material/AppBar";
import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import CloseIcon from "@mui/icons-material/Close";
import Slide from "@mui/material/Slide";
import ZoomInIcon from "@mui/icons-material/ZoomIn";
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
import RotateRightIcon from "@mui/icons-material/RotateRight";
import { Box } from "@mui/material";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import TextInputField from "./TextInputField";
import { notification, Space } from "antd";
import { toast, ToastContainer } from "react-toastify";
import { useEffect, useState } from "react";
import LoadingContainer from "./LoadingContainer";
const Transition = React.forwardRef(function Transition(props, ref) {
return <Slide direction="up" ref={ref} {...props} />;
});
export default function DummyDuplicatesPreview({
type,
barcode,
dummyDuplicatesData,
setIsDialogOpen,
}) {
const [open, setOpen] = React.useState(false);
const [api, contextHolder] = notification.useNotification();
const [scaleWidthValue, setScaleWidthValue] = React.useState(80);
const [rotateValue, setRotateValue] = React.useState(0);
const [partAResults, setPartAResults] = React.useState([]);
const [partCResults, setPartCResults] = React.useState([]);
const [isLoading, setIsLoading] = React.useState(false);
const [partAImageIndex, setPartAImageIndex] = React.useState(0);
const [partCImageIndex, setPartCImageIndex] = React.useState(0);
const [inputBarcode, setInputBarcode] = useState(null);
const [inputSerialNo, setInputSerialNo] = useState(null);
const [inputSubjectCode, setInputSubjectCode] = useState(null);
const [inputRegisterNumber, setInputRegisterNumber] = useState(null);
const [partAImageS3Path, setPartAImageS3Path] = useState(null);
const [partCImageS3Path, setPartCImageS3Path] = useState(null);
const [loadingText, setLoadingText] = useState(null);
const [isUpdated, setIsUpdated] = useState(false);
const openNotification = (pauseOnHover) => () => {
api.open({
message: "Notification Title",
description: "Record Updated Successfully ....",
showProgress: true,
pauseOnHover,
});
};
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
setIsDialogOpen(false);
setTimeout(() => {
document.body.style.overflow = "auto";
const barcodeCardEle = document.getElementById(barcode);
console.log("barcodeCardEle ======== ", barcodeCardEle);
if (barcodeCardEle) {
if (isUpdated) {
barcodeCardEle.classList.add("completed");
} else {
barcodeCardEle.classList.add("visited");
}
}
}, 100);
};
React.useEffect(() => {
handleClickOpen();
}, []);
useEffect(() => {
if (partAResults.length > 0 && partAImageIndex <= partAResults.length) {
setPartAImageS3Path(partAResults[partAImageIndex]?.s3_path);
}
}, [partAResults]);
useEffect(() => {
console.log("fetchDuplicateBarcodeInfo .........");
const fetchDuplicateBarcodeInfo = async () => {
setIsLoading(true);
console.log("fetching barcode info 12.....");
setLoadingText(`Fetching Barcode Info : ${barcode}`);
try {
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchDummyDuplicateBarcodeInfo`,
{
method: "POST",
body: JSON.stringify({
type,
barcode,
}),
headers: {
"Content-Type": "application/json",
},
}
);
const responseData = await response.json();
setIsLoading(false);
setLoadingText(null);
console.log("Barcode info Response Data ==== ", responseData);
if (responseData?.status == "success") {
console.log("success");
setIsLoading(false);
setPartAResults(responseData?.part_a_results);
setPartCResults(responseData?.part_c_results);
}
} catch (error) {
setIsLoading(false);
setLoadingText(null);
throw new Error(error);
}
};
fetchDuplicateBarcodeInfo();
}, []);
const ZoomInImage = () => {
console.log("Zooming In Image ....");
const elements = document.getElementsByClassName("scanned-img");
for (var ele of elements) {
console.log("Ele is : ", ele);
const newScaleWidthValue = scaleWidthValue + 10;
setScaleWidthValue(newScaleWidthValue);
// ele.style.transform = `scale(${newScaleValue})`;
ele.style.width = `${newScaleWidthValue}%`;
}
};
const ZoomOutImage = () => {
console.log("Zooming Out Image ....");
const elements = document.getElementsByClassName("scanned-img");
for (var ele of elements) {
console.log("Ele is : ", ele);
const newScaleWidthValue = scaleWidthValue - 10;
setScaleWidthValue(newScaleWidthValue);
// ele.style.transform = `scale(${newScaleValue})`;
ele.style.width = `${newScaleWidthValue}%`;
}
};
const RotateImageLeft = () => {
const elements = document.getElementsByClassName("scanned-img");
for (var ele of elements) {
console.log("Ele is : ", ele);
const newRotateValue = rotateValue - 90;
setRotateValue(newRotateValue);
ele.style.transform = `rotate(${newRotateValue}deg)`;
}
};
const RotateImageRight = () => {
const elements = document.getElementsByClassName("scanned-img");
for (var ele of elements) {
console.log("Ele is : ", ele);
const newRotateValue = rotateValue + 90;
setRotateValue(newRotateValue);
ele.style.transform = `rotate(${newRotateValue}deg)`;
}
};
useEffect(() => {
if (partAResults.length > 0 && partAImageIndex <= partAResults.length) {
setLoadingText(null);
setIsLoading(true);
setInputBarcode(null);
setInputRegisterNumber(null);
setInputSubjectCode(null);
setPartAImageS3Path(null);
setInputSerialNo(null);
setTimeout(() => {
setInputBarcode(partAResults[partAImageIndex]?.barcode);
setInputRegisterNumber(partAResults[partAImageIndex]?.register_number);
setInputSubjectCode(partAResults[partAImageIndex]?.subject_code);
setPartAImageS3Path(partAResults[partAImageIndex]?.s3_path);
setInputSerialNo(partAResults[partAImageIndex]?.serial_no);
setIsLoading(false);
}, 500);
}
}, [dummyDuplicatesData, partAImageIndex]);
useEffect(() => {
console.log("part c image index changing ....", partCImageIndex);
if (partCResults.length > 0 && partCImageIndex <= partCResults.length) {
console.log("into if ..");
setPartCImageS3Path(null);
setTimeout(() => {
setPartCImageS3Path(partCResults[partCImageIndex]?.s3_path);
}, 5000);
}
}, [partCImageIndex]);
useEffect(() => {
if (partAImageS3Path) {
const fetchPartAImageData = async () => {
setIsLoading(true);
console.log("fetching Image info .....");
try {
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchPartAS3PathInfo`,
{
method: "POST",
body: JSON.stringify({
partAImageS3Path,
}),
headers: {
"Content-Type": "application/json",
},
}
);
const responseData = await response.json();
setIsLoading(false);
if (responseData?.status === "success") {
const imageInfo = responseData?.image_info;
console.log("Image info ====== ", imageInfo);
if (imageInfo && imageInfo.length > 0) {
setInputBarcode(imageInfo[0]?.barcode);
setInputRegisterNumber(imageInfo[0]?.register_number);
setInputSubjectCode(imageInfo[0]?.subject_code);
}
}
} catch (error) {
setIsLoading(false);
console.error("Error fetching barcode info:", error);
} finally {
setIsLoading(false);
}
};
fetchPartAImageData();
}
}, [partAImageS3Path]);
const updateDuplicateRecordData = async () => {
const regex = /^\d+(_\d+)?$/;
console.log("Regex ===== ", regex);
if (!regex.test(inputBarcode)) {
alert("Please enter valid Barcode");
return;
}
try {
setIsLoading(true);
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/updateDuplicateRecordData`,
{
method: "POST",
body: JSON.stringify({
DuplicatePartAbarcode: barcode,
inputBarcode,
inputRegisterNumber,
inputSerialNo,
inputSubjectCode,
partAS3Path: partAResults[partAImageIndex]?.s3_path,
partCS3Path: partCResults[partCImageIndex]?.s3_path,
}),
headers: {
"Content-Type": "application/json",
},
}
);
const responseData = await response.json();
setIsLoading(false);
console.log("Response Data ==== ", responseData);
if (responseData?.status == "success") {
console.log("Updated successfully ....");
if (responseData?.duplicate_record) {
alert(`Already a record with barcode is present : ${inputBarcode}`);
} else {
console.log("showing notification ...");
toast.success("Record updated Successfully ..");
setIsUpdated(true);
}
}
} catch (error) {
setIsLoading(false);
throw new Error(error);
}
};
return (
<React.Fragment>
<Dialog
fullScreen
open={open}
onClose={handleClose}
TransitionComponent={Transition}
style={{
zIndex: "100",
}}
>
<AppBar sx={{ position: "relative" }}>
{contextHolder}
<ToastContainer />
<Toolbar>
<IconButton
edge="start"
color="inherit"
onClick={handleClose}
aria-label="close"
>
<CloseIcon />
</IconButton>
<IconButton
color="inherit"
onClick={ZoomInImage}
aria-label="zoom in"
>
<ZoomInIcon />
</IconButton>
<IconButton
color="inherit"
onClick={ZoomOutImage}
aria-label="zoom out"
>
<ZoomOutIcon />
</IconButton>
<IconButton
color="inherit"
onClick={RotateImageLeft}
aria-label="rotate"
>
<RotateRightIcon />
</IconButton>
</Toolbar>
</AppBar>
<div
className="overflow-auto"
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100%",
overflow: "auto",
}}
>
{/* <img
className="scanned-img"
style={{ marginTop: "60%" }}
width={`${scaleWidthValue}%`}
// src={`https://docs.exampaper.vidh.ai/${imagePath}`}
alt="S3 Image"
/> */}
<Box className="d-flex flex-row">
<Box className="rounded bg-white d-flex flex-column align-items-center">
<Box>
{partAResults.length > 0 && (
<>
<Box className="text-center">
{partAImageIndex + 1 + "/" + partAResults.length}
</Box>
<Button
className="bg-primary text-white m-3"
onClick={() => {
if (partAImageIndex !== 0) {
setPartAImageIndex((prev) => prev - 1);
}
}}
>
<ArrowBackIcon />
</Button>
<Button
className="bg-primary text-white m-3"
onClick={() => {
console.log("partAimage Index === ", partAImageIndex);
if (partAImageIndex < partAResults.length - 1) {
setPartAImageIndex((prev) => prev + 1);
}
}}
>
<ArrowForwardIcon />
</Button>
</>
)}
</Box>
{partAResults.length > 0 && (
<img
alt="Part-A Image"
src={`https://docs.exampaper.vidh.ai/${partAImageS3Path}`}
width={"900px"}
/>
)}
</Box>
<Box className="rounded bg-white d-flex flex-column align-items-center">
<Box>
{partCResults.length > 0 && (
<>
<Box className="text-center">
{partCImageIndex + 1 + "/" + partCResults.length}
</Box>
<Button
className="bg-primary text-white m-3"
onClick={() => {
if (partCImageIndex !== 0) {
setPartCImageIndex((prev) => prev - 1);
}
}}
>
<ArrowBackIcon />
</Button>
<Button
className="bg-primary text-white m-3"
onClick={() => {
console.log("partCimage Index === ", partCImageIndex);
if (partCImageIndex < partCResults.length - 1) {
setPartCImageIndex((prev) => prev + 1);
}
}}
>
<ArrowForwardIcon />
</Button>
</>
)}
</Box>
{partCResults.length > 0 && (
<img
alt="Part-C Image"
src={`https://docs.exampaper.vidh.ai/${partCResults[partCImageIndex]?.s3_path}`}
width={"900px"}
/>
)}
</Box>
</Box>
</div>
{partAResults.length > 0 && (
<Box className="d-flex justify-content-center align-items-center gap-3 m-3">
<TextInputField
value={inputBarcode}
setValue={setInputBarcode}
placeholder={"Barcode"}
/>
<TextInputField
value={inputSerialNo}
setValue={setInputSerialNo}
placeholder={"Serial No"}
/>
<TextInputField
value={inputSubjectCode}
setValue={setInputSubjectCode}
placeholder={"Subject Code"}
/>
<TextInputField
value={inputRegisterNumber}
setValue={setInputRegisterNumber}
placeholder={"Register Number"}
/>
<Button
className="bg-primary rounded text-white px-5"
style={{ height: "50px" }}
onClick={updateDuplicateRecordData}
>
Update
</Button>
</Box>
)}
</Dialog>
{isLoading && <LoadingContainer loadingText={loadingText} />}
</React.Fragment>
);
}

22
src/Components/Footer.jsx Normal file
View File

@ -0,0 +1,22 @@
import { Height } from "@mui/icons-material";
import { Box } from "@mui/material";
const Footer = () => {
const footerStyle = {
Height: "100px",
position: "absolute",
bottom: "0",
left: "0",
backgroundColor: "#defbef",
color: "black",
width: "100%",
padding: "20px",
};
return (
<Box style={footerStyle}>
<Box className="d-flex justify-content-center align-items-center gap-2"><span>©</span><span>exampaper.usln.in.</span></Box>
</Box>
);
};
export default Footer;

View File

@ -1,73 +1,36 @@
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import HomepageCard from "./HomepageCard"; import HomepageCard from "./HomepageCard";
import {useState,useEffect} from "react" import { useState, useEffect } from "react";
import Notification from "./Notification";
import Footer from "./Footer";
const Home = () => { const Home = () => {
const cards = [ const cards = [
{ {
title: "Reassigned Serial No Anomoly Manual Updation (ATTENDANCE)", title: "APRIL-2024 Examination",
url: "/anomoly/attendence", url: "/sections/april2024",
},
// {
// title: "Part A OCR Anomoly - Batch 2022",
// url: "/anomoly/partA",
// },
{
title: "Part A OCR Anomoly Dummy",
url: "/anomoly/partA?type=new",
}, },
{ {
title: "Part A OCR Anomoly - Old Dummy", title: "NOVEMBER-2024 Examination",
url: "/anomoly/partA?type=old", url: "/sections/november2024",
}, },
{
title: "Part C",
url: "/anomoly/partC",
},
// {
// title:"Verification",
// url:"/verification"
// }
{
title:"SQL Playground",
url:"/sqlPlayground"
},
{
title:"QR Code Scanner",
url:"/barcodeScanner"
},
{
title:"EV Qrcode",
url:"/evQrcode"
},
{
title:"PlayGrounds",
url:"/Playgrounds"
}
// {
// title:"Marks Verfication",
// url:"/part-c/marks/verify"
// }
]; ];
// const cards = [
// {
// title: "Reassingned Serial No Anomoly Manual Updation",
// url: "/anomoly/reassigned",
// }]
return ( return (
<> <>
<Box> <Box className="overflow-auto">
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3"> <Box className="d-flex justify-content-center text-light bg-primary rounded py-3">
<h1>Welcome to exampaper.vidh.ai</h1> <h3>
<strong>MSU Software Solutions</strong>
</h3>
</Box> </Box>
<Box className="p-3" style={{width:'100%'}}> <Box className="p-3" style={{ width: "100%" }}>
{cards.map((card) => ( {cards.map((card) => (
<HomepageCard title={card?.title} url={card?.url} /> <HomepageCard title={card?.title} url={card?.url} />
))} ))}
</Box> </Box>
</Box> </Box>
<Footer/>
</> </>
); );
}; };

View File

@ -0,0 +1,105 @@
import { Box } from "@mui/material";
import HomepageCard from "./HomepageCard";
import {useState,useEffect} from "react"
import Notification from "./Notification";
import { useParams } from 'react-router-dom';
const HomeSections = () => {
const { year } = useParams()
const cards = [
// {
// title:"Data Insertion",
// url:`/sections/${year}/data/insertion`
// },
// {
// title:"Certificate Generation",
// url:`/sections/${year}/certificate/gen`
// },
{
title: "Reassigned Serial No Anomoly Manual Updation (ATTENDANCE)",
url: `/sections/${year}/anomoly/attendence`,
},
// {
// title: "Part A OCR Anomoly - Batch 2022",
// url: "/anomoly/partA",
// },
{
title: "Part A OCR Anomoly Dummy",
url: `/sections/${year}/anomoly/partA?type=new`,
},
{
title: "Part A OCR Anomoly - Old Dummy",
url: `/sections/${year}/anomoly/partA?type=old`,
},
{
title: "Part C",
url: `/sections/${year}/anomoly/partC`,
},
// {
// title:"Verification",
// url:"/verification"
// }
{
title:"SQL Playground",
url:`/sections/${year}/sqlPlayground`
},
{
title:"QR Code Finder",
url:`/sections/${year}/qrcodeFinder`
},
// {
// title:"QR Code Scanner",
// url:`/sections/${year}/barcodeScanner`
// },
// {
// title:"EV Qrcode",
// url:`/sections/${year}/evQrcode`
// },
{
title:"PlayGrounds",
url:`/sections/${year}/Playgrounds`
},
{
title:"Attendence Not Shaded Solver",
url:`/sections/${year}/attendenceNotShadedCorrection`
}
// {
// title:"Revaluation",
// url:"/revaluation"
// },
// {
// title:"Marks Verfication",
// url:"/part-c/marks/verify"
// }
// {
// title:"Part-A Dummy Duplicates",
// url:`/sections/${year}/DummyDuplicates/PartA`
// },
];
// const cards = [
// {
// title: "Reassingned Serial No Anomoly Manual Updation",
// url: "/anomoly/reassigned",
// }]
return (
<>
<Box className="overflow-auto">
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3">
<h3><strong>MSU Software Solutions</strong></h3>
</Box>
<Box className="p-3" style={{width:'100%'}}>
{cards.map((card) => (
<HomepageCard title={card?.title} url={card?.url} />
))}
</Box>
</Box>
</>
);
};
export default HomeSections;

View File

@ -7,7 +7,8 @@ const HomepageCard = ({ title, url }) => {
return ( return (
<Row <Row
gutter={16} gutter={16}
className="p-2" className="p-2 cursor-pointer"
style={{cursor:"pointer !important"}}
> >
<Col span={24}> <Col span={24}>
<Card <Card
@ -18,7 +19,7 @@ const HomepageCard = ({ title, url }) => {
bordered={true} bordered={true}
style={{with:'100%'}} style={{with:'100%'}}
> >
{title} <strong>{title}</strong>
</Card> </Card>
</Col> </Col>
</Row> </Row>

View File

@ -0,0 +1,231 @@
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Box, Button } from "@mui/material";
import AntdesignLayout from "./AntdesignLayout";
import LoadingContainer from "./LoadingContainer";
import infinity_loader from "../../assets/Infinity_loader.gif";
import Notification from "./Notification"; // Import the Notification component
import { Height } from "@mui/icons-material";
import ZoomInIcon from "@mui/icons-material/ZoomIn";
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
} from "@mui/material";
const IndividualMarksheetGen = () => {
const [registerNumber, setRegisterNumber] = useState(null);
const [courseCode, setCourseCode] = useState(null);
const [isLoading, setIsLoading] = useState(null);
const [notification, setNotification] = useState(null);
const [processList, setProcesList] = useState([]);
const showNotification = (message, type) => {
setNotification({ message, type });
};
const uploadDataStyleContainer = {
backgroundColor: "white",
borderRadius: "10px",
minWidth: "800px",
padding: "20px",
margin: "10px",
};
useEffect(() => {
fetchProcessList();
const fetchInterval = setInterval(() => {
fetchProcessList();
}, 20000);
return () => {
clearInterval(fetchInterval);
};
}, []);
const fetchProcessList = async () => {
try {
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchCertificateProcessList`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const responseData = await response.json();
console.log("Response ==== ", responseData);
if (responseData?.status == "success") {
setProcesList(responseData?.data);
}
} catch (error) {
console.log(error);
}
};
const triggenCertificateGen = async () => {
console.log("Button clicked ..");
console.log("Register number ==== ", registerNumber);
if (!registerNumber) {
console.log("returning ....");
return;
}
try {
const payload = {
registerNumber: registerNumber.trim(),
};
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/triggerCertificateGen`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("Response ==== ", responseData);
setIsLoading(false);
if (responseData?.status == "success") {
showNotification("Process Started ...", "success");
fetchProcessList();
} else if (responseData?.status == "failed") {
showNotification("Something went wrong ...", "error");
} else if (responseData?.status == "invalid") {
showNotification("Invalid Register No ...", "error");
}
} catch (error) {
setIsLoading(false);
console.log(error);
}
};
return (
<AntdesignLayout>
<Box
className="d-flex justify-content-center w-100 gap-3 align-items-center mx-auto"
style={{ maxWidth: "1600px" }}
>
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
<strong>Register Number</strong>
</label>
<input
type="text"
className="form-control p-3"
id="regnoInput"
placeholder="Eg : 20213091515201"
onChange={(e) => setRegisterNumber(e.target.value)}
style={{ width: "600px" }}
/>
</div>
<button
type="button"
className="btn btn-primary btn-sm px-4 h-75"
onClick={triggenCertificateGen}
>
Submit
</button>
<Link to="/certificate/gen/upload">
<button
type="button"
className="btn btn-primary btn-sm px-4 h-75"
onClick={triggenCertificateGen}
>
Upload Data
</button>
</Link>
</Box>
<Box style={{ width: "70%", margin: "auto", textAlign: "center" }}>
{processList.length > 0 && (
<>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>
<strong>ID</strong>
</TableCell>
<TableCell>
<strong>Register Number</strong>
</TableCell>
<TableCell>
<strong>Status</strong>
</TableCell>
<TableCell>
<strong>Created on</strong>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{processList.map((processData) => (
<TableRow key={processData.job_vidh_ms_solutions_id}>
<TableCell>
{processData?.job_vidh_ms_solutions_id}
</TableCell>
{processData?.status_code == "JS" ? (
<TableCell><a target="__blank" href={`http://files.usln.in/individual_files_gen/${processData?.register_number}_certificates.pdf`}>{processData?.register_number}</a></TableCell>
) : (
<TableCell>{processData?.register_number}</TableCell>
)}
<TableCell style={{ textAlign: "center" }}>
<button
style={{
backgroundColor:
processData?.status_code === "JF"
? "red"
: "green",
color: "white",
borderRadius: "10px",
padding: "3px 10px",
}}
>
{processData?.status_code}
</button>
</TableCell>
<TableCell>
{processData?.created_on
? new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}).format(parseCreatedOn(processData?.created_on))
: "N/A"}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</>
)}
</Box>
{isLoading && <LoadingContainer />}
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
</AntdesignLayout>
);
};
export default IndividualMarksheetGen;

View File

@ -0,0 +1,248 @@
import React, { useState, useEffect } from "react";
import { Box, Button } from "@mui/material";
import AntdesignLayout from "./AntdesignLayout";
import LoadingContainer from "./LoadingContainer";
import infinity_loader from "../../assets/Infinity_loader.gif";
import Notification from "./Notification"; // Import the Notification component
import { Height } from "@mui/icons-material";
import ZoomInIcon from "@mui/icons-material/ZoomIn";
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
const IndividualStudAttendence = () => {
const [registerNumber, setRegisterNumber] = useState(null);
const [subjectCode, setSubjectCode] = useState(null);
const [attendenceSerialNo, setAttendenceSerialNo] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [attendenceResults, setAttendenceResults] = useState(null);
const [zoomValue, setZoomValue] = useState(950);
const [absentStatus, setAbsentStatus] = useState(-1);
const [notification, setNotification] = useState(null); // Notification state
const [type, setType] = useState(null);
const showNotification = (message, type) => {
setNotification({ message, type });
};
const updateStudentStatus = async () => {
setIsLoading(true);
try {
const payload = {
attendenceResults,
absentStatus,
attendenceSerialNo,
register_number: registerNumber,
subject_code: subjectCode,
};
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/updateStudentAttendenceStatus`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("The response data ===== ", responseData);
if (responseData?.status === "success") {
fetchAttendenceData();
showNotification("Record updated successfully !!", "success");
}
setIsLoading(false);
} catch (error) {
setIsLoading(false);
console.error("Error updating student status:", error);
showNotification("Error updating student status", "error");
}
};
useEffect(() => {
console.log("Absent status changed ==== ", absentStatus);
if (Number(absentStatus) === 0 || Number(absentStatus) === 1) {
updateStudentStatus();
}
}, [absentStatus]);
const fetchAttendenceData = async () => {
setAbsentStatus(-1);
if (!attendenceSerialNo) {
if (!registerNumber || !subjectCode) {
showNotification(
"Registration Number && Subject Code is Mandatory !!",
"error"
);
return;
}
}
if (registerNumber && subjectCode) {
setType(1);
} else if (attendenceSerialNo) {
setType(2);
}
setIsLoading(true);
try {
const payload = {
registerNumber,
subjectCode,
attendenceSerialNo,
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchAttendenceData`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("response data ========= ", responseData);
setIsLoading(false);
if (responseData?.status === "success") {
setAttendenceResults(responseData?.results);
setType(responseData?.type)
}
} catch (error) {
setIsLoading(false);
console.error("Error fetching attendance data:", error);
showNotification("Error fetching attendance data", "error");
}
};
return (
<AntdesignLayout>
<Box className="d-flex justify-content-center w-100 gap-3 align-items-center">
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
Register Number:
</label>
<input
type="text"
className="form-control p-3"
id="exampleFormControlInput1"
placeholder="Eg : 202385510254788"
onChange={(e) => setRegisterNumber(e.target.value)}
/>
</div>
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
Subject Code:
</label>
<input
type="text"
className="form-control p-3"
id="exampleFormControlInput1"
placeholder="Eg : E1TL11"
onChange={(e) => setSubjectCode(e.target.value)}
/>
</div>
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
Attendence Serial No:
</label>
<input
type="text"
className="form-control p-3"
id="exampleFormControlInput1"
placeholder=""
onChange={(e) => setAttendenceSerialNo(e.target.value)}
/>
</div>
<button
type="button"
className="btn btn-primary btn-sm px-4 h-75"
onClick={fetchAttendenceData}
>
Submit
</button>
</Box>
{attendenceResults?.length > 0 && (
<Box className="d-flex justify-content-center gap-5 mx-5">
<Box className="text-left" style={{ maxWidth: "500px" }}>
{Object.keys(attendenceResults[0]).map((key, index) => (
<Box key={index}>
<strong>
{key} : {attendenceResults[0][key]}
</strong>
</Box>
))}
{type === 1 && (
<Box className="d-flex gap-3 my-3">
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => setAbsentStatus(1)}
>
Mark As Absent
</Button>
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => setAbsentStatus(0)}
>
Mark As Present
</Button>
</Box>
)}
</Box>
<Box>
<Box className="d-flex justify-content-end gap-3 my-3">
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => setZoomValue((prev) => prev + 50)}
>
<ZoomInIcon />
</Button>
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => setZoomValue((prev) => prev - 50)}
>
<ZoomOutIcon />
</Button>
</Box>
<Box
id="image-container"
className="overflow-auto d-flex flex-column"
style={{ height: `${type === 1 ? "80vh" : ""}` }}
>
{attendenceResults.length > 0 && type === 2 && (
<img
src={`https://docs.exampaper.vidh.ai/${attendenceResults[0]?.s3_image_path}`}
width={`${zoomValue}px`}
alt="Attendence-image"
/>
)}
{attendenceResults.length > 0 && type === 1 && (
<img
src={`https://docs.exampaper.vidh.ai/${attendenceResults[0]?.s3_path}`}
width={`${zoomValue}px`}
alt="Attendence-image"
/>
)}
</Box>
</Box>
</Box>
)}
{attendenceResults?.length == 0 && (
<Box className="my-3">Attendence Record Not Found !!</Box>
)}
{isLoading && <LoadingContainer />}
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
</AntdesignLayout>
);
};
export default IndividualStudAttendence;

View File

@ -29,9 +29,12 @@ const LoadingContainer = ({ loadingText }) => {
className="d-flex justify-content-center align-items-center" className="d-flex justify-content-center align-items-center"
style={LoadingContainerStyle} style={LoadingContainerStyle}
> >
<Spinner animation="border" variant="light" role="status"> <Box className="d-flex flex-column align-items-center justify-content-center gap-2">
<span className="visually-hidden">Loading...</span> <h6 className="text-white">{loadingText}</h6>
</Spinner> <Spinner animation="border" variant="light" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>
</Box>
</Box> </Box>
</> </>
); );

51
src/Components/Login.jsx Normal file
View File

@ -0,0 +1,51 @@
import { Height } from "@mui/icons-material";
import { Box, Button } from "@mui/material";
import TextInputField from "./TextInputField";
import AccountCircleIcon from "@mui/icons-material/AccountCircle";
import { useState, useEffect } from "react";
const Login = () => {
const [username,setUsername] = useState(null)
const [password,setPassword] = useState(null)
const loginContainerStyle = {
backgroundColor: "white",
width: "500px",
Height: "500px",
borderRadius: "15px",
padding: "25px",
};
const loginMainContainerStyle = {
position: "absolute",
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "rgba(0,0,0,0.5)",
height: "100%",
top: "0",
left: "0",
};
const accountIconStyle = {
width: "50px",
height: "auto",
color: "blue",
};
return (
<Box style={loginMainContainerStyle}>
<Box style={loginContainerStyle}>
<AccountCircleIcon style={accountIconStyle} />
<TextInputField placeholder={"Username"} />
<TextInputField placeholder={"Password"} />
<Button className="bg-primary rounded p-3 text-white my-4 w-100">
Submit
</Button>
</Box>
</Box>
);
};
export default Login;

View File

@ -0,0 +1,117 @@
// // import React, { useEffect, useState } from 'react';
// // import PropTypes from 'prop-types';
// // const Notification = ({ message, type, onClose, duration }) => {
// // const [visible, setVisible] = useState(true);
// // useEffect(() => {
// // const timer = setTimeout(() => {
// // setVisible(false);
// // setTimeout(onClose, 300); // Allow time for the fade-out transition
// // }, duration);
// // return () => clearTimeout(timer);
// // }, [onClose, duration]);
// // return (
// // <div className={`notification ${type} ${visible ? 'show' : 'hide'}`}>
// // {message}
// // </div>
// // );
// // };
// // Notification.propTypes = {
// // message: PropTypes.string.isRequired,
// // type: PropTypes.string,
// // onClose: PropTypes.func.isRequired,
// // duration: PropTypes.number
// // };
// // Notification.defaultProps = {
// // type: 'info',
// // duration: 1000 // Set duration to 1000 milliseconds (1 second)
// // };
// // export default Notification;
// import React, { useEffect, useState } from 'react';
// import PropTypes from 'prop-types';
// const Notification = ({ message, type, onClose, duration }) => {
// const [visible, setVisible] = useState(true);
// console.log("From notification container ....")
// useEffect(() => {
// const timer = setTimeout(() => {
// setVisible(false);
// setTimeout(onClose, 300); // Allow time for the fade-out transition
// }, duration);
// return () => clearTimeout(timer);
// }, [onClose, duration]);
// return (
// visible && (
// <div className={`notification ${type} ${visible ? 'show' : 'hide'}`}>
// {message}
// </div>
// )
// );
// };
// Notification.propTypes = {
// message: PropTypes.string.isRequired,
// type: PropTypes.string,
// onClose: PropTypes.func.isRequired,
// duration: PropTypes.number
// };
// Notification.defaultProps = {
// type: 'info',
// duration: 3000 // Set duration to 3000 milliseconds (3 seconds)
// };
// export default Notification;
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
const Notification = ({ message, type, onClose, duration }) => {
const [visible, setVisible] = useState(true);
console.log("From notification container ....");
useEffect(() => {
console.log("Notification useEffect triggered ....");
const timer = setTimeout(() => {
setVisible(false);
setTimeout(onClose, 300); // Allow time for the fade-out transition
}, duration);
return () => clearTimeout(timer);
}, [onClose, duration]);
return (
visible && (
<div className={`notification ${type} ${visible ? 'show' : 'hide'}`}>
{message}
</div>
)
);
};
Notification.propTypes = {
message: PropTypes.string.isRequired,
type: PropTypes.string,
onClose: PropTypes.func.isRequired,
duration: PropTypes.number
};
Notification.defaultProps = {
type: 'info',
duration: 3000 // Set duration to 3000 milliseconds (3 seconds)
};
export default Notification;

View File

@ -32,6 +32,9 @@ import {
} from "react-redux"; } from "react-redux";
import useEnhancedEffect from "@mui/material/utils/useEnhancedEffect"; import useEnhancedEffect from "@mui/material/utils/useEnhancedEffect";
import SystemNumberDialog from "./SystemNumberDialog"; import SystemNumberDialog from "./SystemNumberDialog";
import FormControl from "@mui/material/FormControl";
import Select, { selectClasses } from "@mui/material/Select";
import MenuItem from "@mui/material/MenuItem";
const { Header, Content, Footer, Sider } = Layout; const { Header, Content, Footer, Sider } = Layout;
function getItem(label, key, icon, children) { function getItem(label, key, icon, children) {
@ -49,9 +52,11 @@ const PartAReassigned = () => {
const [collapsed, setCollapsed] = useState(false); const [collapsed, setCollapsed] = useState(false);
const [anomolyData, setAnomolyData] = useState([]); const [anomolyData, setAnomolyData] = useState([]);
const [tableRowData, setTableRowData] = useState([]); const [tableRowData, setTableRowData] = useState([]);
const [selectedDegreeType, setSelectedDegreeType] = useState(null);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [windowWidth, setWindowWidth] = useState(window.innerWidth); const [windowWidth, setWindowWidth] = useState(window.innerWidth);
let [searchParams, setSearchParams] = useSearchParams(); let [searchParams, setSearchParams] = useSearchParams();
const [showSystemNoContainer, setShowSystemNoContainer] = useState(false); const [showSystemNoContainer, setShowSystemNoContainer] = useState(false);
const searchParamsType = searchParams.get("type"); const searchParamsType = searchParams.get("type");
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -60,6 +65,27 @@ const PartAReassigned = () => {
); );
const reduxSystemNo = useSelector((state) => state?.systemNumber); const reduxSystemNo = useSelector((state) => state?.systemNumber);
console.log("Redux partA 2023 anomoly data : ", reduxPartA2023AnomolyData); console.log("Redux partA 2023 anomoly data : ", reduxPartA2023AnomolyData);
const degreeTypes = [
{ type: "NON VOCATIONAL", type_code: "0" },
{ type: "VOCATIONAL", type_code: "6" },
];
const handleDegreeTypeChange = (e) => {
const newDegreeType = e.target.value;
console.log("Value ===== ", newDegreeType);
setSelectedDegreeType(newDegreeType);
// dispatch(updatePartCDegreeType(newDegreeType));
};
useEffect(() => {
if (!selectedDegreeType) {
setSelectedDegreeType("0");
}
}, []);
useEffect(() => {
console.log("Selected degree type in use Effect === ", selectedDegreeType);
}, [selectedDegreeType]);
useEffect(() => { useEffect(() => {
if (!reduxSystemNo) { if (!reduxSystemNo) {
@ -77,7 +103,10 @@ const PartAReassigned = () => {
// localstorageRecords = JSON.parse(localstorageRecords); // localstorageRecords = JSON.parse(localstorageRecords);
// } // }
// } // }
fetchAnomalyData(reduxSystemNo) if (selectedDegreeType) {
fetchAnomalyData(reduxSystemNo);
}
// if (localstorageRecords && localstorageRecords.length > 0) { // if (localstorageRecords && localstorageRecords.length > 0) {
// console.log( // console.log(
// "Length of local storage records is high so aborting fetching ..." // "Length of local storage records is high so aborting fetching ..."
@ -112,7 +141,7 @@ const PartAReassigned = () => {
// const sytemData = localStorage.get("part-a-old-anomoly") // const sytemData = localStorage.get("part-a-old-anomoly")
// } // }
} }
}, [reduxSystemNo]); }, [reduxSystemNo, selectedDegreeType]);
useEffect(() => { useEffect(() => {
const handleResize = () => { const handleResize = () => {
@ -157,7 +186,7 @@ const PartAReassigned = () => {
const updateSystemReservationStatus = async (systemRecords) => { const updateSystemReservationStatus = async (systemRecords) => {
const payload = { const payload = {
systemRecords, systemRecords,
sysNo:reduxSystemNo sysNo: reduxSystemNo,
}; };
try { try {
fetch( fetch(
@ -187,7 +216,7 @@ const PartAReassigned = () => {
fetch( fetch(
`${ `${
import.meta.env.VITE_REACT_APP_BACKEND_URL import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchAnamolyPartAData?type=${searchParamsType}&sysNo=${reduxSystemNo}`, }/fetchAnamolyPartAData?type=${searchParamsType}&sysNo=${reduxSystemNo}&degreeType=${selectedDegreeType}`,
{ {
method: "GET", method: "GET",
headers: { headers: {
@ -203,15 +232,15 @@ const PartAReassigned = () => {
console.log("Response Data is : ", responseData); console.log("Response Data is : ", responseData);
setIsLoading(false); setIsLoading(false);
if (responseData.status === "success") { if (responseData.status === "success") {
console.log("System record ====== ",responseData.systemRecord) console.log("System record ====== ", responseData.systemRecord);
var systemRecords = responseData?.data var systemRecords = responseData?.data;
if(!responseData.systemRecord){ if (!responseData.systemRecord) {
systemRecords = getRecordsBySystemId( systemRecords = getRecordsBySystemId(
responseData?.data, responseData?.data,
reduxSystemNo reduxSystemNo
); );
} }
updateSystemReservationStatus(systemRecords); //updateSystemReservationStatus(systemRecords);
console.log("System records : ", systemRecords); console.log("System records : ", systemRecords);
if (searchParamsType === "old") { if (searchParamsType === "old") {
localStorage.setItem( localStorage.setItem(
@ -351,6 +380,22 @@ const PartAReassigned = () => {
margin: "16px 16px", margin: "16px 16px",
}} }}
> >
<Box className="w-25 text-left">
<h6>Degree Type</h6>
<FormControl fullWidth>
<Select
className="bg-white"
value={selectedDegreeType}
onChange={handleDegreeTypeChange}
>
{degreeTypes.map((degree) => (
<MenuItem key={degree.type_code} value={degree.type_code}>
{degree.type}
</MenuItem>
))}
</Select>
</FormControl>
</Box>
<Box className="w-100 d-flex justify-content-between"> <Box className="w-100 d-flex justify-content-between">
<Box className="w-100 d-flex justify-content-center"> <Box className="w-100 d-flex justify-content-center">
{tableRowData.length > 0 && ( {tableRowData.length > 0 && (

View File

@ -0,0 +1,325 @@
import React, { useState, useEffect } from "react";
import { Box, Button } from "@mui/material";
import AntdesignLayout from "./AntdesignLayout";
import LoadingContainer from "./LoadingContainer";
import infinity_loader from "../../assets/Infinity_loader.gif";
import Notification from "./Notification"; // Import the Notification component
import { Height } from "@mui/icons-material";
import ZoomInIcon from "@mui/icons-material/ZoomIn";
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
const PendingAttendenceCorrection = () => {
const [registerNumber, setRegisterNumber] = useState(null);
const [subjectCode, setSubjectCode] = useState(null);
const [attendenceSerialNo, setAttendenceSerialNo] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [attendenceResults, setAttendenceResults] = useState(null);
const [zoomValue, setZoomValue] = useState(950);
const [absentStatus, setAbsentStatus] = useState(-1);
const [notification, setNotification] = useState(null); // Notification state
const [type, setType] = useState(null);
const [attendenceIndex, setAttendenceIndex] = useState(0);
const showNotification = (message, type) => {
setNotification({ message, type });
};
useEffect(() => {
const fetchingPendingData = async () => {
setType(1);
setIsLoading(true);
try {
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchPendingAttendenceData`,
{
method: "GET",
}
);
const responseData = await response.json();
console.log("The response data ===== ", responseData);
setIsLoading(false);
if (responseData?.status === "success") {
setAttendenceResults(responseData?.attendence_results);
}
} catch (error) {
setIsLoading(false);
console.error("Error updating student status:", error);
}
};
fetchingPendingData();
}, []);
const updateStudentStatus = async () => {
setIsLoading(true);
try {
const payload = {
attendenceResults,
absentStatus,
attendenceSerialNo,
register_number: registerNumber,
subject_code: subjectCode,
};
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/updateStudentAttendenceStatus`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("The response data ===== ", responseData);
if (responseData?.status === "success") {
setAttendenceIndex((prev) => prev + 1);
showNotification("Record updated successfully !!", "success");
setAbsentStatus(-1)
}
setIsLoading(false);
} catch (error) {
setIsLoading(false);
console.error("Error updating student status:", error);
showNotification("Error updating student status", "error");
}
};
useEffect(() => {
console.log("Absent status changed ==== ", absentStatus);
if (Number(absentStatus) === 0 || Number(absentStatus) === 1) {
updateStudentStatus();
}
}, [absentStatus]);
const fetchAttendenceData = async () => {
setAbsentStatus(-1);
if (!attendenceSerialNo) {
if (!registerNumber || !subjectCode) {
showNotification(
"Registration Number && Subject Code is Mandatory !!",
"error"
);
return;
}
}
if (registerNumber && subjectCode) {
setType(1);
} else if (attendenceSerialNo) {
setType(2);
}
setIsLoading(true);
try {
const payload = {
registerNumber,
subjectCode,
attendenceSerialNo,
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchAttendenceData`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("response data ========= ", responseData);
setIsLoading(false);
if (responseData?.status === "success") {
setType(responseData?.type);
const modifiedResponseData = responseData?.results;
console.log("attendence response data ===== ", modifiedResponseData);
if (modifiedResponseData) {
setAttendenceResults((prevResults) => {
const newAttendenceData = [...prevResults];
newAttendenceData[attendenceIndex] = modifiedResponseData;
console.log("new attendence data ==== ", newAttendenceData);
return newAttendenceData;
});
}
}
} catch (error) {
setIsLoading(false);
console.error("Error fetching attendance data:", error);
showNotification("Error fetching attendance data", "error");
}
};
useEffect(() => {
if (attendenceResults?.length > 0) {
setRegisterNumber(attendenceResults[attendenceIndex]?.register_number);
setSubjectCode(attendenceResults[attendenceIndex]?.subject_code);
}
}, [attendenceIndex, attendenceResults]);
return (
<AntdesignLayout>
{/* <Box className="d-flex justify-content-center w-100 gap-3 align-items-center">
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
Register Number:
</label>
<input
type="text"
className="form-control p-3"
id="exampleFormControlInput1"
placeholder="Eg : 202385510254788"
onChange={(e) => setRegisterNumber(e.target.value)}
/>
</div>
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
Subject Code:
</label>
<input
type="text"
className="form-control p-3"
id="exampleFormControlInput1"
placeholder="Eg : E1TL11"
onChange={(e) => setSubjectCode(e.target.value)}
/>
</div>
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
Attendence Serial No:
</label>
<input
type="text"
className="form-control p-3"
id="exampleFormControlInput1"
placeholder=""
onChange={(e) => setAttendenceSerialNo(e.target.value)}
/>
</div>
<button
type="button"
className="btn btn-primary btn-sm px-4 h-75"
onClick={fetchAttendenceData}
>
Submit
</button>
</Box> */}
{attendenceResults?.length > 0 && (
<Box className="d-flex justify-content-center gap-5 mx-5">
<Box className="text-left" style={{ maxWidth: "500px" }}>
{Object.keys(attendenceResults[attendenceIndex]).map(
(key, index) => (
<Box key={index}>
<strong>
{key} : {attendenceResults[attendenceIndex][key]}
</strong>
</Box>
)
)}
{type === 1 && (
<>
<Box className="d-flex gap-3 my-3">
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => setAbsentStatus(1)}
>
Mark As Absent
</Button>
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => setAbsentStatus(0)}
>
Mark As Present
</Button>
</Box>
</>
)}
</Box>
<Box>
<Box className="d-flex justify-content-end">
<strong>
{attendenceIndex + 1 + " / " + attendenceResults.length}
</strong>
</Box>
<Box className="d-flex justify-content-end gap-3 my-3">
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => setZoomValue((prev) => prev + 50)}
>
<ZoomInIcon />
</Button>
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => setZoomValue((prev) => prev - 50)}
>
<ZoomOutIcon />
</Button>
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => {
if (attendenceIndex !== 0) {
setAttendenceIndex((prev) => prev - 1);
}
}}
>
<ArrowBackIcon />
</Button>
<Button
className="btn bg-primary rounded text-white p-3"
onClick={() => {
if (attendenceIndex < attendenceResults.length) {
setAttendenceIndex((prev) => prev + 1);
}
}}
>
<ArrowForwardIcon />
</Button>
</Box>
<Box
id="image-container"
className="overflow-auto d-flex flex-column"
style={{ height: `${type === 1 ? "80vh" : ""}` }}
>
{attendenceResults.length > 0 && type === 2 && (
<img
src={`https://docs.exampaper.vidh.ai/${attendenceResults[attendenceIndex]?.s3_image_path}`}
width={`${zoomValue}px`}
alt="Attendence-image"
/>
)}
{attendenceResults.length > 0 && type === 1 && (
<img
src={`https://docs.exampaper.vidh.ai/${attendenceResults[attendenceIndex]?.s3_path}`}
width={`${zoomValue}px`}
alt="Attendence-image"
/>
)}
</Box>
</Box>
</Box>
)}
{attendenceResults?.length == 0 && (
<Box className="my-3">Attendence Record Not Found !!</Box>
)}
{isLoading && <LoadingContainer />}
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
</AntdesignLayout>
);
};
export default PendingAttendenceCorrection;

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect, useRef } from "react";
import { import {
DesktopOutlined, DesktopOutlined,
FileOutlined, FileOutlined,
@ -28,7 +28,7 @@ import {
updatePlaygroundTotalPages, updatePlaygroundTotalPages,
updateSystemNo, updateSystemNo,
} from "../redux/actions/actions"; } from "../redux/actions/actions";
import { Select } from "antd";
import CustomQueryExecutorCard from "./CustomQueryExecutorCard"; import CustomQueryExecutorCard from "./CustomQueryExecutorCard";
import SimpleDialog from "./SimpleDialog"; import SimpleDialog from "./SimpleDialog";
@ -44,19 +44,20 @@ import { updatePlaygroundQuery } from "../redux/actions/actions";
import { useSelector, useDispatch } from "react-redux"; import { useSelector, useDispatch } from "react-redux";
import PlayGrounds from "./PlayGrounds"; import PlayGrounds from "./PlayGrounds";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import Login from "./Login";
const { Header, Content, Footer, Sider } = Layout; const { Header, Content, Footer, Sider } = Layout;
const PlayGround = () => { const PlayGround = () => {
const { type } = useParams(); const { type, year } = useParams();
console.log("year in playground ====== ",year)
console.log("Backend URL:", import.meta.env.VITE_REACT_APP_BACKEND_URL); console.log("Backend URL:", import.meta.env.VITE_REACT_APP_BACKEND_URL);
console.log("Type ============= ", type); console.log("Type ============= ", type);
const [tableName, setTableName] = useState(null); const [tableName, setTableName] = useState(null);
const tableType = { const tableType = {
PartA: "ocr_scanned_part_a_v1", PartA: year == "april2024" ? "ocr_scanned_part_a_v1" : year == "november2024" ? "ocr_scanned_part_a_v2" : '',
PartC: "ocr_scanned_part_c_v1", PartC: year == "april2024" ? "ocr_scanned_part_c_v1" : year == "november2024" ? "ocr_scanned_part_c_v2" : '',
Attendence: "attendence_scanned_data", Attendence: year == "april2024" ? "attendence_scanned_data" : year == "november2024" ? "attendence_scanned_data_oct" : '',
}; };
useEffect(() => { useEffect(() => {
@ -68,16 +69,18 @@ const PlayGround = () => {
} }
}, [type, tableName]); }, [type, tableName]);
const [responseData, setResponseData] = useState([]); const [responseData, setResponseData] = useState(null);
const [totalData, setTotalData] = useState([]); const [totalData, setTotalData] = useState([]);
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(0); const [totalPages, setTotalPages] = useState(0);
const [imageColumn, setImageColumn] = useState(null); const [imageColumn, setImageColumn] = useState(null);
const [dataFetched, setDataFetched] = useState(false);
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [paginationPages, setPaginationPages] = useState(null); const [paginationPages, setPaginationPages] = useState(null);
const [limit, setLimit] = useState(""); const [limit, setLimit] = useState("100");
const recordsPerPage = 50; const recordsPerPage = 50;
const resultsContainerRef = useRef();
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch(); const dispatch = useDispatch();
const reduxPlaygroundQuery = useSelector((state) => state?.playGroundQuery); const reduxPlaygroundQuery = useSelector((state) => state?.playGroundQuery);
@ -111,12 +114,15 @@ const PlayGround = () => {
}, [reduxPlaygroundTotalPages]); }, [reduxPlaygroundTotalPages]);
useEffect(() => { useEffect(() => {
console.log("1234 ---- useEffect") console.log("1234 ---- useEffect");
if (totalData.length == 0 && reduxPlaygroundResults) { if (totalData.length == 0 && reduxPlaygroundResults) {
console.log("Redux playground results if ..."); console.log("Redux playground results if ...");
console.log("reduxPlaygroundResults.type === type ",reduxPlaygroundResults.type === type) console.log(
"reduxPlaygroundResults.type === type ",
reduxPlaygroundResults.type === type
);
if (reduxPlaygroundResults.type === type) { if (reduxPlaygroundResults.type === type) {
console.log("Into if ...") console.log("Into if ...");
setTotalData(reduxPlaygroundResults?.data); setTotalData(reduxPlaygroundResults?.data);
setImageColumn("s3_path"); setImageColumn("s3_path");
} }
@ -131,6 +137,14 @@ const PlayGround = () => {
}, [reduxPlaygroundPageNo]); }, [reduxPlaygroundPageNo]);
const fetchQueryValue = async () => { const fetchQueryValue = async () => {
// console.log("results container ref ===== ", resultsContainerRef);
// if (resultsContainerRef) {
// console.log(
// "Results container ref current ===== ",
// resultsContainerRef.current
// );
// resultsContainerRef.current.innerHTML = "";
// }
if (query.includes("limit")) { if (query.includes("limit")) {
alert("Please specify the limit in the input field."); alert("Please specify the limit in the input field.");
return; return;
@ -177,6 +191,7 @@ const PlayGround = () => {
const data = await response.json(); const data = await response.json();
setIsLoading(false); setIsLoading(false);
if (data.status === "success") { if (data.status === "success") {
setDataFetched(true);
setTotalData(data.results); setTotalData(data.results);
var tmp = {}; var tmp = {};
tmp.type = type; tmp.type = type;
@ -241,7 +256,14 @@ const PlayGround = () => {
}, [currentPage, totalPages]); }, [currentPage, totalPages]);
const getTableData = () => { const getTableData = () => {
if (responseData.length === 0) return null; if (totalData.length === 0) {
return (
<Box className="bg-white rounded p-3 my-3 w-100 h6">
No Results Found ...
</Box>
);
}
const keys = Object.keys(totalData[0]); const keys = Object.keys(totalData[0]);
return ( return (
@ -289,20 +311,32 @@ const PlayGround = () => {
)} )}
</div> </div>
<div className="my-2 overflow-auto"> <div className="my-2 overflow-auto">
{responseData.map((data) => ( {responseData ? (
<CustomQueryExecutorCard responseData.length > 0 ? (
type={type} responseData.map((data) => (
tableName={tableName} <CustomQueryExecutorCard
data={data} type={type}
s3_image_column={imageColumn} tableName={tableName}
query={query} data={data}
/> s3_image_column={imageColumn}
))} query={query}
year={year}
/>
))
) : (
<Box>No Results Found ...</Box>
)
) : null}
</div> </div>
</div> </div>
); );
}; };
const handleSelect = (e) => {
console.log("E ======= ", e);
setImageColumn(e);
};
return ( return (
<AntdesignLayout> <AntdesignLayout>
<div className="mx-3"> <div className="mx-3">
@ -317,11 +351,16 @@ const PlayGround = () => {
value={limit} value={limit}
setValue={setLimit} setValue={setLimit}
/> />
<TextInputField {totalData && totalData.length > 0 ? (
placeholder={"imageColumn"} <Select onChange={handleSelect} style={{ height: "50px" }}>
value={imageColumn} {Object.keys(totalData[0]).map((key) => (
setValue={setImageColumn} <Select.Option key={key} value={key}>
/> {key}
</Select.Option>
))}
</Select>
) : null}
<button <button
className="btn bg-primary text-light" className="btn bg-primary text-light"
id="submit-btn" id="submit-btn"
@ -343,15 +382,16 @@ const PlayGround = () => {
value={limit} value={limit}
onChange={(e) => setLimit(e.target.value)} onChange={(e) => setLimit(e.target.value)}
/> />
<TextField {totalData && totalData.length > 0 ? (
className="input rounded h6 bg-white" <Select onChange={handleSelect} style={{ height: "50px" }}>
type="text" {Object.keys(totalData[0]).map((key) => (
placeholder="Image column name" <Select.Option key={key} value={key}>
id="image-column-input" {key}
autoComplete="off" </Select.Option>
value={imageColumn} ))}
onChange={(e) => setImageColumn(e.target.value)} </Select>
/> ) : null}
<button <button
className="btn bg-primary text-light" className="btn bg-primary text-light"
id="submit-btn" id="submit-btn"
@ -364,9 +404,10 @@ const PlayGround = () => {
</div> </div>
<div <div
id="results-container" id="results-container"
ref={resultsContainerRef}
className="d-flex w-100 justify-content-center" className="d-flex w-100 justify-content-center"
> >
{getTableData()} {dataFetched && getTableData()}
</div> </div>
</div> </div>
{isLoading && <LoadingContainer />} {isLoading && <LoadingContainer />}

View File

@ -9,51 +9,140 @@ import { NavLink, Link } from "react-router-dom";
import TextInputField from "./TextInputField"; import TextInputField from "./TextInputField";
import { Height } from "@mui/icons-material"; import { Height } from "@mui/icons-material";
import HighlightOffIcon from "@mui/icons-material/HighlightOff"; import HighlightOffIcon from "@mui/icons-material/HighlightOff";
import LoadingContainer from "./LoadingContainer";
import { toast } from "react-toastify";
import { updatePlayGroundAttendence } from "./Utilities/AttendencePlaygroundUtilities";
import { updateAttendenceBlank } from "./Utilities/AttendencePlaygroundUtilities";
import Notification from "./Notification"; // Import the Notification component
import { ToastContainer } from "react-toastify";
const PlayGroundEditContainer = ({ const PlayGroundEditContainer = ({
year,
imageDomain,
data, data,
s3Path, s3Path,
imageName, imageName,
tableName, tableName,
setShowEditContainer, setShowEditContainer,
rotateAngle, rotateAngle,
type,
}) => { }) => {
const type = "PartC"; // const type = "PartC";
// const type = type;
const dialogText = "This is dialog text"; const dialogText = "This is dialog text";
const [marks, setMarks] = useState(null); const [marks, setMarks] = useState(null);
const [registerNumber, setRegisterNumber] = useState(null);
const [totalStudents, setTotalStudents] = useState(null);
const [totalPresent, setTotalPresent] = useState(null);
const [totalAbsent, setTotalAbsent] = useState(null);
const [barcode, setBarcode] = useState(null); const [barcode, setBarcode] = useState(null);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [qrcode, setQrcode] = useState(null); const [qrcode, setQrcode] = useState(null);
const [subjectCode, setSubjectCode] = useState(null); const [subjectCode, setSubjectCode] = useState(null);
const [marksR1, setMarksR1] = useState(null);
const [marksR2, setMarksR2] = useState(null);
const [open, setOpen] = useState(true); // Set open state to true by default const [open, setOpen] = useState(true); // Set open state to true by default
const [serialNo, setSerialNo] = useState(null);
const [notification, setNotification] = useState(null); // Notification state
const showNotification = (message, type) => {
console.log("setting notification ===== ", message);
const notificationData = { message, type };
console.log("notification data ==== ", notificationData);
setNotification(notificationData);
};
const handleClose = () => { const handleClose = () => {
setOpen(false); setOpen(false);
}; };
console.log("image_name ======================= ", imageName);
console.log("data === i ==== ", data);
useEffect(() => { useEffect(() => {
if (data) { const fetchImageData = async () => {
setQrcode(data?.qrcode); setIsLoading(true);
setBarcode(data?.barcode); try {
setMarks(data?.marks); if (data) {
setSubjectCode(data?.subject_code) const payload = {
} type,
imageName,
tableName,
year
};
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchTableImageNameData`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
setIsLoading(false);
console.log("response data {{{{ ", responseData);
if (responseData.status === "success") {
const imageData = responseData?.results;
if (imageData && imageData?.length > 0) {
const imageDataEle = imageData[0];
setQrcode(imageDataEle?.qrcode);
setBarcode(imageDataEle?.barcode);
setMarks(imageDataEle?.marks);
setMarksR1(imageDataEle?.marks_R1);
setMarksR2(imageDataEle?.marks_R2);
setSubjectCode(imageDataEle?.subject_code);
setRegisterNumber(imageDataEle?.register_number);
setTotalAbsent(imageDataEle?.total_absent);
setTotalPresent(imageDataEle?.total_present);
setTotalStudents(imageDataEle?.total_students);
setSerialNo(imageDataEle?.manually_corrected_serial_no)
}
}
}
} catch (error) {
throw new Error(error);
setIsLoading(false);
}
};
fetchImageData();
console.log("the currect editor type: ", type);
}, [data]); }, [data]);
const updateRecord = async () => { // useEffect(() => {
if (!marks) { // if (data) {
return; // setQrcode(data?.qrcode);
} // setBarcode(data?.barcode);
// setMarks(data?.marks);
// setMarksR1(data?.marks_R1);
// setMarksR2(data?.marks_R2);
// setSubjectCode(data?.subject_code);
// setRegisterNumber(data?.register_number);
// setTotalAbsent(data?.total_absent);
// setTotalPresent(data?.total_present);
// setTotalStudents(data?.total_students);
// }
// console.log("the currect editor type: ", type);
// }, [data]);
const updateRecordPartC = async () => {
setIsLoading(true); setIsLoading(true);
try { try {
const payload = { const payload = {
qrcode, qrcode,
barcode, barcode,
table:tableName, table: tableName,
s3Path, s3Path,
subjectCode, subjectCode,
registerNumber,
marks, marks,
marksR1,
marksR2,
imageName, imageName,
rotateAngle, rotateAngle,
year
}; };
const response = await fetch( const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartCdata`, `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartCdata`,
@ -69,47 +158,222 @@ const PlayGroundEditContainer = ({
setIsLoading(false); setIsLoading(false);
console.log("response data ========= ", responseData); console.log("response data ========= ", responseData);
if (responseData?.status === "success") { if (responseData?.status === "success") {
toast.success("Record Updated Successfully ..."); showNotification("Record updated successfully !!", "success");
setShowEditContainer(false);
const queryContainerEle = document.getElementById(imageName);
console.log("querycontainerEle ===== ", queryContainerEle);
if (queryContainerEle) {
queryContainerEle.classList.add("grey-background");
// toast.success("Record Updated Successfully !!");
// showNotification("Record Updated Successfully ...", "success");
}
} }
} catch (error) { } catch (error) {
setIsLoading(false); setIsLoading(false);
showNotification("Something Went Wrong !!", "error");
throw new Error(error); throw new Error(error);
} }
}; };
const updateRecordPartA = async () => {
setNotification({});
console.log(registerNumber);
console.log(subjectCode);
console.log(barcode, qrcode);
console.log("image_name = ", imageName);
console.log(!registerNumber && !subjectCode && (!barcode || !qrcode));
if (!registerNumber && !subjectCode && (!barcode || !qrcode)) {
return;
}
setIsLoading(true);
try {
const payload = {
qrcode,
barcode,
table: tableName,
s3Path,
subjectCode,
registerNumber,
imageName,
rotateAngle,
serialNo,
year
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartAdata`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
setIsLoading(false);
console.log("response data 122 ========= ", responseData);
if (responseData?.status === "success") {
showNotification("Record updated successfully !!", "success");
setShowEditContainer(false);
const queryContainerEle = document.getElementById(imageName);
console.log("querycontainerEle ===== ", queryContainerEle);
if (queryContainerEle) {
queryContainerEle.classList.add("grey-background");
}
setTimeout(() => {
showNotification("Record Updated Successfully !!", "success");
}, 500);
}
} catch (error) {
setIsLoading(false);
//toast.error("Something Went Wrong ...");
throw new Error(error);
}
};
const imageStyle = {
transform: `rotate(${rotateAngle})deg !important`,
};
console.log("Image style ====== ", imageStyle);
return ( return (
<Dialog open={open} onClose={handleClose} maxWidth="lg" style={{zIndex:100}} fullWidth> <Dialog
open={open}
sx={{ zIndex: "fab" }}
onClose={handleClose}
maxWidth="xl"
style={{ zIndex: 100 }}
fullWidth
>
<ToastContainer />
<DialogContent> <DialogContent>
<Box className="d-flex justify-content-between align-items-start gap-4"> <Box className="d-flex justify-content-between align-items-center gap-4">
<Box className="d-flex flex-column"> <Box className="d-flex flex-column" style={imageStyle}>
<img <img
src={`https://docs.exampaper.vidh.ai/${s3Path}`} src={`${imageDomain}/${s3Path}`}
height={"100%"} height={"100%"}
width={"100%"} width={"100%"}
/> />
</Box> </Box>
<Box className="py-3 d-flex flex-column justify-content-end w-100 gap-3"> <Box className="py-3 d-flex flex-column justify-content-end w-100 gap-3">
<TextInputField {type !== "Attendence" ? (
value={qrcode} <>
setValue={setQrcode} <TextInputField
placeholder={"QR code"} value={qrcode}
/> setValue={setQrcode}
<TextInputField placeholder={"QR code"}
value={barcode} />
setValue={setBarcode} <TextInputField
placeholder={"BarCode"} value={barcode}
/> setValue={setBarcode}
<TextInputField placeholder={"BarCode"}
value={marks} />
setValue={setMarks} <TextInputField
placeholder={"Marks"} value={subjectCode}
/> setValue={setSubjectCode}
<Button placeholder={"Subject code"}
className="bg-primary text-white p-3" />
onClick={() => updateRecord()} <TextInputField
> value={registerNumber}
Update setValue={setRegisterNumber}
</Button> placeholder={"Register Number"}
/>
</>
) : (
<>
<TextInputField
value={qrcode}
setValue={setQrcode}
placeholder={"QR code"}
/>
<TextInputField
value={subjectCode}
setValue={setSubjectCode}
placeholder={"Subject Code"}
/>
<TextInputField
value={totalStudents}
setValue={setTotalStudents}
placeholder={"Total Students"}
/>
<TextInputField
value={totalPresent}
setValue={setTotalPresent}
placeholder={"Total Present"}
/>
<TextInputField
value={totalAbsent}
setValue={setTotalAbsent}
placeholder={"Total Absent"}
/>
</>
)}
{type == "PartC" ? (
<>
<TextInputField
value={marks}
setValue={setMarks}
placeholder={"Marks"}
/>
<TextInputField
value={marksR1}
setValue={setMarksR1}
placeholder={"Marks R1"}
/>
<TextInputField
value={marksR2}
setValue={setMarksR2}
placeholder={"Marks R2"}
/>
</>
) : type == "PartA" ? (
<>
<TextInputField
value={registerNumber}
setValue={setRegisterNumber}
placeholder={"Register no"}
/>
<TextInputField
value={serialNo}
setValue={setSerialNo}
placeholder={"Serial No"}
/>
</>
) : null}
{type == "PartC" ? (
<Button
className="bg-primary text-white p-3"
onClick={() => updateRecordPartC()}
>
Update
</Button>
) : type == "PartA" ? (
<Button
className="bg-primary text-white p-3"
onClick={() => updateRecordPartA()}
>
Update
</Button>
) : type == "Attendence" ? (
<Button
className="bg-primary text-white p-3"
onClick={() =>
updatePlayGroundAttendence(
setIsLoading,
qrcode,
subjectCode,
totalStudents,
totalPresent,
totalAbsent,
data,
setShowEditContainer
)
}
>
Update
</Button>
) : null}
<Button <Button
className="bg-primary text-white p-3" className="bg-primary text-white p-3"
onClick={() => setShowEditContainer(false)} onClick={() => setShowEditContainer(false)}
@ -119,6 +383,14 @@ const PlayGroundEditContainer = ({
</Box> </Box>
</Box> </Box>
</DialogContent> </DialogContent>
{isLoading && <LoadingContainer />}
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
</Dialog> </Dialog>
); );
}; };

View File

@ -1,21 +1,27 @@
import React from "react"; import React from "react";
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import HomepageCard from "./HomepageCard"; import HomepageCard from "./HomepageCard";
import { useParams } from "react-router-dom";
const PlayGrounds = () => { const PlayGrounds = () => {
const { year } = useParams()
const cards = [ const cards = [
// { // {
// title: "PART - A", // title: "PART - A",
// url: "/Playground/PartA", // url: `/sections/${year}/Playground/PartA`,
// }, // },
{ {
title: "PART - C", title: "Part - A",
url: "/Playground/PartC", url: `/sections/${year}/Playground/updated/PartA`,
}, },
// { {
// title: "ATTENDENCE", title: "PART - C",
// url: "/Playground/Attendence", url: `/sections/${year}/Playground/PartC`,
// }, },
{
title: "ATTENDENCE",
url: `/sections/${year}/Playground/Attendence`,
}
]; ];
return ( return (
<> <>

View File

@ -0,0 +1,414 @@
import React, { useState, useEffect, useRef } from "react";
import {
DesktopOutlined,
FileOutlined,
PieChartOutlined,
TeamOutlined,
UserOutlined,
} from "@ant-design/icons";
import { Breadcrumb, Layout, Menu, Typography, theme } from "antd";
import { ToastContainer, toast } from "react-toastify";
import { Box, Button } from "@mui/material";
import TextField from "@mui/material/TextField";
import EditButton from "./EditButton";
import { width } from "@mui/system";
import "react-toastify/dist/ReactToastify.css";
import { useSearchParams } from "react-router-dom";
import LoadingContainer from "./LoadingContainer";
import HomeIcon from "@mui/icons-material/Home";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import { useNavigate } from "react-router-dom";
import QueryStatsIcon from "@mui/icons-material/QueryStats";
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
import RotateRightIcon from "@mui/icons-material/RotateRight";
import {
updatePartAanomolyData,
updatePlaygroundCurrentPage,
updatePlaygroundResults,
updatePlaygroundTotalPages,
updateSystemNo,
} from "../redux/actions/actions";
import { Select } from "antd";
import CustomQueryExecutorCard from "./CustomQueryExecutorCard";
import SimpleDialog from "./SimpleDialog";
import SystemNumberDialog from "./SystemNumberDialog";
import ValidationContainer from "./ValidationContainer";
import QueryExecutorCard from "./QueryExecutorCard";
import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
import QueryExecutortextArea from "./QueryExecutortextArea";
import AntdesignLayout from "./AntdesignLayout";
import TextInputField from "./TextInputField";
import { render } from "react-dom";
import { updatePlaygroundQuery } from "../redux/actions/actions";
import { useSelector, useDispatch } from "react-redux";
import PlayGrounds from "./PlayGrounds";
import { useParams } from "react-router-dom";
import UpdatedPlaygroundUpdater from "./UpdatedPlaygroundUpdater";
const { Header, Content, Footer, Sider } = Layout;
const PlayGroundUpdated = () => {
const { type, year } = useParams();
console.log("Backend URL:", import.meta.env.VITE_REACT_APP_BACKEND_URL);
console.log("Type ============= ", type);
const [tableName, setTableName] = useState(null);
const tableType = {
PartA: year == "april2024" ? "ocr_scanned_part_a_v1" : year == "november2024" ? "ocr_scanned_part_a_v2" : '',
PartC: year == "april2024" ? "ocr_scanned_part_c_v1" : year == "november2024" ? "ocr_scanned_part_c_v2" : '',
Attendence: year == "april2024" ? "attendence_scanned_data" : year == "november2024" ? "attendence_scanned_data_oct" : '',
};
useEffect(() => {
console.log("use effect type 123==== ", type);
console.log("use effect table name ===== ", tableName);
console.log("table name ==== ", tableType[type]);
if (!tableName) {
setTableName(tableType[type]);
}
}, [type, tableName]);
const [cardData, setCardData] = useState({});
const [responseData, setResponseData] = useState(null);
const [totalData, setTotalData] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(0);
const [imageColumn, setImageColumn] = useState(null);
const [dataFetched, setDataFetched] = useState(false);
const [currentCardIndex, setCurrentCardIndex] = useState(0);
const [query, setQuery] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [paginationPages, setPaginationPages] = useState(null);
const [limit, setLimit] = useState("");
const recordsPerPage = 50;
const resultsContainerRef = useRef();
const navigate = useNavigate();
const dispatch = useDispatch();
const reduxPlaygroundQuery = useSelector((state) => state?.playGroundQuery);
const reduxPlaygroundPageNo = useSelector(
(state) => state?.playGroundCurrentPage
);
const reduxPlaygroundTotalPages = useSelector(
(state) => state?.playGroundtotalPages
);
const reduxPlaygroundResults = useSelector(
(state) => state?.playGroundResults
);
console.log("Redux playground query : ", reduxPlaygroundQuery);
console.log("Redux playground page no : ", reduxPlaygroundPageNo);
console.log("Redux playground total pages : ", reduxPlaygroundTotalPages);
console.log("Redux playground resutls : ", reduxPlaygroundResults);
const {
token: { colorBgContainer, borderRadiusLG },
} = theme.useToken();
useEffect(() => {
if (reduxPlaygroundQuery && !query) {
setQuery(reduxPlaygroundQuery);
}
}, [reduxPlaygroundQuery]);
useEffect(() => {
if (reduxPlaygroundPageNo != 0 && totalPages == 0) {
setTotalPages(reduxPlaygroundTotalPages);
}
}, [reduxPlaygroundTotalPages]);
useEffect(() => {
console.log("1234 ---- useEffect");
if (totalData?.length == 0 && reduxPlaygroundResults) {
console.log("Redux playground results if ...");
console.log(
"reduxPlaygroundResults.type === type ",
reduxPlaygroundResults.type === type
);
if (reduxPlaygroundResults.type === type) {
console.log("Into if ...");
setTotalData(reduxPlaygroundResults?.data);
setImageColumn("s3_path");
}
}
}, [reduxPlaygroundResults]);
useEffect(() => {
if (currentPage == 0 && reduxPlaygroundPageNo !== 0) {
console.log("Updating in use effect ============================= >");
setCurrentPage(reduxPlaygroundPageNo);
}
}, [reduxPlaygroundPageNo]);
const fetchQueryValue = async () => {
// console.log("results container ref ===== ", resultsContainerRef);
// if (resultsContainerRef) {
// console.log(
// "Results container ref current ===== ",
// resultsContainerRef.current
// );
// resultsContainerRef.current.innerHTML = "";
// }
if (query.includes("limit")) {
alert("Please specify the limit in the input field.");
return;
}
if (query.includes(";")) {
alert("Please remove the special character from the query ';'");
return;
}
if (!limit) {
alert("Limit cannot be empty !!");
return;
}
if (
!query.includes("image_name") &&
!query.includes("*") &&
query.includes("ocr_scanned_part_c_v1")
) {
alert(
"Selecting primary Key (image_name) or Selecting all (*) is mandatory"
);
return;
}
if (!query.includes(tableName)) {
alert(`This playground is only for : ${tableName}`);
return;
}
setIsLoading(true);
const payload = {
query: query,
limit: limit,
};
try {
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchQueryValue`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const data = await response.json();
setIsLoading(false);
if (data.status === "success") {
setDataFetched(true);
setTotalData(data.results);
var tmp = {};
tmp.type = type;
tmp.data = data?.results;
// dispatch(updatePlaygroundResults(data?.results));
dispatch(updatePlaygroundResults(tmp));
const totalPageCount = Math.ceil(data?.results.length / recordsPerPage);
setTotalPages(totalPageCount);
dispatch(updatePlaygroundTotalPages(totalPages));
setCurrentPage(1);
setResponseData(data.results.slice(0, recordsPerPage));
const totalResults = data?.results;
if (totalResults) {
if (totalResults?.length > 0) {
setCardData(totalResults[0]);
}
}
} else {
toast.error(data.message);
}
} catch (error) {
console.error("Error:", error);
}
};
useEffect(() => {
dispatch(updatePlaygroundQuery(query));
}, [query]);
useEffect(() => {
if (totalData) {
if (totalData.length > 0) {
setResponseData([]);
console.log(" ===========================>>>>>>>>>>>>>>>>>>>>>>>> ");
setIsLoading(true);
setTimeout(() => {
const startIndex = (currentPage - 1) * recordsPerPage;
const endIndex = startIndex + recordsPerPage;
setResponseData(totalData.slice(startIndex, endIndex));
setIsLoading(false);
}, 1000);
}
dispatch(updatePlaygroundCurrentPage(currentPage));
renderPagination();
}
}, [currentPage, totalData]);
const renderPagination = () => {
const pages = [];
for (let i = 1; i <= totalPages; i++) {
pages.push(
<span key={i}>
{i > 1 && " | "}
<a
href="#!"
onClick={() => setCurrentPage(i)}
className={i === currentPage ? "active" : ""}
>
{i}
</a>
</span>
);
}
setPaginationPages(pages);
};
useEffect(() => {
renderPagination();
dispatch(updatePlaygroundTotalPages(totalPages));
}, [currentPage, totalPages]);
useEffect(() => {
console.log("current card index use effect ... ", currentCardIndex);
if (totalData) {
if (totalData.length > 0 && currentCardIndex < totalData.length) {
setCardData(totalData[currentCardIndex]);
// setIsLoading(true);
// setTimeout(() => {
// setCardData(totalData[currentCardIndex]);
// setIsLoading(false);
// }, 1000);
}
}
}, [currentCardIndex]);
useEffect(() => {
if (totalData?.length > 0) {
console.log("Result container ref ===== ", resultsContainerRef.current);
resultsContainerRef.current.scrollIntoView();
resultsContainerRef.current.scroll;
// Adding a slight delay to ensure the element is rendered
// setTimeout(() => {
// resultsContainerRef.current.scrollIntoView({ behavior: "smooth" });
// }, 100);
}
}, [totalData]);
const getTableData = () => {
if (totalData.length === 0) {
return (
<Box className="bg-white rounded p-3 my-3 w-100 h6">
No Results Found ...
</Box>
);
}
const keys = Object.keys(totalData[0]);
return (
<div className="w-100">
<div className="my-2 overflow-auto">
{responseData ? (
responseData.length > 0 ? (
<UpdatedPlaygroundUpdater
type={type}
tableName={tableName}
oldData={cardData}
currentCardIndex={currentCardIndex}
setCurrentCardIndex={setCurrentCardIndex}
setCardData={setCardData}
totalData={totalData}
s3_image_column={imageColumn}
query={query}
/>
) : (
<Box>No Results Found ...</Box>
)
) : null}
</div>
</div>
);
};
const handleSelect = (e) => {
console.log("E ======= ", e);
setImageColumn(e);
};
return (
<AntdesignLayout>
<div className="mx-3">
<div className="my-3 d-flex flex-md-row flex-column">
<div className="w-100 w-md-75">
<QueryExecutortextArea query={query} setQuery={setQuery} />
</div>
<div className="d-none d-md-block w-25">
<div className="w-100 d-flex flex-column gap-2 mx-2">
<TextInputField
placeholder={"limit"}
value={limit}
setValue={setLimit}
/>
{totalData && totalData.length > 0 ? (
<Select onChange={handleSelect} style={{ height: "50px" }}>
{Object.keys(totalData[0]).map((key) => (
<Select.Option key={key} value={key}>
{key}
</Select.Option>
))}
</Select>
) : null}
<button
className="btn bg-primary text-light"
id="submit-btn"
onClick={fetchQueryValue}
>
Submit
</button>
</div>
</div>
<div className="d-block d-md-none w-100">
<div className="w-100 d-flex flex-column gap-2">
<TextField
className="rounded h6 bg-white"
type="text"
placeholder="Limit"
id="limit-input"
autoComplete="off"
value={limit}
onChange={(e) => setLimit(e.target.value)}
/>
{totalData && totalData.length > 0 ? (
<Select onChange={handleSelect} style={{ height: "50px" }}>
{Object.keys(totalData[0]).map((key) => (
<Select.Option key={key} value={key}>
{key}
</Select.Option>
))}
</Select>
) : null}
<button
className="btn bg-primary text-light"
id="submit-btn"
onClick={fetchQueryValue}
>
Submit
</button>
</div>
</div>
</div>
<div
id="results-container"
ref={resultsContainerRef}
className="d-flex w-100 justify-content-center"
>
{dataFetched && getTableData()}
</div>
</div>
{isLoading && <LoadingContainer />}
</AntdesignLayout>
);
};
export default PlayGroundUpdated;

View File

@ -15,9 +15,12 @@ import RotateRightIcon from "@mui/icons-material/RotateRight";
import { updatePartCErrorData, updateSystemNo } from "../redux/actions/actions"; import { updatePartCErrorData, updateSystemNo } from "../redux/actions/actions";
import { updatePartCErrorList } from "../redux/actions/actions"; import { updatePartCErrorList } from "../redux/actions/actions";
import { DiscFullTwoTone } from "@mui/icons-material"; import { DiscFullTwoTone } from "@mui/icons-material";
import { useParams } from "react-router-dom";
const QrcodeCardEditor = () => { const QrcodeCardEditor = () => {
const {year} = useParams()
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
const table = year === "april2024" ? "ocr_scanned_part_c_v1" : year === "november2024" ? "ocr_scanned_part_c_v2" : "ocr_scanned_part_c_v1"
const [evQrcode, setEvQrcode] = useState(null); const [evQrcode, setEvQrcode] = useState(null);
const [imageName, setImageName] = useState(null); const [imageName, setImageName] = useState(null);
@ -28,7 +31,6 @@ const QrcodeCardEditor = () => {
const [rotationResults, setRotationResults] = useState([]); const [rotationResults, setRotationResults] = useState([]);
const [rotateAngle, setRotateAngle] = useState(0); const [rotateAngle, setRotateAngle] = useState(0);
const evErrorsList = useSelector((state) => state?.partCErrorList); const evErrorsList = useSelector((state) => state?.partCErrorList);
const table = searchParams.get("table");
const image_name = searchParams.get("image_name"); const image_name = searchParams.get("image_name");
const paramsError = searchParams.get("error"); const paramsError = searchParams.get("error");
const paramsErrorReason = searchParams.get("error_reason"); const paramsErrorReason = searchParams.get("error_reason");

View File

@ -0,0 +1,290 @@
import React, { useState, useEffect } from "react";
import { Box, Button } from "@mui/material";
import AntdesignLayout from "./AntdesignLayout";
import LoadingContainer from "./LoadingContainer";
import infinity_loader from "../../assets/Infinity_loader.gif";
import Notification from "./Notification"; // Import the Notification component
import { Height } from "@mui/icons-material";
import ZoomInIcon from "@mui/icons-material/ZoomIn";
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
const QrcodeFinder = () => {
const [registerNumber, setRegisterNumber] = useState(null);
const [subjectCode, setSubjectCode] = useState(null);
const [attendenceSerialNo, setAttendenceSerialNo] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [attendenceResults, setAttendenceResults] = useState(null);
const [zoomValue, setZoomValue] = useState(950);
const [absentStatus, setAbsentStatus] = useState(-1);
const [notification, setNotification] = useState(null); // Notification state
const [type, setType] = useState(null);
const [coverBarcode, setCoverBarcode] = useState(null);
const [pdfPath, setPdfPath] = useState(null);
const [coverInfo, setCoverInfo] = useState(null);
const [pdfData, setPdfData] = useState(null);
const showNotification = (message, type) => {
setNotification({ message, type });
};
const updateStudentStatus = async () => {
setIsLoading(true);
try {
const payload = {
attendenceResults,
absentStatus,
attendenceSerialNo,
register_number: registerNumber,
subject_code: subjectCode,
};
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/updateStudentAttendenceStatus`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("The response data ===== ", responseData);
if (responseData?.status === "success") {
fetchAttendenceData();
showNotification("Record updated successfully !!", "success");
}
setIsLoading(false);
} catch (error) {
setIsLoading(false);
console.error("Error updating student status:", error);
showNotification("Error updating student status", "error");
}
};
useEffect(() => {
console.log("Absent status changed ==== ", absentStatus);
if (Number(absentStatus) === 0 || Number(absentStatus) === 1) {
updateStudentStatus();
}
}, [absentStatus]);
const fetchAttendenceData = async () => {
setAbsentStatus(-1);
if (!attendenceSerialNo) {
if (!registerNumber || !subjectCode) {
showNotification(
"Registration Number && Subject Code is Mandatory !!",
"error"
);
return;
}
}
if (registerNumber && subjectCode) {
setType(1);
} else if (attendenceSerialNo) {
setType(2);
}
setIsLoading(true);
try {
const payload = {
registerNumber,
subjectCode,
attendenceSerialNo,
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchAttendenceData`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("response data ========= ", responseData);
setIsLoading(false);
if (responseData?.status === "success") {
setAttendenceResults(responseData?.results);
setType(responseData?.type);
}
} catch (error) {
setIsLoading(false);
console.error("Error fetching attendance data:", error);
showNotification("Error fetching attendance data", "error");
}
};
const fetchCoverCodeInfo = async () => {
if (!coverBarcode && !pdfPath) {
showNotification("CoverBarcode or Pdf path is mandatory !!", "error");
return;
}
setCoverInfo(null)
setPdfData(null)
setIsLoading(true);
try {
const payload = {
coverBarcode,
pdfPath,
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchCoverBarcode`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("response data ========= ", responseData);
setIsLoading(false);
if (responseData?.status === "success") {
setCoverInfo(responseData?.ev_results);
setPdfData(responseData?.part_c_results);
}
} catch (error) {
setIsLoading(false);
console.error("Error fetching attendance data:", error);
showNotification("Error fetching attendance data", "error");
}
};
return (
<AntdesignLayout>
<Box className="d-flex justify-content-center w-100 gap-3 align-items-center mx-auto" style={{maxWidth:"1600px"}}>
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
<strong>Cover Barcode</strong>
</label>
<input
type="text"
className="form-control p-3"
id="exampleFormControlInput1"
placeholder="Eg : MW9898"
onChange={(e) => setCoverBarcode(e.target.value)}
style={{ width: "600px" }}
/>
</div>
<div className="mb-3">
<label htmlFor="exampleFormControlInput1" className="form-label">
<strong>Pdf Path</strong>
</label>
<input
type="text"
style={{ width: "600px" }}
className="form-control p-3"
id="exampleFormControlInput1"
placeholder="Eg : /datadarive/scanned_files/05-07-2024/05-07-2024/scan1/20240705195510.pdf"
onChange={(e) => setPdfPath(e.target.value)}
/>
</div>
<button
type="button"
className="btn btn-primary btn-sm px-4 h-75"
onClick={fetchCoverCodeInfo}
>
Submit
</button>
</Box>
{coverInfo && coverInfo?.length === 0 && <Box>Cover Info Not Found</Box>}
<Box className="d-flex justify-content-center gap-5 p-3">
{coverInfo && coverInfo?.length > 0 && (
<Box className="text-left rounded">
<Box>
<strong>Cover Info :</strong>
</Box>
<img
src={`https://docs.exampaper.vidh.ai/${coverInfo[0]?.s3_path}`}
width={"700px"}
/>
</Box>
)}
<Box>
{pdfData && pdfData.length > 0 && (
<Box className="text-left">
<strong>PDF Info - </strong> {pdfData.length} Pages
</Box>
)}
<Box className="overflow-auto my-2 shadow" style={{ height: "70vh" }}>
{pdfData &&
pdfData.length > 0 &&
pdfData.map((data, index) => (
<Box className="shadow mb-5 d-flex flex-column justify-content-between bg-white rounded p-3 align-items-center">
<Box className="text-left">
<strong>{index + 1 + "/" + pdfData.length}</strong>
</Box>
<Box>
{" "}
<img
src={`https://docs.exampaper.vidh.ai/${data?.s3_path}`}
width={"700px"}
/>
</Box>
<Box className="p-5 w-100">
<table className="w-100 text-center">
<tr className="text-center">
<th>Register Number</th>
<td className="text-center">
{data?.register_number || "NULL"}
</td>
</tr>
<tr>
<th>Subject Code</th>
<td className="text-center">
{data?.subject_code || "NULL"}
</td>
</tr>
<tr>
<th>Marks</th>
<td className="text-center">{data?.marks || "NULL"}</td>
</tr>
<tr>
<th>Marks R1</th>
<td className="text-center">
{data?.marks_R1 || "NULL"}
</td>
</tr>
<tr>
<th>Marks R2</th>
<td className="text-center">
{data?.marks_R2 || "NULL"}
</td>
</tr>
<tr>
<th>Page Number</th>
<td className="text-center">
{data?.page_number || "NULL"}
</td>
</tr>
</table>
</Box>
</Box>
))}
</Box>
</Box>
</Box>
{isLoading && <LoadingContainer/>}
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
</AntdesignLayout>
);
};
export default QrcodeFinder;

View File

@ -15,8 +15,10 @@ import RotateRightIcon from "@mui/icons-material/RotateRight";
import { updatePartCErrorData, updateSystemNo } from "../redux/actions/actions"; import { updatePartCErrorData, updateSystemNo } from "../redux/actions/actions";
import { updatePartCErrorList } from "../redux/actions/actions"; import { updatePartCErrorList } from "../redux/actions/actions";
import { DiscFullTwoTone } from "@mui/icons-material"; import { DiscFullTwoTone } from "@mui/icons-material";
import { useParams } from "react-router-dom";
const QueryCardEditor = () => { const QueryCardEditor = () => {
const {year} = useParams()
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
const [barcode, setBarcode] = useState(); const [barcode, setBarcode] = useState();
const [qrcode, setQrcode] = useState(); const [qrcode, setQrcode] = useState();
@ -30,7 +32,8 @@ const QueryCardEditor = () => {
const [rotationResults, setRotationResults] = useState([]); const [rotationResults, setRotationResults] = useState([]);
const [rotateAngle, setRotateAngle] = useState(0); const [rotateAngle, setRotateAngle] = useState(0);
const evErrorsList = useSelector((state) => state?.partCErrorList); const evErrorsList = useSelector((state) => state?.partCErrorList);
const table = searchParams.get("table"); const table = year === "april2024" ? "ocr_scanned_part_c_v1" : year === "november2024" ? "ocr_scanned_part_c_v2" : "ocr_scanned_part_c_v1"
const imageDomain = (year === "april2024" ? "https://docs.exampaper.vidh.ai" : (year === "november2024" ? 'https://images.exampaper.usln.in' : 'https://docs.exampaper.vidh.ai'))
const image_name = searchParams.get("image_name"); const image_name = searchParams.get("image_name");
const paramsError = searchParams.get("error"); const paramsError = searchParams.get("error");
const paramsErrorReason = searchParams.get("error_reason"); const paramsErrorReason = searchParams.get("error_reason");
@ -107,6 +110,7 @@ const QueryCardEditor = () => {
} }
}; };
fetchData(); fetchData();
marksInputRef.current.focus()
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -134,6 +138,7 @@ const QueryCardEditor = () => {
marks, marks,
imageName, imageName,
rotateAngle, rotateAngle,
year
}; };
const response = await fetch( const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartCdata`, `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartCdata`,
@ -171,7 +176,7 @@ const QueryCardEditor = () => {
if (newRecords.length > 0) { if (newRecords.length > 0) {
console.log("Has to navigte 12 ....."); console.log("Has to navigte 12 .....");
localStorage.setItem("marks_manual_data", JSON.stringify(newRecords)); localStorage.setItem("marks_manual_data", JSON.stringify(newRecords));
const newUrl = `/sqlPlayground/edit?image_name=${newRecords[currentIndex]?.image_name}&table=ocr_scanned_part_c_v1&error=${paramsError}&error_reason=${paramsErrorReason}&degreeType=${paramsDegreeType}&sysNo=${paramsSysNo}`; const newUrl = `/sections/${year}/sqlPlayground/edit?image_name=${newRecords[currentIndex]?.image_name}&error=${paramsError}&error_reason=${paramsErrorReason}&degreeType=${paramsDegreeType}&sysNo=${paramsSysNo}`;
console.log("new url ==== ", newUrl); console.log("new url ==== ", newUrl);
window.location.href = newUrl; window.location.href = newUrl;
} else { } else {
@ -242,7 +247,7 @@ const QueryCardEditor = () => {
console.log("new index ===== ", newIndex); console.log("new index ===== ", newIndex);
if (newRecords.length > 0) { if (newRecords.length > 0) {
console.log("Has to navigte 12 ....."); console.log("Has to navigte 12 .....");
const newUrl = `/sqlPlayground/edit?image_name=${evErrorsData[newIndex]?.image_name}&table=ocr_scanned_part_c_v1&error=${paramsError}&error_reason=${paramsErrorReason}&degreeType=${paramsDegreeType}&sysNo=${paramsSysNo}`; const newUrl = `/sections/${year}/sqlPlayground/edit?image_name=${evErrorsData[newIndex]?.image_name}&table=ocr_scanned_part_c_v1&error=${paramsError}&error_reason=${paramsErrorReason}&degreeType=${paramsDegreeType}&sysNo=${paramsSysNo}`;
console.log("new url ==== ", newUrl); console.log("new url ==== ", newUrl);
window.location.href = newUrl; window.location.href = newUrl;
} }
@ -273,9 +278,18 @@ const QueryCardEditor = () => {
return ( return (
<AntdesignLayout> <AntdesignLayout>
<Box className="d-flex justify-content-between align-items-center"> <Box className="d-flex justify-content-between align-items-start">
<Box className="w-75">
<Box className="px-5" id="img-container">
<img
src={`${imageDomain}/${recordData?.s3_path}`}
width="100%"
height="auto"
/>
</Box>
</Box>
<Box className="d-flex flex-column gap-3 w-25"> <Box className="d-flex flex-column gap-3 w-25">
{imageName && <h5 className="text-left">ID : {imageName}</h5>} {/* {imageName && <h5 className="text-left">ID : {imageName}</h5>}
{paramsError && ( {paramsError && (
<h5 className="text-left">Error Code : {paramsError}</h5> <h5 className="text-left">Error Code : {paramsError}</h5>
)} )}
@ -285,7 +299,8 @@ const QueryCardEditor = () => {
) : ( ) : (
<h5 className="text-left">Degree Type : PG</h5> <h5 className="text-left">Degree Type : PG</h5>
) )
) : null} ) : null} */}
<h5 style={{textAlign:"left",marginTop:'10px',marginBottom:'0px'}}><strong>COVER CODE : </strong>{recordData?.new_cover_barcode}</h5>
<TextInputField <TextInputField
placeholder="Barcode" placeholder="Barcode"
value={barcode} value={barcode}
@ -345,15 +360,6 @@ const QueryCardEditor = () => {
</Button> </Button>
</Box> </Box>
</Box> </Box>
<Box className="w-75">
<Box className="px-5" id="img-container">
<img
src={`https://docs.exampaper.vidh.ai/${recordData?.s3_path}`}
width="100%"
height="auto"
/>
</Box>
</Box>
</Box> </Box>
{isLoading && <LoadingContainer />} {isLoading && <LoadingContainer />}
{showDialog && ( {showDialog && (

View File

@ -6,7 +6,7 @@ import {
TeamOutlined, TeamOutlined,
UserOutlined, UserOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { Breadcrumb, Layout, Menu, Typography, theme } from "antd"; import { Breadcrumb, Layout, Menu, Select, Typography, theme } from "antd";
import { ToastContainer, toast } from "react-toastify"; import { ToastContainer, toast } from "react-toastify";
import { Box, Button } from "@mui/material"; import { Box, Button } from "@mui/material";
import TextField from "@mui/material/TextField"; import TextField from "@mui/material/TextField";
@ -50,7 +50,8 @@ const QueryExecutor = () => {
const [imageColumn, setImageColumn] = useState(null); const [imageColumn, setImageColumn] = useState(null);
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [paginationPages,setPaginationPages] = useState(null) const [paginationPages, setPaginationPages] = useState(null);
const [dataFetched,setDataFetched] = useState(false)
const [limit, setLimit] = useState(""); const [limit, setLimit] = useState("");
const recordsPerPage = 50; const recordsPerPage = 50;
const navigate = useNavigate(); const navigate = useNavigate();
@ -88,18 +89,19 @@ const QueryExecutor = () => {
useEffect(() => { useEffect(() => {
if (totalData.length == 0 && reduxPlaygroundResults.length > 0) { if (totalData.length == 0 && reduxPlaygroundResults.length > 0) {
setTotalData(reduxPlaygroundResults); setTotalData(reduxPlaygroundResults);
setImageColumn("s3_path") setImageColumn("s3_path");
} }
}, [reduxPlaygroundResults]); }, [reduxPlaygroundResults]);
useEffect(() => { useEffect(() => {
if (currentPage == 0 && reduxPlaygroundPageNo !== 0) { if (currentPage == 0 && reduxPlaygroundPageNo !== 0) {
console.log("Updating in use effect ============================= >") console.log("Updating in use effect ============================= >");
setCurrentPage(reduxPlaygroundPageNo); setCurrentPage(reduxPlaygroundPageNo);
} }
}, [reduxPlaygroundPageNo]); }, [reduxPlaygroundPageNo]);
const fetchQueryValue = async () => { const fetchQueryValue = async () => {
setDataFetched(false)
if (query.includes("limit")) { if (query.includes("limit")) {
alert("Please specify the limit in the input field."); alert("Please specify the limit in the input field.");
return; return;
@ -114,6 +116,7 @@ const QueryExecutor = () => {
} }
if ( if (
!query.includes("image_name") && !query.includes("image_name") &&
!query.includes("*") &&
query.includes("ocr_scanned_part_c_v1") query.includes("ocr_scanned_part_c_v1")
) { ) {
alert("Selecting primary Key (image_name) is mandatory"); alert("Selecting primary Key (image_name) is mandatory");
@ -139,30 +142,35 @@ const QueryExecutor = () => {
const data = await response.json(); const data = await response.json();
setIsLoading(false); setIsLoading(false);
if (data.status === "success") { if (data.status === "success") {
setDataFetched(true)
setTotalData(data.results); setTotalData(data.results);
dispatch(updatePlaygroundResults(data?.results)); dispatch(updatePlaygroundResults(data?.results));
const totalPageCount = Math.ceil(data?.results.length / recordsPerPage); const totalPageCount = Math.ceil(data?.results.length / recordsPerPage);
setTotalPages(totalPageCount); setTotalPages(totalPageCount);
dispatch(updatePlaygroundTotalPages(totalPages)) dispatch(updatePlaygroundTotalPages(totalPages));
setCurrentPage(1); setCurrentPage(1);
setResponseData(data.results.slice(0, recordsPerPage)); setResponseData(data.results.slice(0, recordsPerPage));
} else { } else {
// toast.error(data.message); toast.error(data.message);
} }
} catch (error) { } catch (error) {
console.error("Error:", error); console.error("Error:", error);
} }
}; };
useEffect(()=>{
console.log("datafetched ======= ",dataFetched)
},[dataFetched])
useEffect(() => { useEffect(() => {
dispatch(updatePlaygroundQuery(query)); dispatch(updatePlaygroundQuery(query));
}, [query]); }, [query]);
useEffect(() => { useEffect(() => {
if (totalData.length > 0) { if (totalData.length > 0) {
setResponseData([]) setResponseData([]);
console.log(" ===========================>>>>>>>>>>>>>>>>>>>>>>>> ") console.log(" ===========================>>>>>>>>>>>>>>>>>>>>>>>> ");
setIsLoading(true); setIsLoading(true);
setTimeout(() => { setTimeout(() => {
const startIndex = (currentPage - 1) * recordsPerPage; const startIndex = (currentPage - 1) * recordsPerPage;
@ -172,7 +180,7 @@ const QueryExecutor = () => {
}, 1000); }, 1000);
} }
dispatch(updatePlaygroundCurrentPage(currentPage)); dispatch(updatePlaygroundCurrentPage(currentPage));
renderPagination() renderPagination();
}, [currentPage, totalData]); }, [currentPage, totalData]);
const renderPagination = () => { const renderPagination = () => {
@ -191,7 +199,7 @@ const QueryExecutor = () => {
</span> </span>
); );
} }
setPaginationPages(pages) setPaginationPages(pages);
}; };
useEffect(() => { useEffect(() => {
@ -200,7 +208,15 @@ const QueryExecutor = () => {
}, [currentPage, totalPages]); }, [currentPage, totalPages]);
const getTableData = () => { const getTableData = () => {
if (responseData.length === 0) return null; console.log("total data in get table data ================ ",totalData)
if (totalData.length === 0){
console.log("Total data length ======= 0",totalData?.length)
return (
<Box className="bg-white rounded p-3 my-3 w-100 h6">No Results Found ...</Box>
)
}
const keys = Object.keys(totalData[0]); const keys = Object.keys(totalData[0]);
return ( return (
@ -248,18 +264,38 @@ const QueryExecutor = () => {
)} )}
</div> </div>
<div className="my-2 overflow-auto"> <div className="my-2 overflow-auto">
{responseData.map((data) => ( {responseData ? (
<QueryExecutorCard responseData.length > 0 ? (
data={data} responseData.map((data) => (
s3_image_column={imageColumn} <QueryExecutorCard
query={query} key={data.id} // Assuming 'data' has a unique 'id' property
/> data={data}
))} s3_image_column={imageColumn}
query={query}
/>
))
) : (
<Box>No Results Found ...</Box>
)
) : null}
</div> </div>
</div> </div>
); );
}; };
const handleSelect = (e) => {
console.log("E ======= ", e);
setImageColumn(e);
};
useEffect(() => {
console.log("Use effect ============ ", responseData);
}, [responseData]);
useEffect(() => {
console.log("Image column use effect .......... ", imageColumn);
}, [imageColumn]);
return ( return (
<AntdesignLayout> <AntdesignLayout>
<div className="mx-3"> <div className="mx-3">
@ -274,11 +310,22 @@ const QueryExecutor = () => {
value={limit} value={limit}
setValue={setLimit} setValue={setLimit}
/> />
<TextInputField {/* <TextInputField
placeholder={"imageColumn"} placeholder={"imageColumn"}
value={imageColumn} value={imageColumn}
setValue={setImageColumn} setValue={setImageColumn}
/> /> */}
{totalData && totalData.length > 0 ? (
<Select onChange={handleSelect} style={{ height: "50px" }}>
{Object.keys(totalData[0]).map((key) => (
<Select.Option key={key} value={key}>
{key}
</Select.Option>
))}
</Select>
) : null}
<button <button
className="btn bg-primary text-light" className="btn bg-primary text-light"
id="submit-btn" id="submit-btn"
@ -300,7 +347,7 @@ const QueryExecutor = () => {
value={limit} value={limit}
onChange={(e) => setLimit(e.target.value)} onChange={(e) => setLimit(e.target.value)}
/> />
<TextField {/* <TextField
className="input rounded h6 bg-white" className="input rounded h6 bg-white"
type="text" type="text"
placeholder="Image column name" placeholder="Image column name"
@ -308,7 +355,17 @@ const QueryExecutor = () => {
autoComplete="off" autoComplete="off"
value={imageColumn} value={imageColumn}
onChange={(e) => setImageColumn(e.target.value)} onChange={(e) => setImageColumn(e.target.value)}
/> /> */}
{totalData && totalData.length > 0 ? (
<Select onChange={handleSelect} style={{ height: "50px" }}>
{Object.keys(totalData[0]).map((key) => (
<Select.Option key={key} value={key}>
{key}
</Select.Option>
))}
</Select>
) : null}
<button <button
className="btn bg-primary text-light" className="btn bg-primary text-light"
id="submit-btn" id="submit-btn"
@ -323,7 +380,7 @@ const QueryExecutor = () => {
id="results-container" id="results-container"
className="d-flex w-100 justify-content-center" className="d-flex w-100 justify-content-center"
> >
{getTableData()} {dataFetched && getTableData()}
</div> </div>
</div> </div>
{isLoading && <LoadingContainer />} {isLoading && <LoadingContainer />}

View File

@ -6,15 +6,19 @@ import { useState, useEffect } from "react";
import { ToastContainer, toast } from "react-toastify"; import { ToastContainer, toast } from "react-toastify";
import LoadingContainer from "./LoadingContainer"; import LoadingContainer from "./LoadingContainer";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useParams } from "react-router-dom";
const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason, reduxSystemNo,degreeType }) => { const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason, reduxSystemNo,degreeType }) => {
const { year } = useParams()
const imageDomain = (year === "april2024" ? "https://docs.exampaper.vidh.ai" : (year === "november2024" ? 'https://images.exampaper.usln.in' : 'https://docs.exampaper.vidh.ai'))
// console.log("ERROR ============= ",error) // console.log("ERROR ============= ",error)
// console.log("ERROR REASON ============== ",error_reason) // console.log("ERROR REASON ============== ",error_reason)
// console.log("REDUX SYSTEM NO ================== ",reduxSystemNo) // console.log("REDUX SYSTEM NO ================== ",reduxSystemNo)
const navigate = useNavigate() const navigate = useNavigate()
const [dataValue, setDataValue] = useState({}); const [dataValue, setDataValue] = useState({});
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
// console.log("data in query executor Card : ", data); console.log("data in query executor Card : ", data);
const [keys, setKeys] = useState([]); const [keys, setKeys] = useState([]);
const [values, setValues] = useState([]); const [values, setValues] = useState([]);
// console.log("image column ====== ", s3_image_column); // console.log("image column ====== ", s3_image_column);
@ -175,7 +179,7 @@ const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason,
<> <>
<Button <Button
className="w-50 m-0 bg-primary text-white p-1 rounded" className="w-50 m-0 bg-primary text-white p-1 rounded"
onClick={() => navigate(`/sqlPlayground/edit?image_name=${data["image_name"]}&table=ocr_scanned_part_c_v1&error=${error}&error_reason=${error_reason}&sysNo=${reduxSystemNo}&degreeType=${degreeType}`)} onClick={() => navigate(`/sections/${year}/sqlPlayground/edit?image_name=${data["image_name"]}&error=${error}&error_reason=${error_reason}&sysNo=${reduxSystemNo}&degreeType=${degreeType}`)}
> >
Edit Edit
</Button> </Button>
@ -207,7 +211,7 @@ const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason,
)} )}
<Button className="bg-primary"> <Button className="bg-primary">
<a <a
href={`https://docs.exampaper.vidh.ai/${data[s3_image_column]}`} href={`${imageDomain}/${data[s3_image_column]}`}
> >
<DownloadIcon className="text-light text-white" /> <DownloadIcon className="text-light text-white" />
</a> </a>
@ -215,7 +219,7 @@ const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason,
</Box> </Box>
<Box className="border border-dark"> <Box className="border border-dark">
<img <img
src={`https://docs.exampaper.vidh.ai/${data[s3_image_column]}`} src={`${imageDomain}/${data[s3_image_column]}`}
width="800px" width="800px"
height="auto" height="auto"
alt="Image Alt" alt="Image Alt"

View File

@ -1,16 +1,26 @@
import { useState } from "react";
const QueryExecutortextArea = ({ query, setQuery }) => {
const [inputValue, setInputValue] = useState(query);
const handleChange = (e) => {
setInputValue(e.target.value);
// Debounce the state update
clearTimeout(window.debounceTimeout);
window.debounceTimeout = setTimeout(() => {
setQuery(e.target.value);
}, 500); // Update state after 500ms of no typing
};
const QueryExecutortextArea = ({query,setQuery}) => {
return ( return (
<> <textarea
<textarea className="w-100 p-3 h5 bg-white"
className="w-100 p-3 h5 bg-white" id="text-area-input"
id="text-area-input" placeholder="Enter your query ...."
placeholder="Enter your query ...." rows="7"
rows="7" value={inputValue}
value={query} onChange={handleChange}
onChange={(e) => setQuery(e.target.value)} ></textarea>
></textarea>
</>
); );
}; };

View File

@ -0,0 +1,215 @@
import { Box, Button } from "@mui/material";
import { useState, useEffect } from "react";
import { ToastContainer, toast } from "react-toastify";
import { UserOutlined } from "@ant-design/icons";
import { Avatar, Space } from "antd";
import { Drawer, Flex } from "antd";
import { DownloadOutlined } from "@ant-design/icons";
import TextInputField from "./TextInputField";
import LoadingContainer from "./LoadingContainer";
const Revaluation = () => {
const [registerNumber, setRegisterNumber] = useState(null);
const [subjectCode, setSubjectCode] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [studentInfo, setStudentInfo] = useState([]);
const [partAInfo, setPartAInfo] = useState([]);
const [partCInfo, setPartCInfo] = useState([]);
const [open, setOpen] = useState(false);
const [size, setSize] = useState("large");
const [type,setType] = useState(null)
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
const submitRevaluationAction = async () => {
console.log("submitRevalutionResults ....");
if (!subjectCode || !registerNumber) {
console.log("Returning ...");
return;
}
setIsLoading(true);
const payload = {
subjectCode,
registerNumber,
};
try {
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/submitRevalutionResults`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
setStudentInfo(responseData?.studentInfo);
setPartAInfo(responseData?.partAInfo);
setPartCInfo(responseData?.partCInfo);
} else {
toast.error("Something went Wrong !!");
}
} catch (error) {
setIsLoading(false);
throw new Error(error);
}
};
return (
<>
<ToastContainer />
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3">
<h1>Welcome to exampaper.vidh.ai</h1>
</Box>
<Box className="d-flex justify-content-between p-3">
{" "}
<Box
sx={{
width: {
xs: "100%", // mobile
md: "40%", // desktop
},
marginX: "auto",
display: "flex",
flexDirection: "column",
gap: 4,
my: 5,
p: 4,
}}
>
<TextInputField
value={registerNumber}
setValue={setRegisterNumber}
placeholder={"Register Number"}
/>
<TextInputField
value={subjectCode}
setValue={setSubjectCode}
placeholder={"Subject Code"}
/>
<Button
className="w-100 bg-primary text-light p-3 rounded"
onClick={submitRevaluationAction}
>
Submit
</Button>
</Box>
{studentInfo.length > 0 && (
<Box className="rounded p-5 mx-5 d-flex flex-column gap-2 text-center w-50">
<Box className="bg-light shadow p-5">
<Box className="my-3 d-flex justify-content-center">
<Avatar size={64} icon={<UserOutlined />} />
</Box>
<Box>
<strong>Student Name : </strong>
{studentInfo[0]?.candidate_name}
</Box>
<Box>
<strong>Register Number : </strong>
{studentInfo[0]?.register_number}
</Box>
<Box>
{" "}
<strong>Subject Code : </strong>
{studentInfo[0]?.subject_code}
</Box>
<Box>
{" "}
<strong>Exam Date : </strong>
{studentInfo[0]?.exam_date}
</Box>
<Box>
{" "}
<strong>Exam Centre Code : </strong>
{studentInfo[0]?.exam_centre_code}
</Box>
<Box>
{" "}
<strong>Exam Centre : </strong>
{studentInfo[0]?.exam_center}
</Box>
</Box>
<Box>
{partCInfo && (
<Box
className="w-100 bg-white rounded p-3 bg-light my-3 shadow"
onClick={showDrawer}
>
Show Part C Data..
</Box>
)}
</Box>
<Box>
{studentInfo.length > 0 && (
<Box className="bg-light p-3 rounded shadow">
<Box>
{" "}
<strong>Barcode 2 : </strong>
{studentInfo[0]?.bar_code2}
</Box>
<Box>
{" "}
<strong>QR code 2 : </strong>
{studentInfo[0]?.qr_code2}
</Box>
<Box>
{" "}
<strong>Barcode 4 : </strong>
{studentInfo[0]?.bar_code4}
</Box>
<Box>
{" "}
<strong>QR code 4 : </strong>
{studentInfo[0]?.qr_code4}
</Box>
<Box className="my-2 d-flex justify-content-end">
<Button className="bg-primary text-white p-2 rounded">
<DownloadOutlined />
</Button>
</Box>
</Box>
)}
</Box>
<Box>
{partCInfo && (
<Box
className="w-100 bg-white rounded p-3 bg-light my-3 shadow"
onClick={showDrawer}
>
Show Part A Data..
</Box>
)}
</Box>
<Drawer
title=""
size={'large'}
onClose={onClose}
open={open}
>
{partCInfo.length > 0 && (
<img
src={`https://docs.exampaper.vidh.ai/${partCInfo[0]?.s3_path}`}
width={"700px"}
height={"auto"}
/>
)}
</Drawer>
</Box>
)}
{isLoading && <LoadingContainer />}
</Box>
</>
);
};
export default Revaluation;

View File

@ -28,7 +28,7 @@ const SystemNumberDialog = (setShowSystemNoContainer,showSystemNoContainer) => {
const handleSubmit = () => { const handleSubmit = () => {
console.log("Handling submit") console.log("Handling submit")
dispatch(updateSystemNo(systemNo)); dispatch(updateSystemNo(systemNo));
navigate("/") // navigate("/")
handleClose(true) handleClose(true)
}; };

View File

@ -1,25 +1,27 @@
import { TextField, Box } from "@mui/material"; import { TextField, Box } from "@mui/material";
import React from 'react'; import React from "react";
const TextInputField = React.forwardRef(({ placeholder, value, setValue, onKeyDown }, ref) => { const TextInputField = React.forwardRef(
return ( ({ placeholder, value, setValue, onKeyDown }, ref) => {
<Box className="d-flex flex-column"> return (
<label htmlFor="limit-input" className="text-left"> <Box className="d-flex flex-column py-2">
{placeholder} :- <label htmlFor="limit-input" className="text-left">
</label> {placeholder} :-
<TextField </label>
className="rounded h6 bg-white" <TextField
type="text" className="rounded h6 bg-white"
placeholder={placeholder} type="text"
id="limit-input" placeholder={placeholder}
autoComplete="off" id="limit-input"
value={value} autoComplete="off"
onChange={(e) => setValue(e.target.value)} value={value}
onKeyDown={onKeyDown} onChange={(e) => setValue(e.target.value)}
inputRef={ref} onKeyDown={onKeyDown}
/> inputRef={ref}
</Box> />
); </Box>
}); );
}
);
export default TextInputField; export default TextInputField;

View File

@ -0,0 +1,860 @@
import { Box, Button } from "@mui/material";
import DownloadIcon from "@mui/icons-material/Download";
import { LazyLoadImage } from "react-lazy-load-image-component";
import { Label, MoreHorizTwoTone, RotateRight } from "@mui/icons-material";
import { useState, useEffect, useRef } from "react";
import { ToastContainer, toast } from "react-toastify";
import LoadingContainer from "./LoadingContainer";
import { useNavigate } from "react-router-dom";
// import "react-toastify/dist/ReactToastify.css";
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
import RotateRightIcon from "@mui/icons-material/RotateRight";
import PlayGroundEditContainer from "./PlayGroundEditContainer";
import saveRotatedImage from "./Utilities/PartCPlaygroundUtilities";
import markAsPartc from "./Utilities/PartAPlaygroundUtilities";
import { updateAttendenceBlank } from "./Utilities/AttendencePlaygroundUtilities";
import TextInputField from "./TextInputField";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import { useParams } from "react-router-dom";
const UpdatedPlaygroundUpdater = ({
oldData,
s3_image_column,
query,
error,
error_reason,
reduxSystemNo,
degreeType,
type,
tableName,
currentCardIndex,
setCurrentCardIndex,
setCardData,
totalData,
}) => {
// console.log("ERROR ============= ",error)
// console.log("ERROR REASON ============== ",error_reason)
// console.log("REDUX SYSTEM NO ================== ",reduxSystemNo)
const navigate = useNavigate();
const { year } = useParams();
const imageDomain =
year === "april2024"
? "https://docs.exampaper.vidh.ai"
: year === "november2024"
? "https://images.exampaper.usln.in"
: "https://docs.exampaper.vidh.ai";
const [dataValue, setDataValue] = useState({});
const [isLoading, setIsLoading] = useState(false);
// console.log("data in query executor Card : ", data);
const [keys, setKeys] = useState([]);
const [values, setValues] = useState([]);
const [rotateAngle, setRotateAngle] = useState(0);
const [imageName, setImageName] = useState(null);
const [tableNameData, setTableNameData] = useState(null);
const imageEleRef = useRef();
const subjectCodeInputEleRef = useRef();
const registerNumberInputEleRef = useRef();
const [showEditContainer, setShowEditContainer] = useState(false);
const [editorType, setEditorType] = useState(null);
const dialogText = "This is dialog text";
const [marks, setMarks] = useState(null);
const [registerNumber, setRegisterNumber] = useState(null);
const [totalStudents, setTotalStudents] = useState(null);
const [totalPresent, setTotalPresent] = useState(null);
const [totalAbsent, setTotalAbsent] = useState(null);
// const [barcode, setBarcode] = useState(null);
const [qrcode, setQrcode] = useState(null);
const [bar_code, set_Barcode] = useState(null);
const [s3Path, setS3Path] = useState(null);
const [subjectCode, setSubjectCode] = useState(null);
const [data, setData] = useState(null);
const [marksR1, setMarksR1] = useState(null);
const [marksR2, setMarksR2] = useState(null);
const [open, setOpen] = useState(true); // Set open state to true by default
const handleClose = () => {
setOpen(false);
};
useEffect(() => {
console.log("data ========== ", data);
if (data) {
console.log("barcode = ", data.barcode);
setQrcode(data.qrcode);
// set_Barcode(data.barcode)
set_Barcode(data.barcode === "" ? null : data.barcode);
setMarks(data.marks);
setS3Path(data.s3_path);
setSubjectCode(data.subject_code);
setRegisterNumber(data.register_number);
setTotalAbsent(data?.total_absent);
setTotalPresent(data?.total_present);
setTotalStudents(data?.total_students);
setRotateAngle(0);
}
console.log("the currect editor type: ", type);
}, [data]);
useEffect(() => {
if (type == "PartA") {
subjectCodeInputEleRef.current.focus();
}
}, [type]);
const handleKeyDown = (e) => {
console.log("handle key down ...")
try {
if (type === "PartA") {
// console.log("Handle key down clicked ...", e);
// console.log("event target ..... ", e.target);
// console.log("barcode targed .....", barcodeInputRef.current);
if (e.key === "Enter") {
if (e.target === subjectCodeInputEleRef.current) {
console.log("subject code input ele ...")
registerNumberInputEleRef.current.focus();
} else if (e.target === registerNumberInputEleRef.current) {
console.log('updating ...')
updateRecordPartA()
}
}
}
} catch (error) {}
};
// useEffect(() => {
// console.log("barcode in use effect ==== ", barcode);
// }, [barcode]);
console.log("data =================== ", data);
// console.log("image column ====== ", s3_image_column);
// console.log("s3 image ======= ", data[s3_image_column]);
// console.log("Keys ==== ",keys)
// console.log("Values ===== ",values)
useEffect(() => {
if (data) {
console.log("Image name ====== ", data?.image_name);
setImageName(data?.image_name);
}
if (tableName) {
setTableNameData(tableName);
}
if (data?.subject_code) {
}
}, [data]);
const updatePartAInstructions = async () => {
console.log("update instrunction");
const payload = {
data,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/updatePartAInstructions`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData?.status === "success") {
console.log("Updation successfull ....");
const updatedData = { ...dataValue, is_backpage: 1 };
// console.log("Data ===== ", updatedData);
setDataValue(updatedData);
// toast.success("Record Marked as Backpage ! ....");
} else {
throw new Error(responseData?.message);
}
} catch (error) {
throw new Error(error);
}
};
const updatePartAFront = async () => {
console.log("update front");
const payload = {
data,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partAFrontSideMarking`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
console.log("Updation successfull ....");
const updatedData = { ...dataValue, is_backpage: 1 };
// console.log("Data ===== ", updatedData);
setDataValue(updatedData);
// toast.success("Record Marked as Backpage ! ....");
} else {
throw new Error(responseData?.message);
}
} catch (error) {
throw new Error(error);
}
};
const updateFront = async () => {
console.log("update front");
const payload = {
data,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcEvFrontSideMarking`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
console.log("Updation successfull ....");
const updatedData = { ...dataValue, is_backpage: 1 };
// console.log("Data ===== ", updatedData);
setDataValue(updatedData);
toast.success("Record Marked as Frontpage ! ....");
} else {
toast.error("Something Went Wrong !...");
setIsLoading(false);
throw new Error(responseData?.message);
}
} catch (error) {
throw new Error(error);
}
};
const updateBack = async () => {
const payload = {
data,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcEvBacksideMarking`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
console.log("Updation successfull ....");
const updatedData = { ...dataValue, is_backpage: 1 };
// console.log("Data ===== ", updatedData);
setDataValue(updatedData);
toast.success("Record Marked as Backpage ! ....");
} else {
setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(responseData?.message);
}
} catch (error) {
throw new Error(error);
}
};
const initateProcess = () => {
console.log("inititate process..");
};
const rotateLeft = () => {
console.log("rotate left .....");
const newAngle = rotateAngle - 90;
setRotateAngle((prev) => prev - 90);
console.log("new angle ....", newAngle);
const newStyle = `rotate(${newAngle}deg)`;
imageEleRef.current.style.transform = newStyle;
};
const rotateRight = () => {
console.log("rotate right");
const newAngle = rotateAngle + 90;
setRotateAngle((prev) => prev + 90);
const newStyle = `rotate(${newAngle}deg)`;
imageEleRef.current.style.transform = newStyle;
};
const updateEvCover = async () => {
const payload = {
data,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcEvCoverMarking`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
const updatedData = { ...dataValue, is_cover: 1 };
// console.log("Data ===== ", updatedData);
setDataValue(updatedData);
console.log("Updation successfull ....");
// toast.success("Record Marked As Ev !...");
} else {
throw new Error(responseData?.message);
}
} catch (error) {
throw new Error(error);
}
};
const markAsDummy = async () => {
const payload = {
data,
};
try {
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcEvDummyMarking`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
const updatedData = { ...dataValue, is_cover: 1 };
// console.log("Data ===== ", updatedData);
setDataValue(updatedData);
console.log("Updation successfull ....");
toast.success("Record Marked As Ev !...");
} else {
setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(responseData?.message);
}
} catch (error) {
setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(error);
}
};
const showContainerAction = () => {
setShowEditContainer(true);
console.log("type === ", type);
// setEditorType(type)
};
const updateAttendenceBlankAction = () => {
updateAttendenceBlank(setIsLoading, data, setShowEditContainer);
};
const buttonActions = {
PartC: [
{ btnLabel: "Mark As Front", action: updateFront },
{ btnLabel: "Mark As Back", action: updateBack },
{ btnLabel: "Mark As Ev", action: updateEvCover },
{ btnLabel: "Mark As Dummy", action: markAsDummy },
{ btnLabel: "Edit", action: showContainerAction },
],
PartA: [
{ btnLabel: "Mark As Front", action: updatePartAFront },
{ btnLabel: "Mark As Backpage", action: updatePartAInstructions },
// { btnLabel: "Initiate Process", action: initateProcess },
{ btnLabel: "Mark As Dummy", action: markAsDummy },
{ btnLabel: "Mark As Part-C", action: markAsPartc },
{ btnLabel: "Edit", action: showContainerAction },
],
Attendence: [
{ btnLabel: "Mark As Blank", action: updateAttendenceBlankAction },
{ btnLabel: "Edit", action: showContainerAction },
],
};
// useEffect(() => {
// setDataValue(data);
// setKeys(Object.keys(data));
// setValues(Object.values(data));
// }, [data]);
useEffect(() => {
console.log("Data value ===== ", dataValue);
setKeys(Object.keys(dataValue));
setValues(Object.values(dataValue));
}, [dataValue]);
const rotate_and_process = async () => {
setIsLoading(true);
try {
const payload = {
data,
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partCRotateProcess`,
{
method: "POST",
header: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
setIsLoading(false);
if (responseData.status === "success") {
console.log("Response successfull ...");
}
} catch (error) {
setIsLoading(false);
throw new Error(error);
}
};
const updateRecordPartA = async () => {
console.log(registerNumber);
console.log(subjectCode);
console.log(bar_code, qrcode);
console.log(!registerNumber && !subjectCode && (!bar_code || !qrcode));
if (!registerNumber && !subjectCode && (!bar_code || !qrcode)) {
return;
}
setIsLoading(true);
try {
const payload = {
qrcode,
barcode: bar_code,
table: tableName,
s3Path,
subjectCode,
registerNumber,
imageName,
rotateAngle,
year,
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartAdata`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
setIsLoading(false);
console.log("response data ========= ", responseData);
if (responseData?.status === "success") {
//toast.success("Record Updated Successfully ...");
if (totalData) {
console.log("current total length ... ", totalData?.length);
console.log("current current index ...", currentCardIndex);
if (currentCardIndex < totalData?.length - 1) {
setCurrentCardIndex((prev) => prev + 1);
}
}
const newCurrentIndex = currentCardIndex + 1;
}
} catch (error) {
setIsLoading(false);
//toast.error("Something Went Wrong ...");
throw new Error(error);
}
};
const saveRotatedImage = async () => {
try {
if (rotateAngle === 0) {
return;
}
const payload = {
imageName,
tableNameData,
rotateAngle,
s3_path: data[s3_image_column],
};
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/saveRotatedImage`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
toast.success("Image Rotation Saved Successfully");
} else {
toast.error("Something Went Wrong !...");
}
} catch (error) {
setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(error);
}
};
useEffect(() => {
if (oldData?.image_name && tableName) {
const fetchPrimaryKeyData = async () => {
setIsLoading(true);
try {
const payload = {
table: tableName,
image_name: oldData?.image_name,
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchPrimaryKeyData`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
const responseData = await response.json();
console.log("response json 11 === ", responseData);
setIsLoading(false);
if (responseData?.status === "success") {
const results = responseData?.data;
console.log("results ==== ", results);
if (results?.length > 0) {
console.log("results === ", results);
setData(results[0]);
}
}
} catch (error) {
setIsLoading(false);
throw new Error(error);
}
};
setTimeout(() => {
fetchPrimaryKeyData();
}, 200);
}
}, [oldData]);
return (
<Box className="w-100 rounded shadow mb-5 bg-white">
<ToastContainer />
<Box className="p-4 d-flex justify-content-between align-items-center">
<Box className="p-1">
<Box className="p-2 d-flex justify-content-end gap-3 align-items-center">
{/* {query.includes("ocr_scanned_part_c_v1") &&
data[s3_image_column] && (
<>
<Button
className="w-50 m-0 bg-primary text-white p-1 rounded"
onClick={() => navigate(`/sqlPlayground/edit?image_name=${data["image_name"]}&table=ocr_scanned_part_c_v1&error=${error}&error_reason=${error_reason}&sysNo=${reduxSystemNo}&degreeType=${degreeType}`)}
>
Edit
</Button>
<Button
className="w-50 m-0 bg-primary text-white p-1 rounded"
onClick={() => {
mark_as_backpage();
}}
>
Mark As Back
</Button>
<Button
className="w-50 m-0 bg-primary text-white p-1 rounded"
onClick={() => {
mark_as_ev();
}}
>
Mark As EV
</Button>
<Button
className="w-50 m-0 bg-primary text-white p-1 rounded"
onClick={() => {
mark_as_dummy();
}}
>
Mark As Dummy
</Button>
</>
)} */}
{/* <Button className="bg-primary">
<a
href={`https://docs.exampaper.vidh.ai/${data[s3_image_column]}`}
>
<DownloadIcon className="text-light text-white" />
</a>
</Button> */}
</Box>
<Box className="border border-dark" id={imageName}>
<img
src={`${imageDomain}/${oldData[s3_image_column]}`}
width="850px"
height="auto"
alt="Image Alt"
ref={imageEleRef}
/>
</Box>
</Box>
{/* <Box
className="d-flex flex-column gap-2 mx-2 py-3"
style={{ minWidth: "250px" }}
>
{type &&
buttonActions[type].map((action) => (
<Button
className="m-0 bg-primary text-white p-3 rounded"
onClick={action?.action}
>
{action?.btnLabel}
</Button>
))}
<Box className="d-flex flex-column justify-content-between gap-2 my-2">
<Button
className="m-0 bg-primary text-white p-3 rounded"
onClick={rotateLeft}
>
Rotate left
<RotateLeftIcon />
</Button>
<Button
className="m-0 bg-primary text-white p-3 rounded"
onClick={rotateRight}
>
Rotate Right
<RotateRight />
</Button>
<Button
className="m-0 bg-primary text-white p-3 rounded"
onClick={() =>
saveRotatedImage(
imageName,
tableNameData,
rotateAngle,
data,
setIsLoading
)
}
>
Save
</Button>
</Box>
</Box> */}
<Box className="py-3 d-flex flex-column justify-content-end w-100 gap-3 p-3">
{type !== "Attendence" ? (
<>
<TextInputField
value={qrcode || ""}
setValue={setQrcode}
placeholder={"QR code"}
/>
<TextInputField
value={bar_code || ""}
setValue={set_Barcode}
placeholder={"BarCode"}
/>
<TextInputField
value={subjectCode || ""}
setValue={setSubjectCode}
placeholder={"Subject code"}
ref={subjectCodeInputEleRef}
onKeyDown={handleKeyDown}
/>
</>
) : (
<>
<TextInputField
value={qrcode}
setValue={setQrcode}
placeholder={"QR code"}
/>
<TextInputField
value={subjectCode}
setValue={setSubjectCode}
placeholder={"Subject Code"}
ref={subjectCodeInputEleRef}
onKeyDown={handleKeyDown}
/>
<TextInputField
value={totalStudents}
setValue={setTotalStudents}
placeholder={"Total Students"}
/>
<TextInputField
value={totalPresent}
setValue={setTotalPresent}
placeholder={"Total Present"}
/>
<TextInputField
value={totalAbsent}
setValue={setTotalAbsent}
placeholder={"Total Absent"}
/>
</>
)}
{type == "PartC" ? (
<>
<TextInputField
value={marks}
setValue={setMarks}
placeholder={"Marks"}
/>
</>
) : type == "PartA" ? (
<TextInputField
value={registerNumber || ""}
setValue={setRegisterNumber}
placeholder={"Register no"}
ref={registerNumberInputEleRef}
onKeyDown={handleKeyDown}
/>
) : null}
<Box display="flex" justifyContent="space-between">
<Button
className="m-0 bg-primary text-white p-3 rounded"
onClick={rotateLeft}
>
Rotate left
<RotateLeftIcon />
</Button>
<Button
className="m-0 bg-primary text-white p-3 rounded"
onClick={rotateRight}
>
Rotate Right
<RotateRightIcon />
</Button>
</Box>
{/* <Button
className="m-0 bg-primary text-white p-3 rounded"
onClick={() =>
saveRotatedImage(
imageName,
tableNameData,
rotateAngle,
data,
setIsLoading
)
}
>
Save
</Button> */}
{type == "PartC" ? (
<Button
className="bg-primary text-white p-3"
onClick={() => updateRecordPartC()}
>
Update
</Button>
) : type == "PartA" ? (
<Button
className="bg-primary text-white p-3"
onClick={() => updateRecordPartA()}
>
Update
</Button>
) : type == "Attendence" ? (
<Button
className="bg-primary text-white p-3"
onClick={() =>
updatePlayGroundAttendence(
setIsLoading,
qrcode,
subjectCode,
totalStudents,
totalPresent,
totalAbsent,
data,
setShowEditContainer
)
}
>
Update
</Button>
) : null}
{/* <Button className="bg-primary text-white p-3">Skip</Button> */}
<Box className="d-flex justify-content-between gap-5">
<Button
className="bg-primary text-white p-3 w-50"
onClick={() => {
if (totalData) {
if (currentCardIndex >= 1) {
setCurrentCardIndex((prev) => prev - 1);
}
}
}}
>
<ArrowBackIcon />
</Button>
<Button
className="bg-primary text-white p-3 w-50"
onClick={() => {
if (totalData) {
console.log("current total length ... ", totalData?.length);
console.log("current current index ...", currentCardIndex);
if (currentCardIndex < totalData?.length - 1) {
setCurrentCardIndex((prev) => prev + 1);
}
}
}}
>
<ArrowForwardIcon />
</Button>
</Box>
</Box>
</Box>
{isLoading && <LoadingContainer loadingText={"Loading ..."} />}
{showEditContainer && (
<PlayGroundEditContainer
type={type}
rotateAngle={rotateAngle}
data={data}
s3Path={data[s3_image_column]}
tableName={tableName}
imageName={data["image_name"]}
setShowEditContainer={setShowEditContainer}
/>
)}
</Box>
);
};
export default UpdatedPlaygroundUpdater;

View File

@ -0,0 +1,325 @@
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Box, Button, Typography } from "@mui/material";
import AntdesignLayout from "./AntdesignLayout";
import LoadingContainer from "./LoadingContainer";
import infinity_loader from "../../assets/Infinity_loader.gif";
import Notification from "./Notification"; // Import the Notification component
import { Height } from "@mui/icons-material";
import ZoomInIcon from "@mui/icons-material/ZoomIn";
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
import DeleteIcon from "@mui/icons-material/Delete";
import { Navigate} from "react-router-dom";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
} from "@mui/material";
const UploadMarksheetDataContainer = () => {
const uploadDataStyleContainer = {
backgroundColor: "white",
borderRadius: "10px",
minWidth: "800px",
padding: "25px 40px",
margin: "10px",
};
const [selectedFile, setSelectedFile] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [notification, setNotification] = useState(null); // Notification state
const [processList, setProcesList] = useState([]);
const showNotification = (message, type) => {
setNotification({ message, type });
};
const handleFileChange = (event) => {
const file = event.target.files && event.target.files[0];
setSelectedFile(file);
};
useEffect(() => {
fetchCertificateDataInsertionList();
const fetchInterval = setInterval(() => {
fetchCertificateDataInsertionList();
}, 2000);
return () => {
clearInterval(fetchInterval);
};
}, []);
const fetchCertificateDataInsertionList = async () => {
try {
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/fetchCertificateDataInsertionList`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const responseData = await response.json();
console.log("Response ==== ", responseData);
if (responseData?.status == "success") {
setProcesList(responseData?.data);
}
} catch (error) {
console.log(error);
}
};
const handleUploadClick = async () => {
// Logic to handle file upload (send the file to server, etc.)
if (selectedFile) {
setIsLoading(true);
console.log(`File selected: ${selectedFile.name}`);
try {
const formData = new FormData();
formData.append("file", selectedFile);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/uploadCertificateData`,
{
method: "POST",
body: formData,
}
);
const result = await response.json();
setIsLoading(false);
if (response.ok) {
console.log(`File uploaded successfully: ${result.message}`);
showNotification("File Uploaded Successfully ...", "success");
} else {
console.error(`Error during upload: ${result.message}`);
showNotification("Something Went Wrong ...", "error");
}
} catch (error) {
setIsLoading(false);
showNotification("Something Went Wrong ...", "error");
console.error("Error uploading the file:", error);
}
}
};
const handleSampleDownload = async () => {
console.log("Downloading ....");
try {
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/download/certificate/sample`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Network response was not ok");
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "sample_certificate_upload_data.csv"; // Customize the file name here
document.body.appendChild(a);
a.click();
a.remove(); // Cleanup
} catch (error) {
console.error("Error downloading the file:", error);
}
};
const parseCreatedOn = (dateValue) => {
console.log("parse created on ....", typeof dateValue);
if (!dateValue) {
return null; // Handle invalid input
} else if (typeof dateValue == "number") {
dateValue = String(dateValue);
}
const year = parseInt(dateValue.substring(0, 4), 10);
console.log("year ===== ", year);
const month = parseInt(dateValue.substring(4, 6), 10) - 1; // Month is 0-based in JS
const day = parseInt(dateValue.substring(6, 8), 10);
const hours = parseInt(dateValue.substring(8, 10), 10);
const minutes = parseInt(dateValue.substring(10, 12), 10);
const seconds = parseInt(dateValue.substring(12, 14), 10);
const parsedDate = new Date(year, month, day, hours, minutes, seconds);
// Check if the date is valid
if (isNaN(parsedDate.getTime())) {
return null; // Invalid date
}
return parsedDate;
};
return (
<AntdesignLayout>
<Box className="d-flex justify-content-center">
<Box style={uploadDataStyleContainer}>
<input
accept=".csv" // File types to accept
style={{ display: "none" }}
id="contained-button-file"
type="file"
onChange={handleFileChange}
/>
<Box className="py-3" style={{ fontSize: "18px" }}>
<strong>Certificate Generation Data Upload:</strong>
</Box>
<Box style={{ fontSize: "15px" }}>
<strong>Note :</strong> The upload data has to be a CSV format with
the following sample CSV header structure.Please Make sure before
Uploading the Data ..
</Box>
<Box className="d-flex justify-content-center align-items-center gap-2 py-4">
<label htmlFor="contained-button-file">
<Button variant="contained" color="primary" component="span">
Choose File
</Button>
</label>
<label>
<Button
variant="contained"
color="primary"
component="span"
onClick={handleSampleDownload}
>
Download Sample CSV
</Button>
</label>
</Box>
{selectedFile && (
<Box
className="d-flex justify-content-center gap-2 rounded p-2 w-100"
style={{ backgroundColor: "#e4f7f5" }}
>
<Typography variant="body1" sx={{ mt: 2 }}>
<strong>Selected File :</strong> {selectedFile.name}
</Typography>
<DeleteIcon
style={{ cursor: "pointer" }}
onClick={() => setSelectedFile(null)}
/>
</Box>
)}
{selectedFile && (
<Button
variant="contained"
color="secondary"
onClick={handleUploadClick}
sx={{ mt: 2 }}
disabled={!selectedFile}
>
Upload File
</Button>
)}
<Box>
<Link to="/certificate/gen">
<Button
variant="contained"
color="secondary"
sx={{ mt: 2 }}
>
Generate For Individual
</Button>
</Link>
</Box>
</Box>
</Box>
<Box
className="py-3"
style={{ width: "70%", margin: "auto", textAlign: "center" }}
>
{processList.length > 0 && (
<>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>
<strong>ID</strong>
</TableCell>
<TableCell>
<strong>File Name</strong>
</TableCell>
<TableCell>
<strong>Status</strong>
</TableCell>
<TableCell>
<strong>Created on</strong>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{processList.map((processData) => (
<TableRow key={processData.id}>
<TableCell>
{processData?.job_vidh_ms_solutions_id}
</TableCell>
<TableCell>{processData?.file_name}</TableCell>
<TableCell style={{ textAlign: "center" }}>
<button
style={{
backgroundColor:
processData?.status_code === "JQ"
? "red"
: "green",
color: "white",
borderRadius: "10px",
padding: "3px 10px",
}}
>
{processData?.status_code}
</button>
</TableCell>
<TableCell>
{processData?.created_on
? new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}).format(parseCreatedOn(processData?.created_on))
: "N/A"}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</>
)}
</Box>
{isLoading && <LoadingContainer />}
{notification && (
<Notification
message={notification.message}
type={notification.type}
onClose={() => setNotification(null)}
/>
)}
</AntdesignLayout>
);
};
export default UploadMarksheetDataContainer;

View File

@ -0,0 +1,138 @@
import { toast } from "react-toastify";
const saveRotatedImage = async (
imageName,
tableNameData,
rotateAngle,
data,
setIsLoading
) => {
try {
console.log("data=", data);
if (rotateAngle === 0) {
return;
}
const payload = {
imageName,
tableNameData,
rotateAngle,
s3_path: data["s3_path"],
};
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/saveRotatedImage`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
toast.success("Image Rotation Saved Successfully");
}
} catch (error) {
setIsLoading(false);
throw new Error(error);
}
};
export default saveRotatedImage;
export const updatePlayGroundAttendence = async (
setIsLoading,
qrcode,
subjectCode,
totalStudents,
totalPresent,
totalAbsent,
data,
setShowEditContainer
) => {
try {
console.log("qrcode ==== ", qrcode);
console.log("subject code ==== ", subjectCode);
console.log("total students ==== ", totalStudents);
console.log("total Absent ==== ", totalAbsent);
console.log("total preent ==== ", totalPresent);
if (!subjectCode || !String(totalStudents) || !String(totalAbsent) || !String(totalPresent)) {
toast.info("Please fill all the fields ...");
return;
}
console.log("updating attendence ...");
console.log("Data ==== ", data);
setIsLoading(true);
const payload = {
qrcode,
subjectCode,
totalStudents,
totalPresent,
totalAbsent,
data,
};
const response = await fetch(
`${
import.meta.env.VITE_REACT_APP_BACKEND_URL
}/updatePlaygroundAttendence`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
toast.success("Attendence Updation Successfully");
setShowEditContainer(false);
}else{
toast.error("Something went Wrong !!")
}
} catch (error) {
setIsLoading(false);
toast.error("Something went Wrong !!");
throw new Error(error);
}
};
export const updateAttendenceBlank = async (
setIsLoading,
data,
setShowEditContainer
) => {
try {
console.log("Data ==== ", data);
setIsLoading(true);
const payload = {
data,
};
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/updateAttendenceBlank`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
toast.success("Attendence Marked as blank Successfully");
setShowEditContainer(false);
} else {
toast.error("Something went Wrong !!");
}
} catch (error) {
setIsLoading(false);
toast.error("Something went Wrong !!");
throw new Error(error);
}
};

View File

@ -0,0 +1,37 @@
import { toast } from "react-toastify";
const markAsPartc = async (data) => {
try {
console.log("data=", data);
if (rotateAngle === 0) {
return;
}
const payload = {
data,
};
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/markAsPartc`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
toast.success("record updated");
} else {
toast.error("Something Went Wrong !...");
}
} catch (error) {
setIsLoading(false);
toast.error("Something Went Wrong !...");
throw new Error(error);
}
};
export default markAsPartc;

View File

@ -0,0 +1,37 @@
import { toast } from "react-toastify";
const saveRotatedImage = async (imageName,tableNameData,rotateAngle,data, setIsLoading) => {
try {
console.log("data=", data)
if (rotateAngle === 0) {
return;
}
const payload = {
imageName,
tableNameData,
rotateAngle,
s3_path: data["s3_path"],
};
setIsLoading(true);
const response = await fetch(
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/saveRotatedImage`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
setIsLoading(false);
const responseData = await response.json();
if (responseData.status === "success") {
toast.success("Image Rotation Saved Successfully")
}
} catch (error) {
setIsLoading(false);
throw new Error(error);
}
};
export default saveRotatedImage

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -8,6 +8,7 @@ export const updatePartAanomolyData = (data) => ({
payload: data, payload: data,
}); });
export const updateSystemNo = (data) => ({ export const updateSystemNo = (data) => ({
type: "UPDATE_SYSTEM_NO", type: "UPDATE_SYSTEM_NO",
payload: data, payload: data,

View File

@ -15,10 +15,12 @@ export default defineConfig(({ mode }) => {
// Load environment variables based on the current mode (e.g., 'development' or 'production') // Load environment variables based on the current mode (e.g., 'development' or 'production')
const env = loadEnv(mode, process.cwd()); const env = loadEnv(mode, process.cwd());
return { return {
define: { define: {
'process.env': env // expose all environment variables prefixed with VITE_ to process.env 'process.env': env // expose all environment variables prefixed with VITE_ to process.env
}, },
plugins: [react()], plugins: [react()],
assetsInclude: ['**/*.csv']
} }
}) })