Compare commits
41 Commits
master
...
part_a_pla
| Author | SHA1 | Date |
|---|---|---|
|
|
f29a3bab00 | |
|
|
9e010d7f49 | |
|
|
caf3eca000 | |
|
|
cbcbf33228 | |
|
|
01234e9295 | |
|
|
63831d050b | |
|
|
6c80deec0d | |
|
|
3ad4c9b51f | |
|
|
72776c2008 | |
|
|
878444d2a9 | |
|
|
e28c9bce3d | |
|
|
0f58d9967a | |
|
|
3161bf2437 | |
|
|
e12f9af402 | |
|
|
955070bab4 | |
|
|
c06b37b28d | |
|
|
d247442c8f | |
|
|
56f3422a84 | |
|
|
a832b7f172 | |
|
|
02a8ec95a9 | |
|
|
48a01ac744 | |
|
|
c948502c26 | |
|
|
8701ee0fd4 | |
|
|
24e413f6cf | |
|
|
f43aa6c583 | |
|
|
9024b77d1d | |
|
|
aee9f5c534 | |
|
|
c31458330b | |
|
|
541654db01 | |
|
|
e88604fdaf | |
|
|
1a4c9538e5 | |
|
|
1c731661f2 | |
|
|
8778784530 | |
|
|
26532bf52d | |
|
|
0d1c8f0101 | |
|
|
d535c3a05f | |
|
|
c49c08e655 | |
|
|
c3f26d3e7b | |
|
|
3c3ee38978 | |
|
|
f010167bdb | |
|
|
42b39b6713 |
3
.env
3
.env
|
|
@ -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"
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
14
deploy.sh
14
deploy.sh
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
217
src/App.css
217
src/App.css
|
|
@ -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;
|
||||||
|
}
|
||||||
138
src/App.jsx
138
src/App.jsx
|
|
@ -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>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -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 cards = [
|
||||||
|
{
|
||||||
|
title: "Reassigned Serial Number Updation",
|
||||||
|
url: "/anomoly/attendence/reassigned",
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// title: "Additional Student Record Insertion",
|
||||||
|
// url: "/anomoly/attendence/additionalRecord",
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
title: "Additional Sheet Insertion",
|
||||||
|
url: "/anomoly/attendence/additionalSheet",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Individual Attendence Sheet Check",
|
||||||
|
url: "/anomoly/attendence/stud_check",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Pending Attendence Correction",
|
||||||
|
url: "/anomoly/attendence/pending_stud_check",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
const AnomolyAttendencePage = () =>{
|
return (
|
||||||
const cards = [
|
<>
|
||||||
{
|
<Box>
|
||||||
title: "Reassigned Serial Number Updation",
|
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3">
|
||||||
url: "/anomoly/attendence/reassigned"
|
<h1>Welcome to exampaper.vidh.ai</h1>
|
||||||
},
|
</Box>
|
||||||
// {
|
<Box className="p-3">
|
||||||
// title: "Additional Student Record Insertion",
|
{cards.map((card) => (
|
||||||
// url: "/anomoly/attendence/additionalRecord",
|
<HomepageCard title={card?.title} url={card?.url} />
|
||||||
// },
|
))}
|
||||||
{
|
</Box>
|
||||||
title: "Additional Sheet Insertion",
|
</Box>
|
||||||
url: "/anomoly/attendence/additionalSheet",
|
</>
|
||||||
}
|
);
|
||||||
]
|
};
|
||||||
|
|
||||||
return (
|
export default AnomolyAttendencePage;
|
||||||
<>
|
|
||||||
<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;
|
|
||||||
|
|
|
||||||
|
|
@ -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(*)"] && (
|
||||||
|
|
|
||||||
|
|
@ -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" />
|
||||||
|
|
|
||||||
|
|
@ -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([]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
const ConvocationCertificateTemplate = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ConvocationCertificateTemplate;
|
||||||
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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}°reeType=${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 && (
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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 />}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -15,10 +15,13 @@ 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);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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}°reeType=${paramsDegreeType}&sysNo=${paramsSysNo}`;
|
const newUrl = `/sections/${year}/sqlPlayground/edit?image_name=${newRecords[currentIndex]?.image_name}&error=${paramsError}&error_reason=${paramsErrorReason}°reeType=${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}°reeType=${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}°reeType=${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 && (
|
||||||
|
|
|
||||||
|
|
@ -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 />}
|
||||||
|
|
|
||||||
|
|
@ -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}°reeType=${degreeType}`)}
|
onClick={() => navigate(`/sections/${year}/sqlPlayground/edit?image_name=${data["image_name"]}&error=${error}&error_reason=${error_reason}&sysNo=${reduxSystemNo}°reeType=${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"
|
||||||
|
|
|
||||||
|
|
@ -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>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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}°reeType=${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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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.
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@ import react from '@vitejs/plugin-react'
|
||||||
export default defineConfig(({ mode }) => {
|
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']
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue