Compare commits
29 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
ae8d795ac3 | |
|
|
5a5c30a6be | |
|
|
b34315f836 | |
|
|
d606973faa | |
|
|
b8c352465c | |
|
|
d009c07a0b | |
|
|
b8f72c2887 | |
|
|
d7c1927bb1 | |
|
|
a2efb769de | |
|
|
23d11e68a9 | |
|
|
4fbaece9fe | |
|
|
42e60020fa | |
|
|
8e2ac24812 | |
|
|
b1c7a4df91 | |
|
|
416e250ad1 | |
|
|
d39348dd48 | |
|
|
01e475baca | |
|
|
2b0e3b11be | |
|
|
165c91d1d0 | |
|
|
1f72fe875f | |
|
|
ab72d324e1 | |
|
|
07e3b607f4 | |
|
|
6ee4b3bfcc | |
|
|
96b231291c | |
|
|
95108241f2 | |
|
|
c2e7f8078d | |
|
|
ae2556c76b | |
|
|
5e091b9a53 | |
|
|
33147c8b0e |
7
.env
7
.env
|
|
@ -1,4 +1,5 @@
|
|||
# VITE_REACT_APP_BACKEND_URL="https://sandbox.exampaper.vidh.ai"
|
||||
VITE_REACT_APP_BACKEND_URL="http://localhost:9999"
|
||||
#VITE_REACT_APP_BACKEND_URL="https://sandbox.exampaper.vidh.ai"
|
||||
METABASE_BASE_URL="http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf"
|
||||
# VITE_REACT_APP_BACKEND_URL="https://api.exampaper.vidh.ai"
|
||||
|
||||
# VITE_REACT_APP_BACKEND_URL="http://localhost:9999"
|
||||
VITE_REACT_APP_BACKEND_URL="https://api.exampaper.vidh.ai"
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
filename*,enter filename,"INSTUCTIONS: Present means mark '0', Absent means mark '1', Assigned means mark as 0, Reassigned means mark '1'. NOTE: all '*' fields are mandatory so please all '*' compulsory. Get filename from the UI which is as Imagename",,,
|
||||
,,,,,
|
||||
subject_code*,enter subject_code,,,,
|
||||
exam_centre_code*,enter exam_centre_code,,,,
|
||||
subject_title*,enter subject_title,,,,
|
||||
degree_with_branch*,enter degree_with_branch,,,,
|
||||
exam_date*,enter exam_date,,,,
|
||||
exam_date_session,enter exam_date_session,,,,
|
||||
cover_a,enter cover_a,,,,
|
||||
cover_b,enter cover_b,,,,
|
||||
,,,,,
|
||||
student_data,,,,,
|
||||
sno*,register_number*,Present/Absent*,Assigned/Reassigned*,reassigned_sno*,signed*
|
||||
1,,,,,
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#! /bin/bash
|
||||
|
||||
SOURCE_DIR=/home/neuu/attendence_UI/frontend
|
||||
BRANCH=master
|
||||
FRONTEND_DIR=/var/www/exampaper.vidh.ai
|
||||
SERVER_IP=52.66.73.43
|
||||
|
||||
cd ~/$SOURCE_DIR
|
||||
echo "Changed into attendence UI frontend dir ....."
|
||||
|
||||
echo "Pulling $BRANCH ..."
|
||||
|
||||
git pull origin $BRANCH
|
||||
if [[ $? -eq 0 ]];then
|
||||
echo "Pulled the latest code ...."
|
||||
npm run build
|
||||
if [[ $? -eq 0 ]];then
|
||||
echo "Build the latest file ....."
|
||||
scp -r dist/* ubuntu@$SERVER_IP:$FRONTEND_DIR
|
||||
if [[ $? -eq 0 ]];then
|
||||
echo "Copying build file to $FRONTEND_DIR successfull ...."
|
||||
else
|
||||
echo "Copying build file to $FRONTEND_DIR failed ...."
|
||||
fi
|
||||
else
|
||||
echo "Build file failed ...."
|
||||
fi
|
||||
else
|
||||
echo "Pulling latest code failed ...."
|
||||
fi
|
||||
|
|
@ -15,13 +15,17 @@
|
|||
"antd": "^5.17.3",
|
||||
"bootstrap": "^5.3.3",
|
||||
"dotenv": "^16.4.5",
|
||||
"react": "^18.2.0",
|
||||
"html5-qrcode": "^2.1.5",
|
||||
"react": "^18.3.1",
|
||||
"react-bootstrap": "^2.10.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-lazy-load-image-component": "^1.6.0",
|
||||
"react-medium-image-zoom": "^5.2.4",
|
||||
"react-qr-barcode-scanner": "^1.0.6",
|
||||
"react-redux": "^9.1.2",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"react-toastify": "^10.0.5",
|
||||
"react-webcam": "^7.2.0",
|
||||
"react-zoom-pan-pinch": "^3.4.4",
|
||||
"redux": "^5.0.1"
|
||||
},
|
||||
|
|
@ -1106,6 +1110,7 @@
|
|||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
||||
"deprecated": "Use @eslint/config-array instead",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^2.0.2",
|
||||
|
|
@ -1133,6 +1138,7 @@
|
|||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
|
||||
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||
"deprecated": "Use @eslint/object-schema instead",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
|
|
@ -1965,6 +1971,11 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/scheduler": {
|
||||
"version": "0.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
||||
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A=="
|
||||
},
|
||||
"node_modules/@types/use-sync-external-store": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||
|
|
@ -2000,6 +2011,26 @@
|
|||
"vite": "^4.2.0 || ^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@zxing/library": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.17.1.tgz",
|
||||
"integrity": "sha512-RuiBZuteGaFXCle/b0X+g3peN8UpDc3pGe/J7hZBzKWaMZLbjensR7ja3vy47xWhXU4e8MICGqegPMxc2V2sow==",
|
||||
"dependencies": {
|
||||
"ts-custom-error": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.4.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@zxing/text-encoding": "~0.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@zxing/text-encoding": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz",
|
||||
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
|
|
@ -3403,6 +3434,7 @@
|
|||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
|
|
@ -3561,6 +3593,11 @@
|
|||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/html5-qrcode": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.1.5.tgz",
|
||||
"integrity": "sha512-3cOA0lPIcKtMd7Sz9BZm5ERAokv5uj35zT3o59LMVF6wLesYJ4WZaD28Z0OPnsfxe4dHGFgZ3RZ1si8f2AfOGw=="
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
|
||||
|
|
@ -3598,6 +3635,7 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
|
|
@ -4127,12 +4165,22 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
|
|
@ -5179,6 +5227,19 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/react-lazy-load-image-component": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/react-lazy-load-image-component/-/react-lazy-load-image-component-1.6.0.tgz",
|
||||
"integrity": "sha512-8KFkDTgjh+0+PVbH+cx0AgxLGbdTsxWMnxXzU5HEUztqewk9ufQAu8cstjZhyvtMIPsdMcPZfA0WAa7HtjQbBQ==",
|
||||
"dependencies": {
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.throttle": "^4.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x",
|
||||
"react-dom": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x"
|
||||
}
|
||||
},
|
||||
"node_modules/react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
|
|
@ -5199,6 +5260,39 @@
|
|||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-qr-barcode-scanner": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/react-qr-barcode-scanner/-/react-qr-barcode-scanner-1.0.6.tgz",
|
||||
"integrity": "sha512-DdalO4oqHyxWPa4cIjiHeMS19HbIvKq+oo/PAglAsxmfhAUGC8sM1mJnzo0zPQM1yw9ZNpjrtqHz+rs86Mu7Ww==",
|
||||
"dependencies": {
|
||||
"@types/react": "^16.9.35",
|
||||
"@zxing/library": "^0.17.0",
|
||||
"react-webcam": "^5.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-qr-barcode-scanner/node_modules/@types/react": {
|
||||
"version": "16.14.60",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.60.tgz",
|
||||
"integrity": "sha512-wIFmnczGsTcgwCBeIYOuy2mdXEiKZ5znU/jNOnMZPQyCcIxauMGWlX0TNG4lZ7NxRKj7YUIZRneJQSSdB2jKgg==",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "^0.16",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/react-qr-barcode-scanner/node_modules/react-webcam": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-webcam/-/react-webcam-5.2.4.tgz",
|
||||
"integrity": "sha512-Qqj14t68Ke1eoEYjFde+N48HtuIJg0ePIQRpFww9eZt5oBcDpe/l60h+m3VRFJAR5/E3dOhSU5R8EJEcdCq/Eg==",
|
||||
"peerDependencies": {
|
||||
"react": ">=15.3.0",
|
||||
"react-dom": ">=15.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz",
|
||||
|
|
@ -5287,6 +5381,15 @@
|
|||
"react-dom": ">=16.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-webcam": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-webcam/-/react-webcam-7.2.0.tgz",
|
||||
"integrity": "sha512-xkrzYPqa1ag2DP+2Q/kLKBmCIfEx49bVdgCCCcZf88oF+0NPEbkwYk3/s/C7Zy0mhM8k+hpdNkBLzxg8H0aWcg==",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.2.0",
|
||||
"react-dom": ">=16.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-zoom-pan-pinch": {
|
||||
"version": "3.4.4",
|
||||
"resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.4.4.tgz",
|
||||
|
|
@ -5393,6 +5496,7 @@
|
|||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
|
|
@ -5768,6 +5872,14 @@
|
|||
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
|
||||
},
|
||||
"node_modules/ts-custom-error": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz",
|
||||
"integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
|
|
@ -6596,8 +6708,7 @@
|
|||
"@emotion/use-insertion-effect-with-fallbacks": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
|
||||
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw=="
|
||||
},
|
||||
"@emotion/utils": {
|
||||
"version": "1.2.1",
|
||||
|
|
@ -7003,8 +7114,7 @@
|
|||
"@mui/types": {
|
||||
"version": "7.2.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz",
|
||||
"integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ=="
|
||||
},
|
||||
"@mui/utils": {
|
||||
"version": "5.15.14",
|
||||
|
|
@ -7176,8 +7286,7 @@
|
|||
"uncontrollable": {
|
||||
"version": "8.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz",
|
||||
"integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -7384,6 +7493,11 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/scheduler": {
|
||||
"version": "0.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
||||
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A=="
|
||||
},
|
||||
"@types/use-sync-external-store": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||
|
|
@ -7413,6 +7527,21 @@
|
|||
"react-refresh": "^0.14.0"
|
||||
}
|
||||
},
|
||||
"@zxing/library": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.17.1.tgz",
|
||||
"integrity": "sha512-RuiBZuteGaFXCle/b0X+g3peN8UpDc3pGe/J7hZBzKWaMZLbjensR7ja3vy47xWhXU4e8MICGqegPMxc2V2sow==",
|
||||
"requires": {
|
||||
"@zxing/text-encoding": "~0.9.0",
|
||||
"ts-custom-error": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@zxing/text-encoding": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz",
|
||||
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
||||
"optional": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
|
|
@ -7423,8 +7552,7 @@
|
|||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.6",
|
||||
|
|
@ -7661,8 +7789,7 @@
|
|||
"bootstrap": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
|
||||
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
|
|
@ -8239,15 +8366,13 @@
|
|||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz",
|
||||
"integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
"dev": true
|
||||
},
|
||||
"eslint-plugin-react-refresh": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.7.tgz",
|
||||
"integrity": "sha512-yrj+KInFmwuQS2UQcg1SF83ha1tuHC1jMQbRNyuWtlEzzKRDgAl7L4Yp4NlDUZTZNlWvHEzOtJhMi40R7JxcSw==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
"dev": true
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "7.2.2",
|
||||
|
|
@ -8560,6 +8685,11 @@
|
|||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"html5-qrcode": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/html5-qrcode/-/html5-qrcode-2.1.5.tgz",
|
||||
"integrity": "sha512-3cOA0lPIcKtMd7Sz9BZm5ERAokv5uj35zT3o59LMVF6wLesYJ4WZaD28Z0OPnsfxe4dHGFgZ3RZ1si8f2AfOGw=="
|
||||
},
|
||||
"ignore": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
|
||||
|
|
@ -8955,12 +9085,22 @@
|
|||
"p-locate": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||
},
|
||||
"lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
|
|
@ -9229,8 +9369,7 @@
|
|||
"qrcode.react": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz",
|
||||
"integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q=="
|
||||
},
|
||||
"queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
|
|
@ -9671,6 +9810,15 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"react-lazy-load-image-component": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/react-lazy-load-image-component/-/react-lazy-load-image-component-1.6.0.tgz",
|
||||
"integrity": "sha512-8KFkDTgjh+0+PVbH+cx0AgxLGbdTsxWMnxXzU5HEUztqewk9ufQAu8cstjZhyvtMIPsdMcPZfA0WAa7HtjQbBQ==",
|
||||
"requires": {
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.throttle": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
|
|
@ -9679,8 +9827,34 @@
|
|||
"react-medium-image-zoom": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-medium-image-zoom/-/react-medium-image-zoom-5.2.4.tgz",
|
||||
"integrity": "sha512-XLu/fLqpbmhiDAGA6yie78tDv4kh8GxvS7kKQArSOvCvm5zvgItoh4h01NAAvnezQ60ovsTeedHiHG3eG9CcGg==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-XLu/fLqpbmhiDAGA6yie78tDv4kh8GxvS7kKQArSOvCvm5zvgItoh4h01NAAvnezQ60ovsTeedHiHG3eG9CcGg=="
|
||||
},
|
||||
"react-qr-barcode-scanner": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/react-qr-barcode-scanner/-/react-qr-barcode-scanner-1.0.6.tgz",
|
||||
"integrity": "sha512-DdalO4oqHyxWPa4cIjiHeMS19HbIvKq+oo/PAglAsxmfhAUGC8sM1mJnzo0zPQM1yw9ZNpjrtqHz+rs86Mu7Ww==",
|
||||
"requires": {
|
||||
"@types/react": "^16.9.35",
|
||||
"@zxing/library": "^0.17.0",
|
||||
"react-webcam": "^5.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/react": {
|
||||
"version": "16.14.60",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.60.tgz",
|
||||
"integrity": "sha512-wIFmnczGsTcgwCBeIYOuy2mdXEiKZ5znU/jNOnMZPQyCcIxauMGWlX0TNG4lZ7NxRKj7YUIZRneJQSSdB2jKgg==",
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "^0.16",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"react-webcam": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-webcam/-/react-webcam-5.2.4.tgz",
|
||||
"integrity": "sha512-Qqj14t68Ke1eoEYjFde+N48HtuIJg0ePIQRpFww9eZt5oBcDpe/l60h+m3VRFJAR5/E3dOhSU5R8EJEcdCq/Eg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-redux": {
|
||||
"version": "9.1.2",
|
||||
|
|
@ -9733,11 +9907,15 @@
|
|||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"react-webcam": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-webcam/-/react-webcam-7.2.0.tgz",
|
||||
"integrity": "sha512-xkrzYPqa1ag2DP+2Q/kLKBmCIfEx49bVdgCCCcZf88oF+0NPEbkwYk3/s/C7Zy0mhM8k+hpdNkBLzxg8H0aWcg=="
|
||||
},
|
||||
"react-zoom-pan-pinch": {
|
||||
"version": "3.4.4",
|
||||
"resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.4.4.tgz",
|
||||
"integrity": "sha512-lGTu7D9lQpYEQ6sH+NSlLA7gicgKRW8j+D/4HO1AbSV2POvKRFzdWQ8eI0r3xmOsl4dYQcY+teV6MhULeg1xBw==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-lGTu7D9lQpYEQ6sH+NSlLA7gicgKRW8j+D/4HO1AbSV2POvKRFzdWQ8eI0r3xmOsl4dYQcY+teV6MhULeg1xBw=="
|
||||
},
|
||||
"redux": {
|
||||
"version": "5.0.1",
|
||||
|
|
@ -10069,6 +10247,11 @@
|
|||
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
|
||||
},
|
||||
"ts-custom-error": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz",
|
||||
"integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
|
|
@ -10186,8 +10369,7 @@
|
|||
"use-sync-external-store": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
|
||||
"integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw=="
|
||||
},
|
||||
"vite": {
|
||||
"version": "5.2.11",
|
||||
|
|
|
|||
|
|
@ -17,13 +17,17 @@
|
|||
"antd": "^5.17.3",
|
||||
"bootstrap": "^5.3.3",
|
||||
"dotenv": "^16.4.5",
|
||||
"react": "^18.2.0",
|
||||
"html5-qrcode": "^2.1.5",
|
||||
"react": "^18.3.1",
|
||||
"react-bootstrap": "^2.10.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-lazy-load-image-component": "^1.6.0",
|
||||
"react-medium-image-zoom": "^5.2.4",
|
||||
"react-qr-barcode-scanner": "^1.0.6",
|
||||
"react-redux": "^9.1.2",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"react-toastify": "^10.0.5",
|
||||
"react-webcam": "^7.2.0",
|
||||
"react-zoom-pan-pinch": "^3.4.4",
|
||||
"redux": "^5.0.1"
|
||||
},
|
||||
|
|
|
|||
73
src/App.jsx
73
src/App.jsx
|
|
@ -12,6 +12,21 @@ import PartAReassigned from "./Components/PartAReassigned";
|
|||
import PartACorrection from "./Components/PartACorrection";
|
||||
import Verification from "./Components/Verification";
|
||||
import Statistics from "./Components/Statistics";
|
||||
import AnomolyAttendencePage from "./Components/AnomolyAttendencePage";
|
||||
import AttendenceAdditionalRecord from "./Components/AttendenceAdditionalRecord";
|
||||
import AttendenceAdditionalRecordCorrection from "./Components/AttendenceAdditionalRecordCorrection";
|
||||
import AttendanceAdditionalSheet from "./Components/AttendanceAdditionalSheet";
|
||||
import QueryExecutor from "./Components/QueryExecutor";
|
||||
import RecordEditor from "./Components/RecordEditor";
|
||||
import VerifyMarks from "./Components/VerifyMarks";
|
||||
import QueryCardEditor from "./Components/QueryCardEditor";
|
||||
import AnomolyPartC from "./Components/AnomolyPartC";
|
||||
import BarcodeScanner from "./Components/BarcodeScanner"
|
||||
import EvQrcode from "./Components/EvQrcode";
|
||||
import QrcodeCardEditor from "./Components/QrCodeCardEditor";
|
||||
import StudentResultsData from "./Components/StudentsResultsData";
|
||||
import PlayGrounds from "./Components/PlayGrounds";
|
||||
import PlayGround from "./Components/PlayGround";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
|
@ -19,40 +34,62 @@ function App() {
|
|||
<BrowserRouter>
|
||||
<Routes>
|
||||
<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
|
||||
path="/anomoly/reassigned"
|
||||
path="/anomoly/attendence/reassigned"
|
||||
element={<AnomolyReassigned />}
|
||||
></Route>
|
||||
<Route
|
||||
path="/sqlPlayground/Editor"
|
||||
element={<RecordEditor />}
|
||||
></Route>
|
||||
<Route
|
||||
path="/anomoly/attendence/additionalSheet"
|
||||
element={<AttendanceAdditionalSheet />}
|
||||
></Route>
|
||||
<Route path="/barcodeScanner" element={<BarcodeScanner/>}></Route>
|
||||
<Route
|
||||
path="/anomoly/reassigned/booklet"
|
||||
element={<AttendenceCorrection />}
|
||||
>
|
||||
</Route>
|
||||
></Route>
|
||||
<Route
|
||||
path="/anomoly/reassigned/stats"
|
||||
element={<ReassignedStats />}
|
||||
>
|
||||
</Route>
|
||||
></Route>
|
||||
<Route
|
||||
path="/anomoly/attendence"
|
||||
element={<AnomolyAttendencePage />}
|
||||
></Route>
|
||||
<Route
|
||||
path="/anomoly/attendence/additionalRecord"
|
||||
element={<AttendenceAdditionalRecord />}
|
||||
/>
|
||||
<Route
|
||||
path="/anomoly/attendence/additionalRecord/correction"
|
||||
element={<AttendenceAdditionalRecordCorrection />}
|
||||
/>
|
||||
<Route
|
||||
path="/anomoly/reassigned/stats/:exam_centre_code"
|
||||
element={<IndividualExamCentreStats/>}
|
||||
>
|
||||
</Route>
|
||||
<Route
|
||||
path="/anomoly/PartA"
|
||||
element={<PartAReassigned/>}
|
||||
>
|
||||
</Route>
|
||||
element={<IndividualExamCentreStats />}
|
||||
></Route>
|
||||
<Route path="/anomoly/PartA" element={<PartAReassigned />}></Route>
|
||||
{/* <Route
|
||||
path="/verification"
|
||||
element={<Verification/>}
|
||||
>
|
||||
</Route> */}
|
||||
<Route path="/statistics" element={<Statistics/>}></Route>
|
||||
<Route path="/anomoly/partA/booklet"
|
||||
element={<PartACorrection/>}
|
||||
>
|
||||
</Route>
|
||||
<Route path="/statistics" element={<Statistics />}></Route>
|
||||
<Route
|
||||
path="/anomoly/partA/booklet"
|
||||
element={<PartACorrection />}
|
||||
></Route>
|
||||
<Route path="/anomoly/partC" element={<AnomolyPartC/>}></Route>
|
||||
<Route path="/evQrcode" element={<EvQrcode/>}></Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
import { Box } from "@mui/material";
|
||||
import HomepageCard from "./HomepageCard";
|
||||
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",
|
||||
}
|
||||
]
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3">
|
||||
<h1>Welcome to exampaper.vidh.ai</h1>
|
||||
</Box>
|
||||
<Box className="p-3">
|
||||
{cards.map((card) => (
|
||||
<HomepageCard title={card?.title} url={card?.url} />
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default AnomolyAttendencePage;
|
||||
|
|
@ -0,0 +1,449 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
CardContent,
|
||||
Typography,
|
||||
CircularProgress,
|
||||
} from "@mui/material";
|
||||
import { Layout, theme, Pagination } from "antd";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||
import HomeIcon from "@mui/icons-material/Home";
|
||||
import QueryExecutorCard from "./QueryExecutorCard";
|
||||
import {
|
||||
updatePartCErrorList,
|
||||
updatePartCErrorData,
|
||||
updateSelectedError,
|
||||
updateSelectedJson,
|
||||
} from "../redux/actions/actions";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import SystemNumberDialog from "./SystemNumberDialog";
|
||||
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 { useSearchParams } from "react-router-dom";
|
||||
import { updatePartCDegreeType } from "../redux/actions/actions";
|
||||
|
||||
const { Content, Header } = Layout;
|
||||
|
||||
function AnomalyPartC() {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isLoading2, setIsLoading2] = useState(false);
|
||||
const [anomalyData, setAnomalyData] = useState(null);
|
||||
const [evErrors, setEvErrors] = useState([]);
|
||||
const [error, setError] = useState(null);
|
||||
const [errorReason, setErrorReason] = useState(null);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [totalPages, setTotalPages] = useState(1);
|
||||
const [showSystemNoContainer, setShowSystemNoContainer] = useState(false);
|
||||
const [selectedIndex, setSelectedIndex] = useState(null);
|
||||
const [selectedDegreeType, setSelectedDegreeType] = useState(null);
|
||||
const [dataFetched, setDataFetched] = useState([]);
|
||||
const [counter, setCounter] = useState(0);
|
||||
const degreeTypes = [
|
||||
{ type: "UG", type_code: "0" },
|
||||
{ type: "PG", type_code: "2" },
|
||||
{ type: "UNIVERSITY" , type_code: "5"}
|
||||
];
|
||||
|
||||
const reduxDegreeType = useSelector((state) => state?.partCDegreeType);
|
||||
console.log("Redux degree type ...", reduxDegreeType);
|
||||
useEffect(() => {
|
||||
if (reduxDegreeType) {
|
||||
setSelectedDegreeType(reduxDegreeType);
|
||||
} else {
|
||||
setSelectedDegreeType("2");
|
||||
}
|
||||
}, [reduxDegreeType]);
|
||||
|
||||
const handleDegreeTypeChange = (e) => {
|
||||
const newDegreeType = e.target.value;
|
||||
console.log("Value ===== ", newDegreeType);
|
||||
setSelectedDegreeType(newDegreeType);
|
||||
dispatch(updatePartCDegreeType(newDegreeType));
|
||||
};
|
||||
const {
|
||||
token: { colorBgContainer, borderRadiusLG },
|
||||
} = theme.useToken();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const paramsError = searchParams.get("error");
|
||||
const paramsErrorReason = searchParams.get("error_reason");
|
||||
const paramsSysNo = searchParams.get("sysNo");
|
||||
const paramsDegreeType = searchParams.get("degreeType");
|
||||
const evErrorsList = useSelector((state) => state?.partCErrorList);
|
||||
console.log("evErrorsList = ", evErrorsList);
|
||||
|
||||
const evErrorsData = useSelector((state) => state?.partCErrorData);
|
||||
console.log("evErrorData: ", evErrorsData);
|
||||
|
||||
const reduxSystemNo = useSelector((state) => state?.systemNumber);
|
||||
console.log("systemno: ", reduxSystemNo);
|
||||
|
||||
// const selectedError = useSelector((state) => state?.selectedError);
|
||||
// console.log("selectedError: ", selectedError)
|
||||
|
||||
// const selectedErrorData = useSelector((state) => state?.selectedErrorData);
|
||||
// console.log("selectedErrorData: ", selectedErrorData)
|
||||
|
||||
const selectedErrorJson = useSelector((state) => state?.selectedErrorJson);
|
||||
console.log("selectedErrorJson: ", selectedErrorJson);
|
||||
|
||||
useEffect(() => {
|
||||
if (!reduxSystemNo) {
|
||||
setShowSystemNoContainer(true);
|
||||
} else {
|
||||
if (evErrorsList && evErrorsList.length > 0) {
|
||||
setAnomalyData(evErrorsList);
|
||||
} else {
|
||||
fetchAnomalyData();
|
||||
}
|
||||
}
|
||||
}, [reduxSystemNo]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Use effect 11 called ...");
|
||||
if (!reduxSystemNo) {
|
||||
setShowSystemNoContainer(true);
|
||||
} else {
|
||||
if (evErrorsData && evErrorsData.length > 0) {
|
||||
setEvErrors(evErrorsData);
|
||||
}
|
||||
if (error) {
|
||||
fetchAnomalyRecords(reduxSystemNo);
|
||||
}
|
||||
}
|
||||
}, [error, errorReason,counter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (evErrors && evErrors.length > 0) {
|
||||
console.log("len = ", evErrors.length);
|
||||
const tp = Math.ceil(evErrors.length / 10);
|
||||
console.log("tp = ", tp);
|
||||
setTotalPages(tp);
|
||||
}
|
||||
}, [evErrors]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(updatePartCErrorData([]));
|
||||
// setAnomalyData([]);
|
||||
setEvErrors([]);
|
||||
setDataFetched(false);
|
||||
fetchAnomalyData();
|
||||
}, [selectedDegreeType]);
|
||||
|
||||
const updateSystemReservationStatus = async (systemRecords) => {
|
||||
const payload = {
|
||||
systemRecords,
|
||||
sysNo: reduxSystemNo,
|
||||
};
|
||||
try {
|
||||
fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/updateSystemReservationStatusPartC`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((responseData) => {
|
||||
console.log("response from updation : ", responseData);
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error("Error in update system records : ", systemRecords);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchAnomalyData = async () => {
|
||||
setIsLoading(true);
|
||||
setDataFetched(false);
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/getpartcEv?degreeType=${selectedDegreeType}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
const responseData = await response.json();
|
||||
setAnomalyData(responseData.data);
|
||||
setDataFetched(true);
|
||||
dispatch(updatePartCErrorList(responseData.data));
|
||||
} catch (error) {
|
||||
console.error("Error fetching data: ", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchAnomalyRecords = async (reduxSystemNo) => {
|
||||
console.log("fetching anomoly records");
|
||||
setIsLoading(true);
|
||||
setDataFetched(false);
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/getpartcEvErrors`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
error,
|
||||
error_reason: errorReason,
|
||||
sysno: reduxSystemNo,
|
||||
degreeType: selectedDegreeType,
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
const responseData = await response.json();
|
||||
var systemRecords = responseData?.data;
|
||||
console.log("System record ====== ", responseData.systemRecord);
|
||||
if (!responseData.systemRecord) {
|
||||
systemRecords = getRecordsBySystemId(responseData?.data, reduxSystemNo);
|
||||
}
|
||||
console.log("System records : ", systemRecords);
|
||||
setDataFetched(true);
|
||||
setEvErrors(systemRecords);
|
||||
setIsLoading(false);
|
||||
dispatch(updatePartCErrorData(systemRecords));
|
||||
localStorage.setItem("marks_manual_data", JSON.stringify(systemRecords));
|
||||
updateSystemReservationStatus(systemRecords);
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
console.error("Error fetching data: ", error);
|
||||
}
|
||||
};
|
||||
|
||||
function getRecordsBySystemId(records, systemId) {
|
||||
const new_data = [];
|
||||
if (!records) records = [];
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
var count = i % 5;
|
||||
if (count === systemId - 1) {
|
||||
new_data.push(records[i]);
|
||||
}
|
||||
}
|
||||
return new_data;
|
||||
}
|
||||
|
||||
const handleClick = (error, errorReason, index) => {
|
||||
setError(error);
|
||||
setErrorReason(errorReason);
|
||||
setCurrentPage(1);
|
||||
setSelectedIndex(index);
|
||||
let tmp = {};
|
||||
tmp["error"] = error;
|
||||
tmp["error_reason"] = errorReason;
|
||||
console.log("tmp = ", tmp);
|
||||
dispatch(updateSelectedJson(tmp));
|
||||
setCounter(prev=>prev+1)
|
||||
};
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
setIsLoading2(true);
|
||||
setCurrentPage(page);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (currentPage > 0) {
|
||||
setIsLoading2(false);
|
||||
}
|
||||
}, [currentPage, evErrors]);
|
||||
|
||||
const getCurrentPageData = () => {
|
||||
const startIndex = (currentPage - 1) * 10;
|
||||
const endIndex = startIndex + 10;
|
||||
return evErrors.slice(startIndex, endIndex);
|
||||
};
|
||||
|
||||
const handleSystemNoChange = () => {
|
||||
console.log("System No Change is called");
|
||||
setShowSystemNoContainer(true);
|
||||
dispatch(updateSelectedJson({}));
|
||||
// dispatch(updatePartCErrorList([]))
|
||||
dispatch(updatePartCErrorData([]));
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout style={{ minHeight: "100vh" }}>
|
||||
<Layout>
|
||||
<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" }}
|
||||
onClick={handleSystemNoChange}
|
||||
>
|
||||
<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%)",
|
||||
}}
|
||||
>
|
||||
{isLoading ? (
|
||||
<Box
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
height="100%"
|
||||
>
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
) : (
|
||||
<>
|
||||
<Box className="w-25 d-flex flex-column align-items-start">
|
||||
<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>
|
||||
{dataFetched ? (
|
||||
anomalyData && anomalyData.length > 0 ? (
|
||||
anomalyData.map((item, index) => (
|
||||
<Card
|
||||
onClick={() =>
|
||||
handleClick(item.error, item.error_reason, index)
|
||||
}
|
||||
key={index}
|
||||
style={{
|
||||
margin: "16px",
|
||||
borderRadius: borderRadiusLG,
|
||||
alignItems: "flex-start",
|
||||
textAlign: "start",
|
||||
cursor: "pointer",
|
||||
color: "white",
|
||||
backgroundColor:
|
||||
selectedIndex === index ? "#3f51b5" : "#537895",
|
||||
backgroundImage:
|
||||
selectedIndex === index
|
||||
? "linear-gradient(315deg, #70a1ff 0%, #c2c0c0 74%);"
|
||||
: "linear-gradient(315deg, #537895 0%, #09203f 74%)",
|
||||
}}
|
||||
>
|
||||
<CardContent>
|
||||
{item.error && (
|
||||
<Typography id="1" variant="body2">
|
||||
Code: {item.error}
|
||||
</Typography>
|
||||
)}
|
||||
{item["count(*)"] && (
|
||||
<Typography id="2" variant="body2" color="whitesmoke">
|
||||
Count: {item["count(*)"]}
|
||||
</Typography>
|
||||
)}
|
||||
{/* {item.error_reason && (
|
||||
<Typography id="3" variant="body2" color="whitesmoke">
|
||||
Reason: {item.error_reason}
|
||||
</Typography>
|
||||
)} */}
|
||||
</CardContent>
|
||||
</Card>
|
||||
))
|
||||
) : (
|
||||
<Box className="p-3 my-3 bg-white rounded">
|
||||
<h5>No data to display ...</h5>
|
||||
</Box>
|
||||
)
|
||||
) : null}
|
||||
{evErrors && evErrors.length > 0 && dataFetched ? (
|
||||
<>
|
||||
<Box
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
marginBottom="16px"
|
||||
>
|
||||
<Pagination
|
||||
current={currentPage}
|
||||
total={totalPages * 10}
|
||||
onChange={handlePageChange}
|
||||
/>
|
||||
</Box>
|
||||
{isLoading2 ? (
|
||||
<Box
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
height="100%"
|
||||
>
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
) : (
|
||||
getCurrentPageData().map((data, index) => (
|
||||
<QueryExecutorCard
|
||||
key={index}
|
||||
data={data}
|
||||
s3_image_column="s3_path"
|
||||
query="ocr_scanned_part_c_v1"
|
||||
error={error}
|
||||
error_reason={errorReason}
|
||||
reduxSystemNo={reduxSystemNo}
|
||||
degreeType={selectedDegreeType}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</>
|
||||
) : dataFetched && evErrorsList && evErrorsList.length == 0 ? (
|
||||
<Box className="p-3 my-3 bg-white rounded">
|
||||
<h5>No data to display ...</h5>
|
||||
</Box>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</Content>
|
||||
{showSystemNoContainer && (
|
||||
<SystemNumberDialog
|
||||
setShowSystemNoContainer={setShowSystemNoContainer}
|
||||
showSystemNoContainer={showSystemNoContainer}
|
||||
/>
|
||||
)}
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default AnomalyPartC;
|
||||
|
|
@ -77,7 +77,7 @@ const AnomolyReassigned = () => {
|
|||
const navigate = useNavigate();
|
||||
function createData(
|
||||
attendence_serial_no,
|
||||
student_slno,
|
||||
answer_booklet_sno,
|
||||
exam_centre_code,
|
||||
exam_centre,
|
||||
student_name,
|
||||
|
|
@ -86,7 +86,7 @@ const AnomolyReassigned = () => {
|
|||
) {
|
||||
return {
|
||||
attendence_serial_no,
|
||||
student_slno,
|
||||
answer_booklet_sno,
|
||||
exam_centre_code,
|
||||
exam_centre,
|
||||
student_name,
|
||||
|
|
@ -101,7 +101,7 @@ const AnomolyReassigned = () => {
|
|||
tmpData.push(
|
||||
createData(
|
||||
data.attendence_serial_no,
|
||||
data.student_slno,
|
||||
data.answer_booklet_sno,
|
||||
data.exam_centre_code,
|
||||
data.exam_centre,
|
||||
data.student_name,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
// import React, { useState } from "react";
|
||||
// import {
|
||||
// DesktopOutlined,
|
||||
// FileOutlined,
|
||||
// PieChartOutlined,
|
||||
// TeamOutlined,
|
||||
// UserOutlined,
|
||||
// } from "@ant-design/icons";
|
||||
// import { Breadcrumb, Layout, Menu, Typography, theme } from "antd";
|
||||
// import BookletInput from "./BookletInput";
|
||||
// import { Box, Button } from "@mui/material";
|
||||
// import { useEffect } from "react";
|
||||
// import TextField from "@mui/material/TextField";
|
||||
// import EditButton from "./EditButton";
|
||||
// import { width } from "@mui/system";
|
||||
// import { ToastContainer, toast } from "react-toastify";
|
||||
// import "react-toastify/dist/ReactToastify.css";
|
||||
// import { TablePagination } from "@mui/base/TablePagination";
|
||||
// import TableComponent from "./TableComponent";
|
||||
// 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 { updateAttendenceAnomolyData } from "../redux/actions/actions";
|
||||
// import { useDispatch, useSelector } from "react-redux";
|
||||
// import SystemNumberDialog from "./SystemNumberDialog";
|
||||
|
||||
// const { Header, Content, Footer, Sider } = Layout;
|
||||
// function getItem(label, key, icon, children) {
|
||||
// return {
|
||||
// key,
|
||||
// icon,
|
||||
// children,
|
||||
// label,
|
||||
// };
|
||||
// }
|
||||
|
||||
|
||||
// const items = [getItem("Reassigned Booklet No", "1", <PieChartOutlined />)];
|
||||
|
||||
// const AnomolyReassigned = () => {
|
||||
// const [collapsed, setCollapsed] = useState(false);
|
||||
// const [anomolyData, setAnomolyData] = useState([]);
|
||||
// const [filteredAnomolyData,setFilterAnomolyData] = useState([])
|
||||
// const [tableRowData, setTableRowData] = useState([]);
|
||||
// const [isLoading, setIsLoading] = useState(false);
|
||||
// const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||
// const [distinctExamCentreCodes,setDistinctExamCentreCodes] = useState([])
|
||||
// const dispatch = useDispatch();
|
||||
// const reduxAnomolyData = useSelector((state) => state.attendenceAnomolyData);
|
||||
// const [filterSelectedExamCentreCode,setFilterSelectedExamCentreCode] = useState("")
|
||||
// const [showSystemNoContainer, setShowSystemNoContainer] = useState(false);
|
||||
|
||||
// // Log Redux store state
|
||||
// console.log("Redux store state after dispatch:", reduxAnomolyData);
|
||||
// const reduxSystemNo = useSelector((state) => state?.systemNumber);
|
||||
// console.log("redux system no: ", reduxSystemNo)
|
||||
|
||||
// useEffect(()=>{
|
||||
// if(!reduxSystemNo){
|
||||
// setShowSystemNoContainer(true);
|
||||
// }else{
|
||||
// fetchAnomalyData(reduxSystemNo)
|
||||
// }
|
||||
|
||||
// },[])
|
||||
|
||||
// useEffect(() => {
|
||||
// const handleResize = () => {
|
||||
// setWindowWidth(window.innerWidth);
|
||||
// };
|
||||
|
||||
// window.addEventListener("resize", handleResize);
|
||||
|
||||
// return () => {
|
||||
// window.removeEventListener("resize", handleResize);
|
||||
// };
|
||||
// }, []);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (windowWidth < 800) {
|
||||
// setCollapsed(true);
|
||||
// }
|
||||
// if (windowWidth > 800) {
|
||||
// setCollapsed(false);
|
||||
// }
|
||||
// }, [windowWidth]);
|
||||
|
||||
// const navigate = useNavigate();
|
||||
// function createData(
|
||||
// attendence_serial_no,
|
||||
// answer_booklet_sno,
|
||||
// exam_centre_code,
|
||||
// exam_centre,
|
||||
// student_name,
|
||||
// register_number,
|
||||
// reassigned_serial_no
|
||||
// ) {
|
||||
// return {
|
||||
// attendence_serial_no,
|
||||
// answer_booklet_sno,
|
||||
// exam_centre_code,
|
||||
// exam_centre,
|
||||
// student_name,
|
||||
// register_number,
|
||||
// reassigned_serial_no,
|
||||
// };
|
||||
// }
|
||||
|
||||
|
||||
// const fetchAnomalyData = (reduxSystemNo) => {
|
||||
// console.log("Fetching.......");
|
||||
// setIsLoading(true);
|
||||
// fetch(
|
||||
// `${
|
||||
// import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
// }/fetchAnamolyAttendenceData?sysNo=${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") {
|
||||
// setAnomolyData(responseData?.data);
|
||||
// const tmpExamCentreCodes = [];
|
||||
// const distinctExamCentreCodesSet = new Set(distinctExamCentreCodes);
|
||||
|
||||
// for (var data of responseData?.data) {
|
||||
// if (!distinctExamCentreCodesSet.has(data.exam_centre_code)) {
|
||||
// distinctExamCentreCodesSet.add(data.exam_centre_code);
|
||||
// tmpExamCentreCodes.push(data.exam_centre_code);
|
||||
// }
|
||||
// setFilterAnomolyData([...tmpExamCentreCodes])
|
||||
// }
|
||||
|
||||
|
||||
// setDistinctExamCentreCodes([...distinctExamCentreCodesSet]);
|
||||
// console.log("Tmp exam centre code: ", tmpExamCentreCodes);
|
||||
|
||||
// // console.log("Data to be stored in store : ", responseData?.data);
|
||||
// dispatch(updateAttendenceAnomolyData(responseData?.data));
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// console.error("Error fetching data: ", error);
|
||||
// setIsLoading(false);
|
||||
// });
|
||||
// };
|
||||
|
||||
|
||||
// const handleSystemNoChange = () => {
|
||||
// console.log("System No Change is called");
|
||||
// setShowSystemNoContainer(true);
|
||||
// };
|
||||
|
||||
// useEffect(()=>{
|
||||
// console.log("redux sys no: ", reduxSystemNo)
|
||||
// },[])
|
||||
|
||||
// const {
|
||||
// token: { colorBgContainer, borderRadiusLG },
|
||||
// } = theme.useToken();
|
||||
|
||||
// return (
|
||||
// <Layout
|
||||
// style={{
|
||||
// minHeight: "100vh",
|
||||
// }}
|
||||
// >
|
||||
// <ToastContainer />
|
||||
// <Sider
|
||||
// collapsible
|
||||
// collapsed={collapsed}
|
||||
// onCollapse={(value) => setCollapsed(value)}
|
||||
// >
|
||||
// <div className="demo-logo-vertical" />
|
||||
// <Menu
|
||||
// theme="dark"
|
||||
// defaultSelectedKeys={["1"]}
|
||||
// mode="inline"
|
||||
// items={items}
|
||||
// />
|
||||
// </Sider>
|
||||
|
||||
// <Layout>
|
||||
// <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">
|
||||
// <Box className="d-flex justify-content-between gap-md-4 gap-1 align-items-center">
|
||||
// {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" }}
|
||||
// onClick={handleSystemNoChange}
|
||||
// >
|
||||
// <b>System No : </b> {reduxSystemNo}
|
||||
// </Box>
|
||||
// )}
|
||||
// </Box>
|
||||
// <Button
|
||||
// className="bg-primary p-1 text-light"
|
||||
// onClick={() => {
|
||||
// navigate("/anomoly/reassigned/stats");
|
||||
// }}
|
||||
// >
|
||||
// <QueryStatsIcon />
|
||||
// </Button>
|
||||
// <Button
|
||||
// className="bg-primary p-1 text-light"
|
||||
// onClick={() => {
|
||||
// navigate("/");
|
||||
// }}
|
||||
// >
|
||||
// <HomeIcon />
|
||||
// </Button>
|
||||
// </Box>
|
||||
// </Box>
|
||||
// </Header>
|
||||
// <Content
|
||||
// style={{
|
||||
// margin: "16px 16px",
|
||||
// }}
|
||||
// >
|
||||
// <Box className="w-100 d-flex justify-content-between">
|
||||
// <Box className="w-100 d-flex justify-content-center">
|
||||
// {tableRowData.length > 0 && (
|
||||
// <TableComponent
|
||||
// filterSelectedExamCentreCode = {filterSelectedExamCentreCode}
|
||||
// setFilterSelectedExamCentreCode = {setFilterSelectedExamCentreCode}
|
||||
// rows={tableRowData}
|
||||
// type={"AnomolyReassigned"}
|
||||
// distinctExamCentreCodes = {distinctExamCentreCodes}
|
||||
// />
|
||||
// )}
|
||||
// {tableRowData.length == 0 && (
|
||||
// <Box className="w-100 d-flex justify-content-center py-2 align-items-center text-center">
|
||||
// <h6>No Data Found !!</h6>
|
||||
// </Box>
|
||||
// )}
|
||||
// </Box>
|
||||
// </Box>
|
||||
// </Content>
|
||||
// <Footer
|
||||
// style={{
|
||||
// textAlign: "center",
|
||||
// }}
|
||||
// >
|
||||
// exampaper.vidh.ai ©{new Date().getFullYear()}
|
||||
// </Footer>
|
||||
// </Layout>
|
||||
// {isLoading && <LoadingContainer loadingText={"Loading"} />}
|
||||
// {showSystemNoContainer && (
|
||||
// <SystemNumberDialog
|
||||
// setShowSystemNoContainer={setShowSystemNoContainer}
|
||||
// showSystemNoContainer={showSystemNoContainer}
|
||||
// />
|
||||
// )}
|
||||
// </Layout>
|
||||
|
||||
// );
|
||||
// };
|
||||
// export default AnomolyReassigned;
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
import React, { useState, useEffect } 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 { useSelector, useDispatch } from "react-redux";
|
||||
import {
|
||||
updatePartAanomolyData,
|
||||
updateSystemNo,
|
||||
} from "../redux/actions/actions";
|
||||
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";
|
||||
|
||||
const { Header, Content, Footer, Sider } = Layout;
|
||||
|
||||
const AntdesignLayout = ({ children }) => {
|
||||
const navigate = useNavigate();
|
||||
const {
|
||||
token: { colorBgContainer, borderRadiusLG },
|
||||
} = theme.useToken();
|
||||
return (
|
||||
<Layout
|
||||
style={{
|
||||
minHeight: "100vh",
|
||||
}}
|
||||
>
|
||||
<ToastContainer />
|
||||
<Layout>
|
||||
<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">
|
||||
{/* <Button
|
||||
className="bg-primary p-1 text-light"
|
||||
onClick={() => {
|
||||
navigate("/anomoly/reassigned/stats");
|
||||
}}
|
||||
>
|
||||
<QueryStatsIcon />
|
||||
</Button> */}
|
||||
<Box className="d-flex justify-content-between gap-md-4 gap-1 align-items-center">
|
||||
<Button
|
||||
className="bg-primary p-1 text-light rounded h-100"
|
||||
onClick={() => {
|
||||
navigate("/");
|
||||
}}
|
||||
>
|
||||
<HomeIcon />
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Header>
|
||||
<Content
|
||||
style={{
|
||||
margin: "16px 16px",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Content>
|
||||
<Box style={{ position: "fixed", bottom: "15px", left: "30px" }}>
|
||||
<Button
|
||||
className="bg-primary rounded-circle p-3"
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
<ArrowUpwardIcon className="text-white" />
|
||||
</Button>
|
||||
</Box>
|
||||
<Footer
|
||||
style={{
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
exampaper.vidh.ai ©{new Date().getFullYear()}
|
||||
</Footer>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default AntdesignLayout;
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Box, Button} from "@mui/material"
|
||||
import { ToastContainer } from "react-toastify";
|
||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||
import HomeIcon from "@mui/icons-material/Home";
|
||||
import LoadingContainer from "./LoadingContainer";
|
||||
import SystemNumberDialog from "./SystemNumberDialog";
|
||||
|
||||
import { Breadcrumb, Layout, Menu, Typography, theme } from "antd";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import TableComponent from "./TableComponent";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import TableComponentAdditionalSheet from "./TableComponentAdditionalSheet";
|
||||
const { Header, Content, Footer, Sider } = Layout;
|
||||
|
||||
function AttendanceAdditionalSheet() {
|
||||
const [tableRowData, setTableRowData] = useState([]);
|
||||
|
||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const [anomolyData, setAnomolyData] = useState([]);
|
||||
const [filteredAnomolyData,setFilterAnomolyData] = useState([])
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [distinctExamCentreCodes,setDistinctExamCentreCodes] = useState([])
|
||||
const dispatch = useDispatch()
|
||||
const reduxAnomolyData = useSelector((state) => state.attendenceAnomolyData);
|
||||
const [showSystemNoContainer, setShowSystemNoContainer] = useState(false);
|
||||
const [filterSelectedExamCentreCode,setFilterSelectedExamCentreCode] = useState("")
|
||||
const reduxSystemNo = useSelector((state) => state?.systemNumber);
|
||||
|
||||
useEffect(() => {
|
||||
if (!reduxSystemNo) {
|
||||
setShowSystemNoContainer(true);
|
||||
} else {
|
||||
|
||||
fetchAnomalyData(reduxSystemNo)
|
||||
|
||||
}
|
||||
},[])
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setWindowWidth(window.innerWidth);
|
||||
};
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (windowWidth < 800) {
|
||||
setCollapsed(true);
|
||||
}
|
||||
if (windowWidth > 800) {
|
||||
setCollapsed(false);
|
||||
}
|
||||
}, [windowWidth]);
|
||||
|
||||
|
||||
function createData(
|
||||
image_name,
|
||||
s3_image_path
|
||||
) {
|
||||
return {
|
||||
image_name,
|
||||
s3_image_path
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// useEffect(()=>{
|
||||
// const tmpData = [];
|
||||
// for (const data of anomolyData) {
|
||||
// tmpData.push(
|
||||
// createData(
|
||||
// data.image_name,
|
||||
// data.s3_image_path
|
||||
// // data.attendence_serial_no,
|
||||
// // data.answer_booklet_sno,
|
||||
// // data.exam_centre_code,
|
||||
// // data.exam_centre,
|
||||
// // data.student_name,
|
||||
// // data.register_number,
|
||||
// // data.reassigned_serial_no
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
// console.log("Tmp data is : ", tmpData);
|
||||
// if (tmpData.length > 0) {
|
||||
// setTableRowData(tmpData);
|
||||
// }
|
||||
// },[anomolyData])
|
||||
|
||||
const updateSystemReservationStatus = async (systemRecords) => {
|
||||
const payload = {
|
||||
systemRecords,
|
||||
sysNo:reduxSystemNo
|
||||
};
|
||||
try {
|
||||
fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/updateSystemReservationStatusAttendence`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((responseData) => {
|
||||
console.log("response from updation : ", responseData);
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error("Error in update system records : ", systemRecords);
|
||||
}
|
||||
};
|
||||
|
||||
function getRecordsBySystemId(records, systemId) {
|
||||
const new_data = [];
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
var count = i % 5;
|
||||
if (count === systemId - 1) {
|
||||
new_data.push(records[i]);
|
||||
}
|
||||
}
|
||||
return new_data;
|
||||
}
|
||||
|
||||
const fetchAnomalyData = (reduxSystemNo) => {
|
||||
console.log("Fetching.......");
|
||||
setIsLoading(true);
|
||||
fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/fetchAnamolyAttendenceAdditionalSheetData?sysNo=${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") {
|
||||
// setAnomolyData(responseData?.data);
|
||||
console.log("System record ====== ",responseData.systemRecord)
|
||||
var systemRecords = responseData?.data
|
||||
if(!responseData.systemRecord){
|
||||
systemRecords = getRecordsBySystemId(
|
||||
responseData?.data,
|
||||
reduxSystemNo
|
||||
);
|
||||
}
|
||||
updateSystemReservationStatus(systemRecords);
|
||||
console.log("System records : ", systemRecords);
|
||||
// if (searchParamsType === "old") {
|
||||
// localStorage.setItem(
|
||||
// "part-a-old-anomoly",
|
||||
// JSON.stringify(systemRecords)
|
||||
// );
|
||||
// } else if (searchParamsType !== "old") {
|
||||
// localStorage.setItem(
|
||||
// "part-a-anomoly",
|
||||
// JSON.stringify(systemRecords)
|
||||
// );
|
||||
// }
|
||||
setAnomolyData(systemRecords);
|
||||
// dispatch(updatePartAanomolyData(systemRecords));
|
||||
const tmpData = [];
|
||||
for (const data of systemRecords) {
|
||||
tmpData.push(
|
||||
createData(
|
||||
data.image_name,
|
||||
data.s3_image_path
|
||||
// data.attendence_serial_no,
|
||||
// data.answer_booklet_sno,
|
||||
// data.exam_centre_code,
|
||||
// data.exam_centre,
|
||||
// data.student_name,
|
||||
// data.register_number,
|
||||
// data.reassigned_serial_no
|
||||
)
|
||||
);
|
||||
}
|
||||
// console.log("Tmp data is : ", tmpData);
|
||||
if (tmpData.length > 0) {
|
||||
setTableRowData(tmpData);
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error fetching data: ", error);
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// useEffect(() => {
|
||||
// if (reduxAnomolyData.length > 0) {
|
||||
// console.log("Redux anomoly data found")
|
||||
// setAnomolyData(reduxAnomolyData)
|
||||
// } else {
|
||||
// console.log("Redux anomoly data not found")
|
||||
// fetchAnomalyData();
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
const tmpData = []
|
||||
for(var data in anomolyData){
|
||||
if(data?.exam_centre_code == filterSelectedExamCentreCode){
|
||||
tmpData.push(data)
|
||||
}
|
||||
}
|
||||
|
||||
},[filterSelectedExamCentreCode])
|
||||
|
||||
const handleSystemNoChange = () => {
|
||||
console.log("System No Change is called");
|
||||
setShowSystemNoContainer(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("System no container show status : ", showSystemNoContainer);
|
||||
}, [showSystemNoContainer]);
|
||||
|
||||
const {
|
||||
token: { colorBgContainer, borderRadiusLG },
|
||||
} = theme.useToken();
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
return (
|
||||
<Layout
|
||||
style={{
|
||||
minHeight: "100vh",
|
||||
}}
|
||||
>
|
||||
<ToastContainer />
|
||||
<Layout>
|
||||
<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" }}
|
||||
onClick={handleSystemNoChange}
|
||||
>
|
||||
<b>System No : </b> {reduxSystemNo}
|
||||
</Box>
|
||||
)}
|
||||
<Button
|
||||
className="bg-primary p-1 text-light"
|
||||
onClick={() => {
|
||||
navigate("/");
|
||||
}}
|
||||
>
|
||||
<HomeIcon />
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Header>
|
||||
|
||||
<Content
|
||||
style={{
|
||||
margin: "16px 16px",
|
||||
}}
|
||||
>
|
||||
<Box className="w-100 d-flex justify-content-between">
|
||||
<Box className="w-100 d-flex justify-content-center">
|
||||
{tableRowData.length > 0 && (
|
||||
<TableComponent
|
||||
filterSelectedExamCentreCode = {filterSelectedExamCentreCode}
|
||||
setFilterSelectedExamCentreCode = {setFilterSelectedExamCentreCode}
|
||||
rows={tableRowData}
|
||||
type={"AdditionalSheet"}
|
||||
distinctExamCentreCodes = {distinctExamCentreCodes}
|
||||
/>
|
||||
)}
|
||||
{tableRowData.length == 0 && (
|
||||
<Box className="w-100 d-flex justify-content-center py-2 align-items-center text-center">
|
||||
<h6>No Data Found !!</h6>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Content>
|
||||
|
||||
|
||||
</Layout>
|
||||
{isLoading && <LoadingContainer loadingText={"Loading"} />}
|
||||
{showSystemNoContainer && (
|
||||
<SystemNumberDialog
|
||||
setShowSystemNoContainer={setShowSystemNoContainer}
|
||||
showSystemNoContainer={showSystemNoContainer}
|
||||
/>
|
||||
)}
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default AttendanceAdditionalSheet;
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
import React, { useState } from "react";
|
||||
import {
|
||||
DesktopOutlined,
|
||||
FileOutlined,
|
||||
PieChartOutlined,
|
||||
TeamOutlined,
|
||||
UserOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Breadcrumb, Layout, Menu, Typography, theme } from "antd";
|
||||
import BookletInput from "./BookletInput";
|
||||
import { Box, Button } from "@mui/material";
|
||||
import { useEffect } from "react";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import EditButton from "./EditButton";
|
||||
import { width } from "@mui/system";
|
||||
import { ToastContainer, toast } from "react-toastify";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { TablePagination } from "@mui/base/TablePagination";
|
||||
import TableComponent from "./TableComponent";
|
||||
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 { updateAttendenceAnomolyData } from "../redux/actions/actions";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
const { Header, Content, Footer, Sider } = Layout;
|
||||
function getItem(label, key, icon, children) {
|
||||
return {
|
||||
key,
|
||||
icon,
|
||||
children,
|
||||
label,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const items = [getItem("Reassigned Booklet No", "1", <PieChartOutlined />)];
|
||||
|
||||
const AttendenceAdditionalRecord = () => {
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const [anomolyData, setAnomolyData] = useState([]);
|
||||
const [filteredAnomolyData,setFilterAnomolyData] = useState([])
|
||||
const [tableRowData, setTableRowData] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||
const [distinctExamCentreCodes,setDistinctExamCentreCodes] = useState([])
|
||||
const dispatch = useDispatch();
|
||||
const reduxAnomolyData = useSelector((state) => state.attendenceAnomolyData);
|
||||
const [filterSelectedExamCentreCode,setFilterSelectedExamCentreCode] = useState("")
|
||||
|
||||
// Log Redux store state
|
||||
console.log("Redux store state after dispatch:", reduxAnomolyData);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setWindowWidth(window.innerWidth);
|
||||
};
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (windowWidth < 800) {
|
||||
setCollapsed(true);
|
||||
}
|
||||
if (windowWidth > 800) {
|
||||
setCollapsed(false);
|
||||
}
|
||||
}, [windowWidth]);
|
||||
|
||||
const navigate = useNavigate();
|
||||
function createData(
|
||||
qrcode,
|
||||
coverA,
|
||||
coverB,
|
||||
subject_code,
|
||||
total_students,
|
||||
total_present,
|
||||
total_absent
|
||||
) {
|
||||
return {
|
||||
qrcode,
|
||||
coverA,
|
||||
coverB,
|
||||
subject_code,
|
||||
total_students,
|
||||
total_present,
|
||||
total_absent
|
||||
};
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
const tmpData = [];
|
||||
for (const data of anomolyData) {
|
||||
tmpData.push(
|
||||
createData(
|
||||
data.qrcode,
|
||||
data.coverA,
|
||||
data.coverB,
|
||||
data.subject_code,
|
||||
data.total_students,
|
||||
data.total_present,
|
||||
data.total_absent
|
||||
)
|
||||
);
|
||||
}
|
||||
console.log("Tmp data is : ", tmpData);
|
||||
if (tmpData.length > 0) {
|
||||
setTableRowData(tmpData);
|
||||
}
|
||||
},[anomolyData])
|
||||
|
||||
const fetchAnomalyData = () => {
|
||||
console.log("Fetching.......");
|
||||
setIsLoading(true);
|
||||
fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/fetchAnamolyAttendencAdditionalRecordeData`,
|
||||
{
|
||||
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") {
|
||||
setAnomolyData(responseData?.data);
|
||||
const tmpExamCentreCodes = [];
|
||||
const distinctExamCentreCodesSet = new Set(distinctExamCentreCodes);
|
||||
|
||||
for (var data of responseData?.data) {
|
||||
if (!distinctExamCentreCodesSet.has(data.exam_centre_code)) {
|
||||
distinctExamCentreCodesSet.add(data.exam_centre_code);
|
||||
tmpExamCentreCodes.push(data.exam_centre_code);
|
||||
}
|
||||
setFilterAnomolyData([...tmpExamCentreCodes])
|
||||
}
|
||||
|
||||
|
||||
setDistinctExamCentreCodes([...distinctExamCentreCodesSet]);
|
||||
console.log("Tmp exam centre code: ", tmpExamCentreCodes);
|
||||
|
||||
// console.log("Data to be stored in store : ", responseData?.data);
|
||||
//dispatch(updateAttendenceAnomolyData(responseData?.data));
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error fetching data: ", error);
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (reduxAnomolyData.length > 0) {
|
||||
console.log("Redux anomoly data found")
|
||||
setAnomolyData(reduxAnomolyData)
|
||||
} else {
|
||||
console.log("Redux anomoly data not found")
|
||||
fetchAnomalyData();
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
const tmpData = []
|
||||
for(var data in anomolyData){
|
||||
if(data?.exam_centre_code == filterSelectedExamCentreCode){
|
||||
tmpData.push(data)
|
||||
}
|
||||
}
|
||||
|
||||
},[filterSelectedExamCentreCode])
|
||||
|
||||
|
||||
|
||||
const {
|
||||
token: { colorBgContainer, borderRadiusLG },
|
||||
} = theme.useToken();
|
||||
|
||||
return (
|
||||
<Layout
|
||||
style={{
|
||||
minHeight: "100vh",
|
||||
}}
|
||||
>
|
||||
<ToastContainer />
|
||||
<Sider
|
||||
collapsible
|
||||
collapsed={collapsed}
|
||||
onCollapse={(value) => setCollapsed(value)}
|
||||
>
|
||||
<div className="demo-logo-vertical" />
|
||||
<Menu
|
||||
theme="dark"
|
||||
defaultSelectedKeys={["1"]}
|
||||
mode="inline"
|
||||
items={items}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<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">
|
||||
<Button
|
||||
className="bg-primary p-1 text-light"
|
||||
onClick={() => {
|
||||
navigate("/anomoly/reassigned/stats");
|
||||
}}
|
||||
>
|
||||
<QueryStatsIcon />
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary p-1 text-light"
|
||||
onClick={() => {
|
||||
navigate("/");
|
||||
}}
|
||||
>
|
||||
<HomeIcon />
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Header>
|
||||
<Content
|
||||
style={{
|
||||
margin: "16px 16px",
|
||||
}}
|
||||
>
|
||||
<Box className="w-100 d-flex justify-content-between">
|
||||
<Box className="w-100 d-flex justify-content-center">
|
||||
{tableRowData.length > 0 && (
|
||||
<TableComponent
|
||||
filterSelectedExamCentreCode = {filterSelectedExamCentreCode}
|
||||
setFilterSelectedExamCentreCode = {setFilterSelectedExamCentreCode}
|
||||
rows={tableRowData}
|
||||
type={"AttendenceAdditionalRecord"}
|
||||
distinctExamCentreCodes = {distinctExamCentreCodes}
|
||||
/>
|
||||
)}
|
||||
{tableRowData.length == 0 && (
|
||||
<Box className="w-100 d-flex justify-content-center py-2 align-items-center text-center">
|
||||
<h6>No Data Found !!</h6>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Content>
|
||||
<Footer
|
||||
style={{
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
exampaper.vidh.ai ©{new Date().getFullYear()}
|
||||
</Footer>
|
||||
</Layout>
|
||||
{isLoading && <LoadingContainer loadingText={"Loading"} />}
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
export default AttendenceAdditionalRecord;
|
||||
|
|
@ -0,0 +1,708 @@
|
|||
import React, { useState } from "react";
|
||||
import {
|
||||
DesktopOutlined,
|
||||
FileOutlined,
|
||||
PieChartOutlined,
|
||||
TeamOutlined,
|
||||
UserOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Breadcrumb, Layout, Menu, Typography, theme } from "antd";
|
||||
import BookletInput from "./BookletInput";
|
||||
import { Box, Button } from "@mui/material";
|
||||
import { useEffect } from "react";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import EditButton from "./EditButton";
|
||||
import { width } from "@mui/system";
|
||||
import { ToastContainer, toast } from "react-toastify";
|
||||
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 { useDispatch, useSelector } from "react-redux";
|
||||
import { updateAttendenceAnomolyData } from "../redux/actions/actions";
|
||||
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
|
||||
import RotateRightIcon from "@mui/icons-material/RotateRight";
|
||||
|
||||
const { Header, Content, Footer, Sider } = Layout;
|
||||
function getItem(label, key, icon, children) {
|
||||
return {
|
||||
key,
|
||||
icon,
|
||||
children,
|
||||
label,
|
||||
};
|
||||
}
|
||||
|
||||
const items = [getItem("Reassigned Booklet No", "1", <PieChartOutlined />)];
|
||||
|
||||
const AttendenceAdditionalRecordCorrection = () => {
|
||||
console.log("Checking1 ...");
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const [bookletInput, setBookletInput] = useState(null);
|
||||
const [dataFetched, setDataFetched] = useState(false);
|
||||
const [studentData, setStudentData] = useState(null);
|
||||
const [updateReassigned, setUpdateReassigned] = useState(false);
|
||||
const [reasssingedSno, setReassignedSno] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [registerNumber, setRegisterNumber] = useState(null);
|
||||
const [backgroundPosition, setBackgroundPosition] = useState("0% 0%");
|
||||
const [zoomed, setZoomed] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const [scaleWidthValue, setScaleWidthValue] = useState(80);
|
||||
const [rotateValue, setRotateValue] = useState(0);
|
||||
const [attendenceQRcode,setAttendenceQRcode] = useState(null)
|
||||
|
||||
// const reduxAnomolyData = useSelector((state) => state.attendenceAnomolyData);
|
||||
// console.log("Anomoly Data is : ", reduxAnomolyData);
|
||||
const [anomolyData, setAnomolyData] = useState([]);
|
||||
|
||||
const handleMouseMove = (e) => {
|
||||
const { left, top, width, height } = e.target.getBoundingClientRect();
|
||||
const x = ((e.pageX - left) / width) * 100;
|
||||
const y = ((e.pageY - top) / height) * 100;
|
||||
setBackgroundPosition(`${x}% ${y}%`);
|
||||
setZoomed(true);
|
||||
};
|
||||
|
||||
const navigate = useNavigate();
|
||||
let [searchParams, setSearchParams] = useSearchParams();
|
||||
const searchParamsqrcode = searchParams.get("qrcode");
|
||||
// console.log("Serach parmas sno : ", searchParamsBookletSerialNo);
|
||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setWindowWidth(window.innerWidth);
|
||||
};
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (windowWidth < 800) {
|
||||
setCollapsed(true);
|
||||
}
|
||||
if (windowWidth > 800) {
|
||||
setCollapsed(false);
|
||||
}
|
||||
}, [windowWidth]);
|
||||
|
||||
useEffect(() => {
|
||||
if (searchParamsqrcode) {
|
||||
setAttendenceQRcode(searchParamsqrcode);
|
||||
}
|
||||
}, [searchParamsqrcode]);
|
||||
|
||||
useEffect(() => {
|
||||
submitQrInputData();
|
||||
}, [attendenceQRcode]);
|
||||
|
||||
const {
|
||||
token: { colorBgContainer, borderRadiusLG },
|
||||
} = theme.useToken();
|
||||
|
||||
// useEffect(() => {
|
||||
// if (reduxAnomolyData.length === 0) {
|
||||
// fetchAnomalyData();
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
const fetchAnomalyData = () => {
|
||||
console.log("Fetching.......");
|
||||
setIsLoading(true);
|
||||
fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/fetchAnamolyAttendenceData`,
|
||||
{
|
||||
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") {
|
||||
setAnomolyData(responseData?.data);
|
||||
console.log("Data to be stored in store : ", responseData?.data);
|
||||
// dispatch(updateAttendenceAnomolyData(responseData?.data));
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error fetching data: ", error);
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const submitQrInputData = async () => {
|
||||
setIsLoading(true);
|
||||
setStudentData(null);
|
||||
if (!bookletInput) {
|
||||
console.log("Returning");
|
||||
}
|
||||
const payload = {
|
||||
attendenceQRcode,
|
||||
};
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchAttendenceAdditionalqrData`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
const responseData = await response.json();
|
||||
console.log("Response Data is : ", responseData);
|
||||
setDataFetched(true);
|
||||
setIsLoading(false);
|
||||
if (responseData.status === "success") {
|
||||
console.log("Into top if");
|
||||
if (!responseData.data) {
|
||||
setStudentData(null);
|
||||
}
|
||||
if (responseData.data) {
|
||||
setStudentData(responseData.data[0]);
|
||||
const student_data = responseData.data[0];
|
||||
setRegisterNumber(student_data?.register_number);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const url = `https://docs.exampaper.vidh.ai/${studentData?.s3_path}`;
|
||||
// console.log("Url is : ", url);
|
||||
const figureStyle = {
|
||||
backgroundImage: `url(${url})`,
|
||||
backgroundPosition: zoomed ? backgroundPosition : "center",
|
||||
backgroundSize: zoomed ? "200%" : "cover",
|
||||
height: "100%", // Adjust the height as needed
|
||||
width: "60%", // Adjust the width as needed
|
||||
border: "1px solid #ddd",
|
||||
overflow: "hidden",
|
||||
};
|
||||
|
||||
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)`;
|
||||
}
|
||||
};
|
||||
|
||||
const ImageStyle = {
|
||||
// transform: `scale(${scaleValue})`,
|
||||
transformOrigin: "left", // Adjust the zoom origin as needed
|
||||
transition: "transform 0.2s ease-in-out",
|
||||
};
|
||||
|
||||
const containerStyle = {
|
||||
width: "auto", // Set the width and height as needed
|
||||
maxHeight: "90%",
|
||||
overflowX: "scroll",
|
||||
position: "relative",
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
setBackgroundPosition("0% 0%");
|
||||
setZoomed(false);
|
||||
};
|
||||
|
||||
const updateReassignedSno = async () => {
|
||||
setIsLoading(true);
|
||||
// if(reduxAnomolyData.length === 0){
|
||||
// console.log("Redux anomoly data length is 0.......")
|
||||
// fetchAnomalyData()
|
||||
// }
|
||||
console.log("Reassgined Sno : ", reasssingedSno);
|
||||
const payload = {
|
||||
bookletInput,
|
||||
reasssingedSno,
|
||||
registerNumber,
|
||||
};
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/updateReassingedSno`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
const responseData = await response.json();
|
||||
setIsLoading(false);
|
||||
setReassignedSno(null);
|
||||
if (responseData.status === "success" && responseData?.status_code == 200) {
|
||||
console.log("Updation success");
|
||||
toast.success("Record Updated Successfully !!");
|
||||
var index = 0
|
||||
var RecordIndex = 0
|
||||
const filteredData = reduxAnomolyData.filter((data) => {
|
||||
if (data?.student_slno === searchParamsBookletSerialNo) {
|
||||
RecordIndex = index
|
||||
console.log("data matched : ", data);
|
||||
return false; // Return false to remove the matched item
|
||||
}
|
||||
index += 1
|
||||
return true; // Keep the unmatched items
|
||||
});
|
||||
|
||||
console.log("Filtered Data: ", filteredData);
|
||||
// dispatch(updateAttendenceAnomolyData(filteredData));
|
||||
if (filteredData.length > 0) {
|
||||
navigate(
|
||||
`/anomoly/reassigned/booklet?sno=${filteredData[RecordIndex].student_slno}`
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
responseData.status === "success" &&
|
||||
responseData?.status_code == 405
|
||||
) {
|
||||
console.log("Updation not allowed");
|
||||
toast.error("Reassigned Serial No is Invalid !!");
|
||||
}
|
||||
};
|
||||
|
||||
const markAsAssigned = async () => {
|
||||
setIsLoading(true);
|
||||
const payload = { bookletInput };
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/markAsAssigned`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
const responseData = await response.json();
|
||||
setIsLoading(false);
|
||||
if (responseData.status === "success") {
|
||||
toast.success("Record Updated Successfully !!");
|
||||
var index = 0
|
||||
var RecordIndex = 0
|
||||
const filteredData = reduxAnomolyData.filter((data) => {
|
||||
if (data?.student_slno === searchParamsBookletSerialNo) {
|
||||
RecordIndex = index
|
||||
console.log("data matched : ", data);
|
||||
return false; // Return false to remove the matched item
|
||||
}
|
||||
index += 1
|
||||
return true; // Keep the unmatched items
|
||||
});
|
||||
|
||||
console.log("Filtered Data: ", filteredData);
|
||||
// dispatch(updateAttendenceAnomolyData(filteredData));
|
||||
if (filteredData.length > 0) {
|
||||
navigate(
|
||||
`/anomoly/reassigned/booklet?sno=${filteredData[RecordIndex].student_slno}`
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout
|
||||
style={{
|
||||
minHeight: "100vh",
|
||||
}}
|
||||
>
|
||||
<ToastContainer />
|
||||
<Sider
|
||||
collapsible
|
||||
collapsed={collapsed}
|
||||
onCollapse={(value) => setCollapsed(value)}
|
||||
>
|
||||
<div className="demo-logo-vertical" />
|
||||
<Menu
|
||||
theme="dark"
|
||||
defaultSelectedKeys={["1"]}
|
||||
mode="inline"
|
||||
items={items}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<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">
|
||||
<Button
|
||||
className="bg-primary p-1 text-light"
|
||||
onClick={() => {
|
||||
navigate("/anomoly/reassigned/stats");
|
||||
}}
|
||||
>
|
||||
<QueryStatsIcon />
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary p-1 text-light"
|
||||
onClick={() => {
|
||||
navigate("/");
|
||||
}}
|
||||
>
|
||||
<HomeIcon />
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
{/* <Box>Reassigned Booklet Serial Manual Updation :</Box> */}
|
||||
</Header>
|
||||
<Content
|
||||
style={{
|
||||
margin: "16px 16px",
|
||||
}}
|
||||
>
|
||||
{/* <Breadcrumb
|
||||
style={{
|
||||
margin: "16px 0",
|
||||
}}
|
||||
>
|
||||
<Breadcrumb.Item>User</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>Bill</Breadcrumb.Item>
|
||||
</Breadcrumb> */}
|
||||
{/* <div
|
||||
style={{
|
||||
padding: 24,
|
||||
minHeight: 360,
|
||||
background: colorBgContainer,
|
||||
borderRadius: borderRadiusLG,
|
||||
}}
|
||||
>
|
||||
Bill is a cat.
|
||||
</div> */}
|
||||
<Box className="w-100 d-flex flex-column flex-md-row justify-content-between">
|
||||
<Box className="w-25 d-none d-md-flex flex-column">
|
||||
<Box className="d-flex justify-content-between">
|
||||
{/* <BookletInput
|
||||
className="d-flex flex-1"
|
||||
setBookletInput={setBookletInput}
|
||||
bookletInput={bookletInput}
|
||||
setDataFetched={setDataFetched}
|
||||
/> */}
|
||||
|
||||
{/* <Button
|
||||
className="px-md-5 px-2 mx-1 mx-md-2 text-light bg-primary"
|
||||
onClick={submitBookletInput}
|
||||
>
|
||||
Submit
|
||||
</Button> */}
|
||||
</Box>
|
||||
{/* {!isLoading && !studentData && (
|
||||
<Box className="w-100 py-5">
|
||||
<h6>Invalid Booklet Serial No !!</h6>
|
||||
</Box>
|
||||
)} */}
|
||||
{studentData && (
|
||||
<>
|
||||
<Box>
|
||||
<Box className="d-flex justify-content-start px-2 py-3">
|
||||
<h6>
|
||||
<u>Booklet Info:</u>
|
||||
</h6>
|
||||
</Box>
|
||||
|
||||
<Box className="px-2">
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="student-name-input" className="h6">
|
||||
<u>Booklet Serial No:</u>
|
||||
</label>
|
||||
<h5>{bookletInput}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="student-name-input" className="h6">
|
||||
<u>Student Name:</u>
|
||||
</label>
|
||||
<h5>{studentData?.student_name}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="exam-centre-code-input" className="h6">
|
||||
<u>Exam Center Code:</u>
|
||||
</label>
|
||||
<h5>{studentData?.exam_centre_code}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="exam-centre-input" className="h6">
|
||||
<u>Exam Centre:</u>
|
||||
</label>
|
||||
<h5>{studentData.exam_centre}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="exam-date-input" className="h6">
|
||||
<u>Exam Date:</u>
|
||||
</label>
|
||||
<h5>{studentData?.exam_date}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="reassigned-serial-no-input">
|
||||
<u>Reassigned Serial No:</u>
|
||||
</label>
|
||||
<Box className="d-flex justify-content-between w-100">
|
||||
<TextField
|
||||
id="reassigned-serial-no-input"
|
||||
className="w-100"
|
||||
value={studentData.reassigned_serial_no}
|
||||
placeholder={`Please enter the SNo.${studentData?.rownumber} Answer Booklet No`}
|
||||
autoComplete="off"
|
||||
onChange={(e) => {
|
||||
setReassignedSno(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box className="py-2 d-flex justify-content-start flex-column gap-2">
|
||||
<Button
|
||||
className="text-light bg-primary p-3 w-100"
|
||||
disabled={!reasssingedSno}
|
||||
onClick={updateReassignedSno}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
<Button
|
||||
className="text-light bg-primary p-3 w-100"
|
||||
onClick={markAsAssigned}
|
||||
>
|
||||
Mark As Assigned
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
<Box className="w-md-25 d-flex d-md-none flex-column">
|
||||
{/* {!isLoading && !studentData && (
|
||||
<Box className="w-100 py-5">
|
||||
<h6>Invalid Booklet Serial No !!</h6>
|
||||
</Box>
|
||||
)} */}
|
||||
{studentData && (
|
||||
<>
|
||||
<Box>
|
||||
<Box className="d-flex justify-content-start px-2 py-3">
|
||||
<h6>
|
||||
<u>Booklet Info:</u>
|
||||
</h6>
|
||||
</Box>
|
||||
|
||||
<Box className="px-2">
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="student-name-input" className="h6">
|
||||
<u>Booklet Serial No:</u>
|
||||
</label>
|
||||
<h5>{bookletInput}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="student-name-input" className="h6">
|
||||
<u>Student Name:</u>
|
||||
</label>
|
||||
<h5>{studentData?.student_name}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="exam-centre-code-input" className="h6">
|
||||
<u>Exam Center Code:</u>
|
||||
</label>
|
||||
<h5>{studentData?.exam_centre_code}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="exam-centre-input" className="h6">
|
||||
<u>Exam Centre:</u>
|
||||
</label>
|
||||
<h5>{studentData.exam_centre}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="exam-date-input" className="h6">
|
||||
<u>Exam Date:</u>
|
||||
</label>
|
||||
<h5>{studentData?.exam_date}</h5>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="reassigned-serial-no-input">
|
||||
<u>Reassigned Serial No:</u>
|
||||
</label>
|
||||
<Box className="d-flex justify-content-between w-100">
|
||||
<TextField
|
||||
id="reassigned-serial-no-input"
|
||||
className="w-100"
|
||||
value={studentData.reassigned_serial_no}
|
||||
placeholder={`Please enter the SNo.${studentData?.rownumber} Answer Booklet No`}
|
||||
autoComplete="off"
|
||||
onChange={(e) => {
|
||||
setReassignedSno(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box className="py-2 d-flex justify-content-start flex-column gap-2">
|
||||
<Button
|
||||
className="text-light bg-primary p-3 w-100"
|
||||
disabled={!reasssingedSno}
|
||||
onClick={updateReassignedSno}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
<Button
|
||||
className="text-light bg-primary p-3 w-100"
|
||||
onClick={markAsAssigned}
|
||||
>
|
||||
Mark As Assigned
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
className="w-75 d-none d-md-block"
|
||||
style={{ height: "800px", overflow: "auto" }}
|
||||
>
|
||||
{studentData && (
|
||||
<>
|
||||
<Box className="py-2">
|
||||
<Button
|
||||
className="bg-primary text-light p-3 mx-1"
|
||||
onClick={ZoomInImage}
|
||||
>
|
||||
ZoomIn
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-light p-3 mx-1"
|
||||
onClick={ZoomOutImage}
|
||||
>
|
||||
ZoomOut
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-light p-3 mx-1"
|
||||
onClick={RotateImageLeft}
|
||||
>
|
||||
<RotateLeftIcon />
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-light p-3 mx-1"
|
||||
onClick={RotateImageRight}
|
||||
>
|
||||
<RotateRightIcon />
|
||||
</Button>
|
||||
</Box>
|
||||
<img
|
||||
className="scanned-img"
|
||||
src={`https://docs.exampaper.vidh.ai/${studentData?.s3_image_path}`}
|
||||
width={`${scaleWidthValue}%`}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
<Box className="w-100 d-md-none overflow-auto">
|
||||
{studentData && (
|
||||
<>
|
||||
<Box className="py-2">
|
||||
<Button
|
||||
className="bg-primary text-light p-3 mx-1"
|
||||
onClick={ZoomInImage}
|
||||
>
|
||||
ZoomIn
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-light p-3 mx-1"
|
||||
onClick={ZoomOutImage}
|
||||
>
|
||||
ZoomOut
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-light p-3 mx-1"
|
||||
onClick={RotateImageLeft}
|
||||
>
|
||||
<RotateLeftIcon />
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-light p-3 mx-1"
|
||||
onClick={RotateImageRight}
|
||||
>
|
||||
<RotateRightIcon />
|
||||
</Button>
|
||||
</Box>
|
||||
<img
|
||||
className="scanned-img"
|
||||
src={`https://docs.exampaper.vidh.ai/${studentData.s3_path}`}
|
||||
width={`${scaleWidthValue}%`}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Content>
|
||||
<Footer
|
||||
style={{
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
exampaper.vidh.ai ©{new Date().getFullYear()}
|
||||
</Footer>
|
||||
</Layout>
|
||||
{isLoading && <LoadingContainer loadingText={"Fetching"} />}
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
export default AttendenceAdditionalRecordCorrection;
|
||||
|
|
@ -80,7 +80,7 @@ const AttendenceCorrection = () => {
|
|||
const navigate = useNavigate();
|
||||
let [searchParams, setSearchParams] = useSearchParams();
|
||||
const searchParamsBookletSerialNo = searchParams.get("sno");
|
||||
// console.log("Serach parmas sno : ", searchParamsBookletSerialNo);
|
||||
console.log("Serach parmas sno : ", searchParamsBookletSerialNo);
|
||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,181 @@
|
|||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Html5QrcodeScanner } from "html5-qrcode";
|
||||
import { Box, Button } from "@mui/material";
|
||||
import LoadingContainer from "./LoadingContainer";
|
||||
|
||||
const BarcodeScanner = () => {
|
||||
const [scanResult, setScanResult] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [barcodeInfo, setBarcodeInfo] = useState([]);
|
||||
const [marksData, setMarksData] = useState([]);
|
||||
const scannerRef = useRef(null); // Use ref to store the scanner instance
|
||||
|
||||
useEffect(() => {
|
||||
scannerRef.current = new Html5QrcodeScanner("reader", {
|
||||
qrbox: {
|
||||
width: 250,
|
||||
height: 250,
|
||||
},
|
||||
fps: 5,
|
||||
});
|
||||
|
||||
const fetchBarcodeData = () => {
|
||||
if(!scanResult){
|
||||
return
|
||||
}
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const payload = {
|
||||
qrcodeValue: scanResult,
|
||||
};
|
||||
fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/fetchQrcodeScannedInfo`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((responseData) => {
|
||||
setIsLoading(false);
|
||||
if (responseData.status === "success") {
|
||||
setBarcodeInfo(responseData.results);
|
||||
setMarksData(responseData?.marks);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
window.fetchBarcodeData = fetchBarcodeData;
|
||||
|
||||
const success = (result) => {
|
||||
// scannerRef.current.clear();
|
||||
const readerEle = document.getElementById("reader");
|
||||
if (readerEle) {
|
||||
readerEle.style.visibility = "hidden";
|
||||
}
|
||||
setScanResult(result);
|
||||
};
|
||||
window.success = success;
|
||||
|
||||
const error = (err) => {
|
||||
console.log("Error: ", err);
|
||||
};
|
||||
window.error = error;
|
||||
// Ensure the element is in the DOM before initializing the scanner
|
||||
if (document.getElementById("reader")) {
|
||||
scannerRef.current.render(success, error);
|
||||
}
|
||||
|
||||
// Cleanup the scanner on component unmount
|
||||
return () => {
|
||||
scannerRef.current.clear();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const reinitializeScanner = () => {
|
||||
setScanResult(null);
|
||||
setBarcodeInfo([]);
|
||||
setMarksData([]);
|
||||
// if (document.getElementById("reader")) {
|
||||
// console.log("Reinitializing scanner...");
|
||||
// scannerRef.current.render(success, error);
|
||||
// }
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!scanResult) {
|
||||
const readerEle = document.getElementById("reader");
|
||||
console.log("Reader ELe ===== ", readerEle);
|
||||
if (readerEle) {
|
||||
console.log("Changing it to visible");
|
||||
readerEle.style.visibility = "visible";
|
||||
scannerRef.current.render(success, error);
|
||||
}
|
||||
} else {
|
||||
fetchBarcodeData();
|
||||
}
|
||||
}, [scanResult]);
|
||||
|
||||
return (
|
||||
<Box className="App">
|
||||
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3">
|
||||
<h1>Welcome to exampaper.vidh.ai</h1>
|
||||
</Box>
|
||||
<Box className="my-3">
|
||||
<Box className="d-none d-md-flex justify-content-center align-items-center w-100">
|
||||
{scanResult ? (
|
||||
<h5>QR : {scanResult}</h5>
|
||||
) : (
|
||||
<div id="reader" style={{ width: "400px", height: "400px" }}></div>
|
||||
)}
|
||||
</Box>
|
||||
<Box className="d-flex d-md-none justify-content-center align-items-center w-100">
|
||||
{scanResult ? (
|
||||
<h5>QR : {scanResult}</h5>
|
||||
) : (
|
||||
<div id="reader" style={{ width: "400px", height: "400px" }}></div>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box className="w-100 d-flex justify-content-center">
|
||||
{barcodeInfo.length > 0 && (
|
||||
<Box className="p-5 w-50 rounded shadow">
|
||||
<h5>Candidate Name: {barcodeInfo[0]?.candidate_name}</h5>
|
||||
<h5>Register Name : {barcodeInfo[0]?.register_number}</h5>
|
||||
<h5>Subject Code : {barcodeInfo[0]?.subject_code}</h5>
|
||||
<h5>Exam center code : {barcodeInfo[0]?.exam_centre_code}</h5>
|
||||
<h5>Exam center : {barcodeInfo[0]?.exam_center}</h5>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
<Box className="w-100 d-flex justify-content-center">
|
||||
{scanResult ? (
|
||||
marksData.length > 0 && barcodeInfo.length > 0 ? (
|
||||
<>
|
||||
<Box className="d-flex flex-column gap-4">
|
||||
<Box className="p-5 rounded shadow">
|
||||
<h5>Marks : {marksData[0]?.marks}</h5>
|
||||
<h5>File Scanned Date : {marksData[0]?.file_scanned_date}</h5>
|
||||
<h5>Cover QR code : {marksData[0]?.cover_barcode}</h5>
|
||||
</Box>
|
||||
<Box>
|
||||
<Button
|
||||
className="p-3 bg-primary text-light rounded"
|
||||
onClick={reinitializeScanner}
|
||||
>
|
||||
Scan Again
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
) : (
|
||||
<Box className="w-50">
|
||||
<Box className="p-5 rounded shadow">
|
||||
<h5>Marks Data Not Found ..</h5>
|
||||
</Box>
|
||||
<Box className="my-3">
|
||||
<Button
|
||||
className="p-3 bg-primary text-light rounded"
|
||||
onClick={reinitializeScanner}
|
||||
>
|
||||
Scan Again
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
) : null}
|
||||
</Box>
|
||||
{isLoading && <LoadingContainer />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default BarcodeScanner;
|
||||
|
|
@ -0,0 +1,472 @@
|
|||
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"
|
||||
|
||||
const CustomQueryExecutorCard = ({
|
||||
data,
|
||||
s3_image_column,
|
||||
query,
|
||||
error,
|
||||
error_reason,
|
||||
reduxSystemNo,
|
||||
degreeType,
|
||||
type,
|
||||
tableName,
|
||||
}) => {
|
||||
// console.log("ERROR ============= ",error)
|
||||
// console.log("ERROR REASON ============== ",error_reason)
|
||||
// console.log("REDUX SYSTEM NO ================== ",reduxSystemNo)
|
||||
const navigate = useNavigate();
|
||||
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 [showEditContainer,setShowEditContainer] = useState(false)
|
||||
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);
|
||||
}
|
||||
}, [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 Backpage ! ....");
|
||||
} else {
|
||||
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 {
|
||||
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 {
|
||||
throw new Error(responseData?.message);
|
||||
}
|
||||
} catch (error) {
|
||||
setIsLoading(false)
|
||||
throw new Error(error);
|
||||
}
|
||||
}
|
||||
|
||||
const showContainerAction = () =>{
|
||||
setShowEditContainer(true)
|
||||
}
|
||||
|
||||
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 Instruction", action: updatePartAInstructions },
|
||||
{ btnLabel: "Initiate Process", action: initateProcess },
|
||||
{ btnLabel: "Mark As Dummy",action:markAsDummy },
|
||||
{ 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 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 () => {
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className="w-100 rounded shadow mb-5 bg-white">
|
||||
<Box className="p-4 d-flex justify-content-between align-items-start">
|
||||
<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={`https://docs.exampaper.vidh.ai/${data[s3_image_column]}`}
|
||||
width="800px"
|
||||
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}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box className="text-left p-3 d-flex flex-column justify-content-between align-items-between h-100">
|
||||
{keys.map((record, index) => (
|
||||
<p>
|
||||
<strong>{keys[index]}</strong> : {values[index]}
|
||||
</p>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
{isLoading && <LoadingContainer loadingText={"Loading ..."} />}
|
||||
{showEditContainer && <PlayGroundEditContainer rotateAngle={rotateAngle} data={data} s3Path={data[s3_image_column]} tableName={tableName} imageName={data["image_name"]} setShowEditContainer={setShowEditContainer}/>}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomQueryExecutorCard;
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
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";
|
||||
|
||||
const CustomQueryExecutorCard = ({
|
||||
data,
|
||||
s3_image_column,
|
||||
query,
|
||||
error,
|
||||
error_reason,
|
||||
reduxSystemNo,
|
||||
degreeType,
|
||||
type,
|
||||
tableName
|
||||
}) => {
|
||||
// console.log("ERROR ============= ",error)
|
||||
// console.log("ERROR REASON ============== ",error_reason)
|
||||
// console.log("REDUX SYSTEM NO ================== ",reduxSystemNo)
|
||||
const navigate = useNavigate();
|
||||
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()
|
||||
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)
|
||||
}
|
||||
},[data])
|
||||
|
||||
|
||||
const updateFront = () => {
|
||||
console.log("update front");
|
||||
};
|
||||
|
||||
const updateBack = () => {
|
||||
console.log("update back ..");
|
||||
};
|
||||
|
||||
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 buttonActions = {
|
||||
PartC: [
|
||||
{ btnLabel: "Mark As Front", action: updateFront },
|
||||
{ btnLabel: "Mark As Back", action: updateBack },
|
||||
{ btnLabel: "Initiate Process", action: initateProcess },
|
||||
],
|
||||
};
|
||||
|
||||
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 mark_as_ev = 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 mark_as_dummy = async () => {
|
||||
const payload = {
|
||||
data,
|
||||
};
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcDummyMarking`,
|
||||
{
|
||||
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, type: 102 };
|
||||
// console.log("Data ===== ", updatedData);
|
||||
setDataValue(updatedData);
|
||||
toast.success("Record Marked as Dummy ! ....");
|
||||
} else {
|
||||
throw new Error(responseData?.message);
|
||||
}
|
||||
} catch (error) {
|
||||
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")
|
||||
}
|
||||
|
||||
}catch(error){
|
||||
setIsLoading(false)
|
||||
throw new Error(error)
|
||||
}
|
||||
}
|
||||
|
||||
const mark_as_backpage = 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 {
|
||||
throw new Error(responseData?.message);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className="w-100 rounded shadow mb-5 bg-white">
|
||||
<ToastContainer />
|
||||
<Box className="p-4 d-flex justify-content-between align-items-start">
|
||||
<Box className="text-left p-3 d-flex flex-column justify-content-between align-items-between h-100">
|
||||
{keys.map((record, index) => (
|
||||
<p>
|
||||
<strong>{keys[index]}</strong> : {values[index]}
|
||||
</p>
|
||||
))}
|
||||
</Box>
|
||||
<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>
|
||||
</>
|
||||
)} */}
|
||||
{type &&
|
||||
buttonActions[type].map((action) => (
|
||||
<Button
|
||||
className="w-50 m-0 bg-primary text-white p-1 rounded"
|
||||
onClick={action?.action}
|
||||
>
|
||||
{action?.btnLabel}
|
||||
</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={`https://docs.exampaper.vidh.ai/${data[s3_image_column]}`}
|
||||
width="800px"
|
||||
height="auto"
|
||||
alt="Image Alt"
|
||||
ref={imageEleRef}
|
||||
/>
|
||||
</Box>
|
||||
<Box className="d-flex justify-content-between gap-2 my-2">
|
||||
<Button
|
||||
className="w-50 m-0 bg-primary text-white p-1 rounded"
|
||||
onClick={rotateLeft}
|
||||
>
|
||||
Rotate left
|
||||
</Button>
|
||||
<Button className="w-50 m-0 bg-primary text-white p-1 rounded" onClick={saveRotatedImage}>
|
||||
Save
|
||||
</Button>
|
||||
<Button
|
||||
className="w-50 m-0 bg-primary text-white p-1 rounded"
|
||||
onClick={rotateRight}
|
||||
>
|
||||
Rotate Right
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
{isLoading && <LoadingContainer loadingText={"Loading ..."} />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomQueryExecutorCard;
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
import { Layout, theme } from "antd";
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import { useNavigate } from "react-router-dom/dist";
|
||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||
import HomeIcon from "@mui/icons-material/Home";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
CardContent,
|
||||
Typography,
|
||||
CircularProgress,
|
||||
} from "@mui/material";
|
||||
import { updateEvQrcodeList } from "../redux/actions/actions";
|
||||
import SystemNumberDialog from "./SystemNumberDialog";
|
||||
import { toast, ToastContainer } from "react-toastify";
|
||||
import LoadingContainer from "./LoadingContainer";
|
||||
|
||||
const { Content, Header } = Layout;
|
||||
|
||||
function EvQrcode() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [showSystemNoContainer, setShowSystemNoContainer] = useState(false);
|
||||
const [anomalyData, setAnomalyData] = useState([]);
|
||||
const [currentIndex, setCurrentIndex] = useState(0);
|
||||
const inputRef = useRef(null);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const evQrcodeList = useSelector((state) => state?.evQrcodeList);
|
||||
console.log("evQrcodeList = ", evQrcodeList);
|
||||
|
||||
const reduxSystemNo = useSelector((state) => state?.systemNumber);
|
||||
console.log("systemno: ", reduxSystemNo);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
token: { colorBgContainer },
|
||||
} = theme.useToken();
|
||||
|
||||
useEffect(() => {
|
||||
if (!reduxSystemNo) {
|
||||
setShowSystemNoContainer(true);
|
||||
} else {
|
||||
if (evQrcodeList.length > 0) {
|
||||
setAnomalyData(evQrcodeList);
|
||||
} else {
|
||||
fetchAnomalyData();
|
||||
}
|
||||
}
|
||||
}, [reduxSystemNo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (evQrcodeList.length > 0) {
|
||||
setAnomalyData(evQrcodeList);
|
||||
}
|
||||
}, [evQrcodeList]);
|
||||
|
||||
const handleSystemNoChange = () => {
|
||||
console.log("System No Change is called");
|
||||
setShowSystemNoContainer(true);
|
||||
dispatch(updateEvQrcodeList([]));
|
||||
};
|
||||
|
||||
const updateSystemReservationStatus = async (systemRecords) => {
|
||||
const payload = {
|
||||
systemRecords,
|
||||
sysNo: reduxSystemNo,
|
||||
};
|
||||
try {
|
||||
fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/updateSystemReservationStatusEvQrcode`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((responseData) => {
|
||||
console.log("response from updation : ", responseData);
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error("Error in update system records : ", systemRecords);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchAnomalyData = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/getEvRecords`,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
sysno: reduxSystemNo,
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
const responseData = await response.json();
|
||||
var systemRecords = responseData?.data;
|
||||
console.log("System record ====== ", responseData.systemRecord);
|
||||
if (!responseData.systemRecord) {
|
||||
systemRecords = getRecordsBySystemId(responseData?.data, reduxSystemNo);
|
||||
}
|
||||
console.log("System records : ", systemRecords);
|
||||
|
||||
dispatch(updateEvQrcodeList(systemRecords));
|
||||
updateSystemReservationStatus(systemRecords);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data: ", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
function getRecordsBySystemId(records, systemId) {
|
||||
const new_data = [];
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
var count = i % 5;
|
||||
if (count === systemId - 1) {
|
||||
new_data.push(records[i]);
|
||||
}
|
||||
}
|
||||
return new_data;
|
||||
}
|
||||
|
||||
const handleNext = () => {
|
||||
setIsLoading(true);
|
||||
setAnomalyData([]);
|
||||
setTimeout(() => {
|
||||
const newItems = anomalyData.filter((_, index) => index !== currentIndex);
|
||||
setAnomalyData(newItems);
|
||||
if (currentIndex >= newItems.length) {
|
||||
setCurrentIndex(0);
|
||||
}
|
||||
setIsLoading(false)
|
||||
},1000);
|
||||
};
|
||||
|
||||
const handleUpdate = async () => {
|
||||
try {
|
||||
const inputValue = document.getElementById("qrcodeInput").value;
|
||||
console.log("inputvalu = ", inputValue);
|
||||
|
||||
const payload = {
|
||||
imageName: currentItem.image_name,
|
||||
qrvalue: inputValue,
|
||||
};
|
||||
console.log("payload=", payload);
|
||||
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/updateEvRecord`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
const responseData = await response.json();
|
||||
console.log("responsedata: ", responseData);
|
||||
if (responseData?.status_code === 200) {
|
||||
toast.success("Record Updated Successfully");
|
||||
handleNext();
|
||||
document.getElementById("qrcodeInput").value = "";
|
||||
} else {
|
||||
toast.error("Updation Failed");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching data: ", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleArrowBack = () => {
|
||||
dispatch(updateEvQrcodeList([]));
|
||||
navigate(-1);
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return <CircularProgress />;
|
||||
}
|
||||
|
||||
const currentItem = anomalyData[currentIndex];
|
||||
const imageUrl = currentItem
|
||||
? `https://docs.exampaper.vidh.ai/${currentItem.s3_path}`
|
||||
: "";
|
||||
|
||||
const handleKeyDown = (e) => {
|
||||
if (e.key === "Enter") {
|
||||
console.log("Updating ......");
|
||||
handleUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout style={{ minHeight: "100vh" }}>
|
||||
<Layout>
|
||||
<ToastContainer />
|
||||
<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={handleArrowBack}
|
||||
>
|
||||
<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" }}
|
||||
onClick={handleSystemNoChange}
|
||||
>
|
||||
<b>System No : </b> {reduxSystemNo}
|
||||
</Box>
|
||||
)}
|
||||
<Button
|
||||
className="bg-primary p-1 text-light"
|
||||
onClick={() => navigate("/")}
|
||||
>
|
||||
<HomeIcon />
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Header>
|
||||
|
||||
<Content>
|
||||
{currentItem ? (
|
||||
<Box
|
||||
className="d-flex justify-content-center align-items-center flex-column"
|
||||
style={{ minHeight: "80vh" }}
|
||||
>
|
||||
<Card
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
margin: "20px 20px 20px 20px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
flex: "20%",
|
||||
padding: "20px",
|
||||
marginTop: "30px",
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h5" style={{ paddingBottom: "20px" }}>
|
||||
Records Count: {anomalyData.length}
|
||||
</Typography>
|
||||
<Typography variant="h6">
|
||||
Image Name: {currentItem.image_name}
|
||||
</Typography>
|
||||
{/* <Typography variant="body2">S3 Path: {currentItem.s3_path}</Typography> */}
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
style={{ paddingTop: "20px", fontWeight: "bold" }}
|
||||
>
|
||||
Qrcode Value
|
||||
</Typography>
|
||||
<input
|
||||
type="text"
|
||||
id="qrcodeInput"
|
||||
placeholder="Enter qrcode value"
|
||||
style={{
|
||||
marginTop: "10px",
|
||||
width: "100%",
|
||||
padding: "5px",
|
||||
backgroundColor: "transparent",
|
||||
color: "#000000", // black text color
|
||||
}}
|
||||
onKeyDown={handleKeyDown}
|
||||
inputRef={inputRef}
|
||||
/>
|
||||
<Box mt={2}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleNext}
|
||||
style={{ marginRight: 10 }}
|
||||
>
|
||||
Skip
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
onClick={handleUpdate}
|
||||
style={{ backgroundColor: "green" }}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
<CardContent style={{ flex: "80%" }}>
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt={currentItem.image_name}
|
||||
style={{ minWidth:"1000px",width: "100%", marginTop: "20px" }}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Box>
|
||||
) : (
|
||||
<Typography>No items to display</Typography>
|
||||
)}
|
||||
</Content>
|
||||
|
||||
{showSystemNoContainer && (
|
||||
<SystemNumberDialog
|
||||
setShowSystemNoContainer={setShowSystemNoContainer}
|
||||
showSystemNoContainer={showSystemNoContainer}
|
||||
/>
|
||||
)}
|
||||
</Layout>
|
||||
{isLoading && <LoadingContainer />}
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default EvQrcode;
|
||||
|
|
@ -5,8 +5,8 @@ import {useState,useEffect} from "react"
|
|||
const Home = () => {
|
||||
const cards = [
|
||||
{
|
||||
title: "Reassingned Serial No Anomoly Manual Updation",
|
||||
url: "/anomoly/reassigned",
|
||||
title: "Reassigned Serial No Anomoly Manual Updation (ATTENDANCE)",
|
||||
url: "/anomoly/attendence",
|
||||
},
|
||||
// {
|
||||
// title: "Part A OCR Anomoly - Batch 2022",
|
||||
|
|
@ -20,13 +20,33 @@ const Home = () => {
|
|||
title: "Part A OCR Anomoly - Old Dummy",
|
||||
url: "/anomoly/partA?type=old",
|
||||
},
|
||||
{
|
||||
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:"Statistics",
|
||||
// url:"/statistics"
|
||||
// title:"Marks Verfication",
|
||||
// url:"/part-c/marks/verify"
|
||||
// }
|
||||
];
|
||||
|
||||
|
|
@ -35,13 +55,14 @@ const Home = () => {
|
|||
// title: "Reassingned Serial No Anomoly Manual Updation",
|
||||
// url: "/anomoly/reassigned",
|
||||
// }]
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Box className="d-flex justify-content-center text-light bg-primary rounded py-3">
|
||||
<h1>Welcome to exampaper.vidh.ai</h1>
|
||||
</Box>
|
||||
<Box className="p-3">
|
||||
<Box className="p-3" style={{width:'100%'}}>
|
||||
{cards.map((card) => (
|
||||
<HomepageCard title={card?.title} url={card?.url} />
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,16 @@ const HomepageCard = ({ title, url }) => {
|
|||
<Row
|
||||
gutter={16}
|
||||
className="p-2"
|
||||
>
|
||||
<Col span={24}>
|
||||
<Card
|
||||
onClick={() => {
|
||||
navigate(url);
|
||||
}}
|
||||
title="" className="shadow"
|
||||
bordered={true}
|
||||
style={{with:'100%'}}
|
||||
>
|
||||
<Col span={12}>
|
||||
<Card title="" className="shadow" bordered={false}>
|
||||
{title}
|
||||
</Card>
|
||||
</Col>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
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';
|
||||
|
||||
const Transition = React.forwardRef(function Transition(props, ref) {
|
||||
return <Slide direction="up" ref={ref} {...props} />;
|
||||
});
|
||||
|
||||
export default function ImageDialog({ imagePath, setIsDialogOpen }) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
|
||||
const [scaleWidthValue, setScaleWidthValue] = React.useState(80);
|
||||
const [rotateValue, setRotateValue] = React.useState(0);
|
||||
|
||||
const handleClickOpen = () => {
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
setIsDialogOpen(false);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
handleClickOpen();
|
||||
}, []);
|
||||
|
||||
|
||||
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)`;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Dialog
|
||||
fullScreen
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
TransitionComponent={Transition}
|
||||
>
|
||||
<AppBar sx={{ position: 'relative' }}>
|
||||
<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 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"
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
|
@ -102,17 +102,38 @@ const PartACorrection = () => {
|
|||
|
||||
|
||||
const subjectCodeInputRef = useRef(null);
|
||||
const examcentreCodeInputRef = useRef(null);
|
||||
const examDateInputRef = useRef(null);
|
||||
const studentNameInputRef = useRef(null);
|
||||
const bookletInputRef = useRef(null);
|
||||
const registerNumberInputRef = useRef(null);
|
||||
|
||||
// Handle the Enter key press in the register number input
|
||||
const handleRegisterNumberKeyDown = (e) => {
|
||||
console.log("Handle register number key down ....")
|
||||
if (e.key === 'Enter') {
|
||||
console.log("Entering subject code field ...")
|
||||
// Focus on the subject code input
|
||||
registerNumberInputRef.current.unfocus()
|
||||
const subjectCodeInput = subjectCodeInputRef.current;
|
||||
console.log("Subject code input :: ",subjectCodeInput)
|
||||
subjectCodeInput.focus();
|
||||
subjectCodeInput.select();
|
||||
}
|
||||
};
|
||||
|
||||
const handleBookletSerialNoKeyDown = (e) =>{
|
||||
console.log("Handdle booklet serial no key down.....")
|
||||
if(e.key === 'Enter'){
|
||||
console.log("Entering register number field...")
|
||||
const registerNumberInputField = registerNumberInputRef.current
|
||||
console.log("Register number input :: ",registerNumberInputField)
|
||||
registerNumberInputField.focus()
|
||||
// const ele = document.getElementById("corrected-register-number-input")
|
||||
// console.log("ELE : ",ele)
|
||||
// ele.focus()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
|
@ -456,6 +477,7 @@ const PartACorrection = () => {
|
|||
};
|
||||
|
||||
const updatePartAanomoly = async (e) => {
|
||||
subjectCodeInputRef.current.blur()
|
||||
setIsLoading(true);
|
||||
setMetaBaseRegnoLink(null);
|
||||
setMetaBaseSubjectLinkWithTitle(null);
|
||||
|
|
@ -764,7 +786,7 @@ const PartACorrection = () => {
|
|||
/>
|
||||
</Box>
|
||||
</Box> */}
|
||||
{showSubjectTitleInput && (
|
||||
{/* {showSubjectTitleInput && (
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="corrected-register-number-input">
|
||||
Corrected Subject Title:
|
||||
|
|
@ -781,10 +803,10 @@ const PartACorrection = () => {
|
|||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
)} */}
|
||||
{showAdditionalStudentInputs && (
|
||||
<>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
{/* <Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="corrected-register-number-input">
|
||||
Corrected Exam Centre Code:
|
||||
</label>
|
||||
|
|
@ -793,6 +815,7 @@ const PartACorrection = () => {
|
|||
id="corrected-register-number-input"
|
||||
className="w-100"
|
||||
value={correctedExamCentreCode}
|
||||
inputRef={examcentreCodeInputRef}
|
||||
autoComplete="off"
|
||||
onChange={(e) => {
|
||||
setCorrectedExamCentreCode(
|
||||
|
|
@ -801,8 +824,8 @@ const PartACorrection = () => {
|
|||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
</Box> */}
|
||||
{/* <Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="corrected-register-number-input">
|
||||
Corrected Exam Date:
|
||||
</label>
|
||||
|
|
@ -812,14 +835,15 @@ const PartACorrection = () => {
|
|||
className="w-100"
|
||||
value={correctedExamDate}
|
||||
autoComplete="off"
|
||||
inputRef = {examDateInputRef}
|
||||
onChange={(e) => {
|
||||
setCorrectedExamDate(e.target.value);
|
||||
}}
|
||||
placeholder="(DD-MM-YYYY)"
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
</Box> */}
|
||||
{/* <Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="corrected-register-number-input">
|
||||
Corrected Student Name:
|
||||
</label>
|
||||
|
|
@ -828,13 +852,14 @@ const PartACorrection = () => {
|
|||
id="corrected-register-number-input"
|
||||
className="w-100"
|
||||
value={correctedCandidateName}
|
||||
inputRef = {studentNameInputRef}
|
||||
autoComplete="off"
|
||||
onChange={(e) => {
|
||||
setCorrectedCandidateName(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box> */}
|
||||
{batchType === "old" && (
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="corrected-register-number-input">
|
||||
|
|
@ -845,7 +870,9 @@ const PartACorrection = () => {
|
|||
id="corrected-register-number-input"
|
||||
className="w-100"
|
||||
value={correctedSerialNo}
|
||||
inputRef={bookletInputRef}
|
||||
autoComplete="off"
|
||||
onKeyDown={handleBookletSerialNoKeyDown}
|
||||
onChange={(e) => {
|
||||
setCorrectedSerialNo(e.target.value);
|
||||
}}
|
||||
|
|
@ -866,6 +893,7 @@ const PartACorrection = () => {
|
|||
id="corrected-register-number-input"
|
||||
className="w-100"
|
||||
value={correctedRegisterNo}
|
||||
inputRef={registerNumberInputRef}
|
||||
autoComplete="off"
|
||||
onKeyDown={handleRegisterNumberKeyDown} // Attach the keydown handler
|
||||
onChange={(e) => {
|
||||
|
|
@ -972,7 +1000,7 @@ const PartACorrection = () => {
|
|||
/>
|
||||
</Box>
|
||||
</Box> */}
|
||||
{showSubjectTitleInput && (
|
||||
{/* {showSubjectTitleInput && (
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="corrected-register-number-input">
|
||||
Corrected Subject Title:
|
||||
|
|
@ -989,10 +1017,10 @@ const PartACorrection = () => {
|
|||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
)} */}
|
||||
{showAdditionalStudentInputs && (
|
||||
<>
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
{/* <Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="corrected-register-number-input">
|
||||
Corrected Exam Centre Code:
|
||||
</label>
|
||||
|
|
@ -1042,7 +1070,7 @@ const PartACorrection = () => {
|
|||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box> */}
|
||||
<Box className="d-flex flex-column align-items-start gap-2 py-2">
|
||||
<label for="corrected-register-number-input">
|
||||
Corrected Booklet Serial No:
|
||||
|
|
@ -1052,6 +1080,7 @@ const PartACorrection = () => {
|
|||
id="corrected-register-number-input"
|
||||
className="w-100"
|
||||
value={correctedSerialNo}
|
||||
onKeyDown={handleBookletSerialNoKeyDown}
|
||||
autoComplete="off"
|
||||
onChange={(e) => {
|
||||
setCorrectedSerialNo(e.target.value);
|
||||
|
|
@ -1073,6 +1102,8 @@ const PartACorrection = () => {
|
|||
className="w-100"
|
||||
value={correctedRegisterNo}
|
||||
autoComplete="off"
|
||||
inputRef={registerNumberInputRef}
|
||||
onKeyDown={handleRegisterNumberKeyDown}
|
||||
onChange={(e) => {
|
||||
setCorrectedRegisterNo(e.target.value);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,377 @@
|
|||
import React, { useState, useEffect } 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 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";
|
||||
|
||||
const { Header, Content, Footer, Sider } = Layout;
|
||||
const PlayGround = () => {
|
||||
const { type } = 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: "ocr_scanned_part_a_v1",
|
||||
PartC: "ocr_scanned_part_c_v1",
|
||||
Attendence: "attendence_scanned_data",
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("use effect type ==== ", type);
|
||||
console.log("use effect table name ===== ", tableName);
|
||||
console.log("table name ==== ", tableType[type]);
|
||||
if (!tableName) {
|
||||
setTableName(tableType[type]);
|
||||
}
|
||||
}, [type, tableName]);
|
||||
|
||||
const [responseData, setResponseData] = useState([]);
|
||||
const [totalData, setTotalData] = useState([]);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [totalPages, setTotalPages] = useState(0);
|
||||
const [imageColumn, setImageColumn] = useState(null);
|
||||
const [query, setQuery] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [paginationPages, setPaginationPages] = useState(null);
|
||||
const [limit, setLimit] = useState("");
|
||||
const recordsPerPage = 50;
|
||||
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 () => {
|
||||
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") {
|
||||
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));
|
||||
} else {
|
||||
toast.error(data.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(updatePlaygroundQuery(query));
|
||||
}, [query]);
|
||||
|
||||
useEffect(() => {
|
||||
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]);
|
||||
|
||||
const getTableData = () => {
|
||||
if (responseData.length === 0) return null;
|
||||
const keys = Object.keys(totalData[0]);
|
||||
|
||||
return (
|
||||
<div className="w-100">
|
||||
<div className="text-left d-flex justify-content-between align-items-center">
|
||||
<h5>
|
||||
<strong>Total Results </strong> : {totalData.length}
|
||||
</h5>
|
||||
{totalData.length > 0 && (
|
||||
<div id="footer-container">
|
||||
<div
|
||||
id="footer-main"
|
||||
className="d-flex justify-content-center p-3 align-items-center"
|
||||
>
|
||||
<div className="d-flex justify-content-center align-items-center p-1">
|
||||
<Box className="d-flex flex-column align-items-end">
|
||||
<Box>{paginationPages}</Box>
|
||||
<Box>
|
||||
<strong>{currentPage}</strong>/
|
||||
<strong>{totalPages}</strong>
|
||||
</Box>
|
||||
</Box>
|
||||
</div>
|
||||
<div className="d-flex gap-3">
|
||||
{/* <button
|
||||
className="btn text-light bg-primary rounded p-2 mx-3"
|
||||
onClick={() =>
|
||||
setCurrentPage((prev) => Math.max(prev - 1, 1))
|
||||
}
|
||||
>
|
||||
Previous
|
||||
</button>
|
||||
<button
|
||||
className="btn text-light bg-primary rounded p-2"
|
||||
onClick={() =>
|
||||
setCurrentPage((prev) => Math.min(prev + 1, totalPages))
|
||||
}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
{} */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="my-2 overflow-auto">
|
||||
{responseData.map((data) => (
|
||||
<CustomQueryExecutorCard
|
||||
type={type}
|
||||
tableName={tableName}
|
||||
data={data}
|
||||
s3_image_column={imageColumn}
|
||||
query={query}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
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}
|
||||
/>
|
||||
<TextInputField
|
||||
placeholder={"imageColumn"}
|
||||
value={imageColumn}
|
||||
setValue={setImageColumn}
|
||||
/>
|
||||
<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)}
|
||||
/>
|
||||
<TextField
|
||||
className="input rounded h6 bg-white"
|
||||
type="text"
|
||||
placeholder="Image column name"
|
||||
id="image-column-input"
|
||||
autoComplete="off"
|
||||
value={imageColumn}
|
||||
onChange={(e) => setImageColumn(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
className="btn bg-primary text-light"
|
||||
id="submit-btn"
|
||||
onClick={fetchQueryValue}
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="results-container"
|
||||
className="d-flex w-100 justify-content-center"
|
||||
>
|
||||
{getTableData()}
|
||||
</div>
|
||||
</div>
|
||||
{isLoading && <LoadingContainer />}
|
||||
</AntdesignLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlayGround;
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import Dialog from "@mui/material/Dialog";
|
||||
import DialogContent from "@mui/material/DialogContent";
|
||||
import DialogContentText from "@mui/material/DialogContentText";
|
||||
import DialogTitle from "@mui/material/DialogTitle";
|
||||
import { Button, Box } from "@mui/material";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { NavLink, Link } from "react-router-dom";
|
||||
import TextInputField from "./TextInputField";
|
||||
import { Height } from "@mui/icons-material";
|
||||
import HighlightOffIcon from "@mui/icons-material/HighlightOff";
|
||||
|
||||
const PlayGroundEditContainer = ({
|
||||
data,
|
||||
s3Path,
|
||||
imageName,
|
||||
tableName,
|
||||
setShowEditContainer,
|
||||
rotateAngle,
|
||||
}) => {
|
||||
const type = "PartC";
|
||||
const dialogText = "This is dialog text";
|
||||
const [marks, setMarks] = useState(null);
|
||||
const [barcode, setBarcode] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [qrcode, setQrcode] = useState(null);
|
||||
const [subjectCode, setSubjectCode] = useState(null);
|
||||
const [open, setOpen] = useState(true); // Set open state to true by default
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setQrcode(data?.qrcode);
|
||||
setBarcode(data?.barcode);
|
||||
setMarks(data?.marks);
|
||||
setSubjectCode(data?.subject_code)
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
const updateRecord = async () => {
|
||||
if (!marks) {
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const payload = {
|
||||
qrcode,
|
||||
barcode,
|
||||
table:tableName,
|
||||
s3Path,
|
||||
subjectCode,
|
||||
marks,
|
||||
imageName,
|
||||
rotateAngle,
|
||||
};
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartCdata`,
|
||||
{
|
||||
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 ...");
|
||||
}
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={handleClose} maxWidth="lg" style={{zIndex:100}} fullWidth>
|
||||
<DialogContent>
|
||||
<Box className="d-flex justify-content-between align-items-start gap-4">
|
||||
<Box className="d-flex flex-column">
|
||||
<img
|
||||
src={`https://docs.exampaper.vidh.ai/${s3Path}`}
|
||||
height={"100%"}
|
||||
width={"100%"}
|
||||
/>
|
||||
</Box>
|
||||
<Box className="py-3 d-flex flex-column justify-content-end w-100 gap-3">
|
||||
<TextInputField
|
||||
value={qrcode}
|
||||
setValue={setQrcode}
|
||||
placeholder={"QR code"}
|
||||
/>
|
||||
<TextInputField
|
||||
value={barcode}
|
||||
setValue={setBarcode}
|
||||
placeholder={"BarCode"}
|
||||
/>
|
||||
<TextInputField
|
||||
value={marks}
|
||||
setValue={setMarks}
|
||||
placeholder={"Marks"}
|
||||
/>
|
||||
<Button
|
||||
className="bg-primary text-white p-3"
|
||||
onClick={() => updateRecord()}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-white p-3"
|
||||
onClick={() => setShowEditContainer(false)}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlayGroundEditContainer;
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import React from "react";
|
||||
import { Box } from "@mui/material";
|
||||
import HomepageCard from "./HomepageCard";
|
||||
|
||||
const PlayGrounds = () => {
|
||||
const cards = [
|
||||
// {
|
||||
// title: "PART - A",
|
||||
// url: "/Playground/PartA",
|
||||
// },
|
||||
{
|
||||
title: "PART - C",
|
||||
url: "/Playground/PartC",
|
||||
},
|
||||
// {
|
||||
// title: "ATTENDENCE",
|
||||
// url: "/Playground/Attendence",
|
||||
// },
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<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" style={{ width: "100%" }}>
|
||||
{cards.map((card) => (
|
||||
<HomepageCard title={card?.title} url={card?.url} />
|
||||
))}
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlayGrounds;
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { Box, Button } from "@mui/material";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
import AntdesignLayout from "./AntdesignLayout";
|
||||
import TextInputField from "./TextInputField";
|
||||
import { toast } from "react-toastify";
|
||||
import LoadingContainer from "./LoadingContainer";
|
||||
import SimpleDialog from "./SimpleDialog";
|
||||
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
|
||||
import RotateRightIcon from "@mui/icons-material/RotateRight";
|
||||
import { updatePartCErrorData, updateSystemNo } from "../redux/actions/actions";
|
||||
import { updatePartCErrorList } from "../redux/actions/actions";
|
||||
import { DiscFullTwoTone } from "@mui/icons-material";
|
||||
|
||||
const QrcodeCardEditor = () => {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
const [evQrcode, setEvQrcode] = useState(null);
|
||||
const [imageName, setImageName] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [recordData, setRecordData] = useState([]);
|
||||
const [s3Path, setS3Path] = useState(null);
|
||||
const [showDialog, setShowDialog] = useState(false);
|
||||
const [rotationResults, setRotationResults] = useState([]);
|
||||
const [rotateAngle, setRotateAngle] = useState(0);
|
||||
const evErrorsList = useSelector((state) => state?.partCErrorList);
|
||||
const table = searchParams.get("table");
|
||||
const image_name = searchParams.get("image_name");
|
||||
const paramsError = searchParams.get("error");
|
||||
const paramsErrorReason = searchParams.get("error_reason");
|
||||
const paramsSysNo = searchParams.get("sysNo");
|
||||
const paramsDegreeType = searchParams.get("degreeType");
|
||||
const [items, setItems] = useState([]);
|
||||
const [evErrorsData,setEvErrorsData] = useState([]);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
console.log("Ev errors list ==== ", evErrorsList);
|
||||
console.log("table is : ", table);
|
||||
// const evErrorsData = useSelector((state) => state?.partCErrorData);
|
||||
// console.log("evErrorData: ", evErrorsData);
|
||||
|
||||
const fetchPrimaryKeyData = async () => {
|
||||
try {
|
||||
const payload = {
|
||||
image_name,
|
||||
table,
|
||||
};
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchPrimaryKeyData`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const marksLocalData = localStorage.getItem("marks_manual_data");
|
||||
console.log("Marks local data 123 ========= ",marksLocalData)
|
||||
if (marksLocalData) {
|
||||
console.log("Into if and updating .......")
|
||||
console.log("marks local data ==== ",marksLocalData)
|
||||
setEvErrorsData(JSON.parse(marksLocalData));
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(()=>{
|
||||
dispatch(updateSystemNo(paramsSysNo))
|
||||
},[paramsSysNo])
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
console.log("Ev error data =============== ",evErrorsData)
|
||||
},[evErrorsData])
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
if (table && image_name) {
|
||||
setIsLoading(true);
|
||||
const response = await fetchPrimaryKeyData();
|
||||
setIsLoading(false);
|
||||
console.log("Response is : ", response);
|
||||
if (response?.status === "success") {
|
||||
console.log("=========== Success ============");
|
||||
const data = response?.data;
|
||||
if (data.length > 0) {
|
||||
setRecordData(data[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("=========== Use effect triggered ===========");
|
||||
setImageName(recordData?.image_name);
|
||||
setEvQrcode(recordData?.cover_barcode);
|
||||
setS3Path(recordData?.s3_path);
|
||||
}, [recordData]);
|
||||
|
||||
|
||||
const updateRecord = async () => {
|
||||
if(!marks){
|
||||
return
|
||||
}
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const payload = {
|
||||
evQrcode,
|
||||
imageName,
|
||||
rotateAngle
|
||||
};
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartCdata`,
|
||||
{
|
||||
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 ...");
|
||||
var currentIndex = null;
|
||||
console.log("Ev errors data before filter ============= ",evErrorsData)
|
||||
var newRecords = evErrorsData.filter((data, index) => {
|
||||
if (data?.image_name === imageName) {
|
||||
currentIndex = index;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if(!currentIndex){
|
||||
currentIndex = 0
|
||||
}
|
||||
console.log("new records ======1 ", newRecords);
|
||||
console.log("Current Index ===== ", currentIndex);
|
||||
dispatch(updatePartCErrorData(newRecords));
|
||||
if (newRecords.length > 0) {
|
||||
console.log("Has to navigte 12 .....");
|
||||
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}`;
|
||||
console.log("new url ==== ", newUrl);
|
||||
window.location.href = newUrl;
|
||||
} else {
|
||||
navigate("/");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Rotate angle changed to ========== ", rotateAngle);
|
||||
const imageContainer = document.getElementById("img-container");
|
||||
console.log("Imge container ===== ", imageContainer);
|
||||
if (imageContainer) {
|
||||
imageContainer.style.transform = `rotate(${rotateAngle}deg)`;
|
||||
}
|
||||
}, [rotateAngle]);
|
||||
|
||||
const initateRotation = async () => {
|
||||
console.log("Rotating initiated ...");
|
||||
setIsLoading(true);
|
||||
const payload = {
|
||||
imageName,
|
||||
};
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/initateRotation`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
setIsLoading(false);
|
||||
const responseData = await response.json();
|
||||
console.log("Response data ======= ", responseData);
|
||||
if (responseData?.status === "success") {
|
||||
setShowDialog(true);
|
||||
setRotationResults(responseData?.result);
|
||||
}
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const skipPage = () =>{
|
||||
try{
|
||||
if(evErrorsData){
|
||||
var currentIndex = null
|
||||
var newRecords = evErrorsData.filter((data, index) => {
|
||||
if (data?.image_name === imageName) {
|
||||
currentIndex = index;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if(!currentIndex){
|
||||
currentIndex = 0
|
||||
}
|
||||
console.log("Current Index ===== ", currentIndex);
|
||||
const newIndex = currentIndex+1
|
||||
console.log("new index ===== ",newIndex)
|
||||
if (newRecords.length > 0) {
|
||||
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}`;
|
||||
console.log("new url ==== ", newUrl);
|
||||
window.location.href = newUrl;
|
||||
}
|
||||
}
|
||||
}catch(error){
|
||||
throw new Error(error)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<AntdesignLayout>
|
||||
<Box className="d-flex justify-content-between align-items-center">
|
||||
<Box className="d-flex flex-column gap-3 w-25">
|
||||
{imageName && <h5 className="text-left">ID : {imageName}</h5>}
|
||||
{paramsError && <h5 className="text-left">Error Code : {paramsError}</h5>}
|
||||
|
||||
|
||||
<TextInputField
|
||||
placeholder={"cover qrcode"}
|
||||
value={evQrcode}
|
||||
setValue={setEvQrcode}
|
||||
/>
|
||||
<Button
|
||||
className="bg-primary text-white rounded p-3"
|
||||
onClick={() => {
|
||||
updateRecord();
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-white rounded p-3"
|
||||
onClick={() => {
|
||||
skipPage()
|
||||
}}
|
||||
>
|
||||
Skip
|
||||
</Button>
|
||||
<Box className="d-flex justify-content-between">
|
||||
<Button
|
||||
className="bg-primary text-white rounded p-3"
|
||||
onClick={() => setRotateAngle((prev) => prev - 90)}
|
||||
>
|
||||
Rotate <RotateLeftIcon />
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-white rounded p-3"
|
||||
onClick={() => setRotateAngle((prev) => prev + 90)}
|
||||
>
|
||||
Rotate <RotateRightIcon />
|
||||
</Button>
|
||||
</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>
|
||||
{isLoading && <LoadingContainer />}
|
||||
{showDialog && (
|
||||
<SimpleDialog
|
||||
type="rotation_results"
|
||||
rotationResults={rotationResults}
|
||||
setShowDialog={setShowDialog}
|
||||
/>
|
||||
)}
|
||||
</AntdesignLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default QrcodeCardEditor;
|
||||
|
|
@ -0,0 +1,370 @@
|
|||
import { useState, useEffect, useRef } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { Box, Button } from "@mui/material";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
import AntdesignLayout from "./AntdesignLayout";
|
||||
import TextInputField from "./TextInputField";
|
||||
import { toast } from "react-toastify";
|
||||
import LoadingContainer from "./LoadingContainer";
|
||||
import SimpleDialog from "./SimpleDialog";
|
||||
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
|
||||
import RotateRightIcon from "@mui/icons-material/RotateRight";
|
||||
import { updatePartCErrorData, updateSystemNo } from "../redux/actions/actions";
|
||||
import { updatePartCErrorList } from "../redux/actions/actions";
|
||||
import { DiscFullTwoTone } from "@mui/icons-material";
|
||||
|
||||
const QueryCardEditor = () => {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [barcode, setBarcode] = useState();
|
||||
const [qrcode, setQrcode] = useState();
|
||||
const [marks, setMarks] = useState(null);
|
||||
const [subjectCode, setSubjectCode] = useState(null);
|
||||
const [imageName, setImageName] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [recordData, setRecordData] = useState([]);
|
||||
const [s3Path, setS3Path] = useState(null);
|
||||
const [showDialog, setShowDialog] = useState(false);
|
||||
const [rotationResults, setRotationResults] = useState([]);
|
||||
const [rotateAngle, setRotateAngle] = useState(0);
|
||||
const evErrorsList = useSelector((state) => state?.partCErrorList);
|
||||
const table = searchParams.get("table");
|
||||
const image_name = searchParams.get("image_name");
|
||||
const paramsError = searchParams.get("error");
|
||||
const paramsErrorReason = searchParams.get("error_reason");
|
||||
const paramsSysNo = searchParams.get("sysNo");
|
||||
const paramsDegreeType = searchParams.get("degreeType");
|
||||
const [items, setItems] = useState([]);
|
||||
const [evErrorsData, setEvErrorsData] = useState([]);
|
||||
const barcodeInputRef = useRef(null);
|
||||
const qrInputRef = useRef(null);
|
||||
const marksInputRef = useRef(null);
|
||||
const subjectCodeInputRef = useRef(null);
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
console.log("Ev errors list ==== ", evErrorsList);
|
||||
console.log("table is : ", table);
|
||||
// const evErrorsData = useSelector((state) => state?.partCErrorData);
|
||||
// console.log("evErrorData: ", evErrorsData);
|
||||
|
||||
const fetchPrimaryKeyData = async () => {
|
||||
try {
|
||||
const payload = {
|
||||
image_name,
|
||||
table,
|
||||
};
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchPrimaryKeyData`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const marksLocalData = localStorage.getItem("marks_manual_data");
|
||||
console.log("Marks local data 123 ========= ", marksLocalData);
|
||||
if (marksLocalData) {
|
||||
console.log("Into if and updating .......");
|
||||
console.log("marks local data ==== ", marksLocalData);
|
||||
setEvErrorsData(JSON.parse(marksLocalData));
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(updateSystemNo(paramsSysNo));
|
||||
}, [paramsSysNo]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Ev error data =============== ", evErrorsData);
|
||||
}, [evErrorsData]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
if (table && image_name) {
|
||||
setIsLoading(true);
|
||||
const response = await fetchPrimaryKeyData();
|
||||
setIsLoading(false);
|
||||
console.log("Response is : ", response);
|
||||
if (response?.status === "success") {
|
||||
console.log("=========== Success ============");
|
||||
const data = response?.data;
|
||||
if (data.length > 0) {
|
||||
setRecordData(data[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("=========== Use effect triggered ===========");
|
||||
setBarcode(recordData?.barcode);
|
||||
setMarks(recordData?.marks);
|
||||
setQrcode(recordData?.qrcode);
|
||||
setImageName(recordData?.image_name);
|
||||
setSubjectCode(recordData?.subject_code);
|
||||
setS3Path(recordData?.s3_path);
|
||||
}, [recordData]);
|
||||
|
||||
const updateRecord = async () => {
|
||||
if (!marks) {
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const payload = {
|
||||
qrcode,
|
||||
barcode,
|
||||
table,
|
||||
s3Path,
|
||||
subjectCode,
|
||||
marks,
|
||||
imageName,
|
||||
rotateAngle,
|
||||
};
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartCdata`,
|
||||
{
|
||||
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 ...");
|
||||
var currentIndex = null;
|
||||
console.log(
|
||||
"Ev errors data before filter ============= ",
|
||||
evErrorsData
|
||||
);
|
||||
var newRecords = evErrorsData.filter((data, index) => {
|
||||
if (data?.image_name === imageName) {
|
||||
currentIndex = index;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (!currentIndex) {
|
||||
currentIndex = 0;
|
||||
}
|
||||
console.log("new records ======1 ", newRecords);
|
||||
console.log("Current Index ===== ", currentIndex);
|
||||
dispatch(updatePartCErrorData(newRecords));
|
||||
if (newRecords.length > 0) {
|
||||
console.log("Has to navigte 12 .....");
|
||||
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}`;
|
||||
console.log("new url ==== ", newUrl);
|
||||
window.location.href = newUrl;
|
||||
} else {
|
||||
navigate("/");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Rotate angle changed to ========== ", rotateAngle);
|
||||
const imageContainer = document.getElementById("img-container");
|
||||
console.log("Imge container ===== ", imageContainer);
|
||||
if (imageContainer) {
|
||||
imageContainer.style.transform = `rotate(${rotateAngle}deg)`;
|
||||
}
|
||||
}, [rotateAngle]);
|
||||
|
||||
const initateRotation = async () => {
|
||||
console.log("Rotating initiated ...");
|
||||
setIsLoading(true);
|
||||
const payload = {
|
||||
imageName,
|
||||
};
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/initateRotation`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
setIsLoading(false);
|
||||
const responseData = await response.json();
|
||||
console.log("Response data ======= ", responseData);
|
||||
if (responseData?.status === "success") {
|
||||
setShowDialog(true);
|
||||
setRotationResults(responseData?.result);
|
||||
}
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const skipPage = () => {
|
||||
try {
|
||||
if (evErrorsData) {
|
||||
var currentIndex = null;
|
||||
var newRecords = evErrorsData.filter((data, index) => {
|
||||
if (data?.image_name === imageName) {
|
||||
currentIndex = index;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (!currentIndex) {
|
||||
currentIndex = 0;
|
||||
}
|
||||
console.log("Current Index ===== ", currentIndex);
|
||||
const newIndex = currentIndex + 1;
|
||||
console.log("new index ===== ", newIndex);
|
||||
if (newRecords.length > 0) {
|
||||
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}`;
|
||||
console.log("new url ==== ", newUrl);
|
||||
window.location.href = newUrl;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = (e) => {
|
||||
try {
|
||||
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 === barcodeInputRef.current) {
|
||||
qrInputRef.current.focus();
|
||||
} else if (e.target === qrInputRef.current) {
|
||||
marksInputRef.current.focus();
|
||||
} else if (e.target === marksInputRef.current) {
|
||||
subjectCodeInputRef.current.focus();
|
||||
} else if (e.target === subjectCodeInputRef.current) {
|
||||
updateRecord();
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
return (
|
||||
<AntdesignLayout>
|
||||
<Box className="d-flex justify-content-between align-items-center">
|
||||
<Box className="d-flex flex-column gap-3 w-25">
|
||||
{imageName && <h5 className="text-left">ID : {imageName}</h5>}
|
||||
{paramsError && (
|
||||
<h5 className="text-left">Error Code : {paramsError}</h5>
|
||||
)}
|
||||
{paramsDegreeType ? (
|
||||
paramsDegreeType === 0 ? (
|
||||
<h5 className="text-left">Degree Type : UG</h5>
|
||||
) : (
|
||||
<h5 className="text-left">Degree Type : PG</h5>
|
||||
)
|
||||
) : null}
|
||||
<TextInputField
|
||||
placeholder="Barcode"
|
||||
value={barcode}
|
||||
setValue={setBarcode}
|
||||
onKeyDown={handleKeyDown}
|
||||
ref={barcodeInputRef}
|
||||
/>
|
||||
<TextInputField
|
||||
placeholder="QR Code"
|
||||
value={qrcode}
|
||||
setValue={setQrcode}
|
||||
onKeyDown={handleKeyDown}
|
||||
ref={qrInputRef}
|
||||
/>
|
||||
<TextInputField
|
||||
placeholder="Marks"
|
||||
value={marks}
|
||||
setValue={setMarks}
|
||||
onKeyDown={handleKeyDown}
|
||||
ref={marksInputRef}
|
||||
/>
|
||||
<TextInputField
|
||||
placeholder="Subject Code"
|
||||
value={subjectCode}
|
||||
setValue={setSubjectCode}
|
||||
onKeyDown={handleKeyDown}
|
||||
ref={subjectCodeInputRef}
|
||||
/>
|
||||
<Button
|
||||
className="bg-primary text-white rounded p-3"
|
||||
onClick={() => {
|
||||
updateRecord();
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-white rounded p-3"
|
||||
onClick={() => {
|
||||
skipPage();
|
||||
}}
|
||||
>
|
||||
Skip
|
||||
</Button>
|
||||
<Box className="d-flex justify-content-between">
|
||||
<Button
|
||||
className="bg-primary text-white rounded p-3"
|
||||
onClick={() => setRotateAngle((prev) => prev - 90)}
|
||||
>
|
||||
Rotate <RotateLeftIcon />
|
||||
</Button>
|
||||
<Button
|
||||
className="bg-primary text-white rounded p-3"
|
||||
onClick={() => setRotateAngle((prev) => prev + 90)}
|
||||
>
|
||||
Rotate <RotateRightIcon />
|
||||
</Button>
|
||||
</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>
|
||||
{isLoading && <LoadingContainer />}
|
||||
{showDialog && (
|
||||
<SimpleDialog
|
||||
type="rotation_results"
|
||||
rotationResults={rotationResults}
|
||||
setShowDialog={setShowDialog}
|
||||
/>
|
||||
)}
|
||||
</AntdesignLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default QueryCardEditor;
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
import React, { useState, useEffect } 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 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";
|
||||
|
||||
const { Header, Content, Footer, Sider } = Layout;
|
||||
const QueryExecutor = () => {
|
||||
const [responseData, setResponseData] = useState([]);
|
||||
const [totalData, setTotalData] = useState([]);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [totalPages, setTotalPages] = useState(0);
|
||||
const [imageColumn, setImageColumn] = useState(null);
|
||||
const [query, setQuery] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [paginationPages,setPaginationPages] = useState(null)
|
||||
const [limit, setLimit] = useState("");
|
||||
const recordsPerPage = 50;
|
||||
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(() => {
|
||||
if (totalData.length == 0 && reduxPlaygroundResults.length > 0) {
|
||||
setTotalData(reduxPlaygroundResults);
|
||||
setImageColumn("s3_path")
|
||||
}
|
||||
}, [reduxPlaygroundResults]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentPage == 0 && reduxPlaygroundPageNo !== 0) {
|
||||
console.log("Updating in use effect ============================= >")
|
||||
setCurrentPage(reduxPlaygroundPageNo);
|
||||
}
|
||||
}, [reduxPlaygroundPageNo]);
|
||||
|
||||
const fetchQueryValue = async () => {
|
||||
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("ocr_scanned_part_c_v1")
|
||||
) {
|
||||
alert("Selecting primary Key (image_name) is mandatory");
|
||||
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") {
|
||||
setTotalData(data.results);
|
||||
dispatch(updatePlaygroundResults(data?.results));
|
||||
const totalPageCount = Math.ceil(data?.results.length / recordsPerPage);
|
||||
setTotalPages(totalPageCount);
|
||||
dispatch(updatePlaygroundTotalPages(totalPages))
|
||||
setCurrentPage(1);
|
||||
setResponseData(data.results.slice(0, recordsPerPage));
|
||||
} else {
|
||||
// toast.error(data.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(updatePlaygroundQuery(query));
|
||||
}, [query]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
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]);
|
||||
|
||||
const getTableData = () => {
|
||||
if (responseData.length === 0) return null;
|
||||
const keys = Object.keys(totalData[0]);
|
||||
|
||||
return (
|
||||
<div className="w-100">
|
||||
<div className="text-left d-flex justify-content-between align-items-center">
|
||||
<h5>
|
||||
<strong>Total Results </strong> : {totalData.length}
|
||||
</h5>
|
||||
{totalData.length > 0 && (
|
||||
<div id="footer-container">
|
||||
<div
|
||||
id="footer-main"
|
||||
className="d-flex justify-content-center p-3 align-items-center"
|
||||
>
|
||||
<div className="d-flex justify-content-center align-items-center p-1">
|
||||
<Box className="d-flex flex-column align-items-end">
|
||||
<Box>{paginationPages}</Box>
|
||||
<Box>
|
||||
<strong>{currentPage}</strong>/
|
||||
<strong>{totalPages}</strong>
|
||||
</Box>
|
||||
</Box>
|
||||
</div>
|
||||
<div className="d-flex gap-3">
|
||||
{/* <button
|
||||
className="btn text-light bg-primary rounded p-2 mx-3"
|
||||
onClick={() =>
|
||||
setCurrentPage((prev) => Math.max(prev - 1, 1))
|
||||
}
|
||||
>
|
||||
Previous
|
||||
</button>
|
||||
<button
|
||||
className="btn text-light bg-primary rounded p-2"
|
||||
onClick={() =>
|
||||
setCurrentPage((prev) => Math.min(prev + 1, totalPages))
|
||||
}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
{} */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="my-2 overflow-auto">
|
||||
{responseData.map((data) => (
|
||||
<QueryExecutorCard
|
||||
data={data}
|
||||
s3_image_column={imageColumn}
|
||||
query={query}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
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}
|
||||
/>
|
||||
<TextInputField
|
||||
placeholder={"imageColumn"}
|
||||
value={imageColumn}
|
||||
setValue={setImageColumn}
|
||||
/>
|
||||
<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)}
|
||||
/>
|
||||
<TextField
|
||||
className="input rounded h6 bg-white"
|
||||
type="text"
|
||||
placeholder="Image column name"
|
||||
id="image-column-input"
|
||||
autoComplete="off"
|
||||
value={imageColumn}
|
||||
onChange={(e) => setImageColumn(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
className="btn bg-primary text-light"
|
||||
id="submit-btn"
|
||||
onClick={fetchQueryValue}
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="results-container"
|
||||
className="d-flex w-100 justify-content-center"
|
||||
>
|
||||
{getTableData()}
|
||||
</div>
|
||||
</div>
|
||||
{isLoading && <LoadingContainer />}
|
||||
</AntdesignLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default QueryExecutor;
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
import { Box, Button } from "@mui/material";
|
||||
import DownloadIcon from "@mui/icons-material/Download";
|
||||
import { LazyLoadImage } from "react-lazy-load-image-component";
|
||||
import { MoreHorizTwoTone } from "@mui/icons-material";
|
||||
import { useState, useEffect } from "react";
|
||||
import { ToastContainer, toast } from "react-toastify";
|
||||
import LoadingContainer from "./LoadingContainer";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason, reduxSystemNo,degreeType }) => {
|
||||
// console.log("ERROR ============= ",error)
|
||||
// console.log("ERROR REASON ============== ",error_reason)
|
||||
// console.log("REDUX SYSTEM NO ================== ",reduxSystemNo)
|
||||
const navigate = useNavigate()
|
||||
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([]);
|
||||
// console.log("image column ====== ", s3_image_column);
|
||||
// console.log("s3 image ======= ", data[s3_image_column]);
|
||||
// console.log("Keys ==== ",keys)
|
||||
// console.log("Values ===== ",values)
|
||||
|
||||
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 mark_as_ev = 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 mark_as_dummy = async () => {
|
||||
const payload = {
|
||||
data,
|
||||
};
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await fetch(
|
||||
`${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcDummyMarking`,
|
||||
{
|
||||
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, type: 102 };
|
||||
// console.log("Data ===== ", updatedData);
|
||||
setDataValue(updatedData);
|
||||
toast.success("Record Marked as Dummy ! ....");
|
||||
} else {
|
||||
throw new Error(responseData?.message);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
}
|
||||
|
||||
const mark_as_backpage = 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 {
|
||||
throw new Error(responseData?.message);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className="w-100 rounded shadow mb-5 bg-white">
|
||||
<ToastContainer />
|
||||
<Box className="p-4 d-flex justify-content-between align-items-start">
|
||||
<Box className="text-left p-3 d-flex flex-column justify-content-between align-items-between h-100">
|
||||
{keys.map((record, index) => (
|
||||
<p>
|
||||
<strong>{keys[index]}</strong> : {values[index]}
|
||||
</p>
|
||||
))}
|
||||
</Box>
|
||||
<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">
|
||||
<img
|
||||
src={`https://docs.exampaper.vidh.ai/${data[s3_image_column]}`}
|
||||
width="800px"
|
||||
height="auto"
|
||||
alt="Image Alt"
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
{isLoading && <LoadingContainer loadingText={"Loading ..."} />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default QueryExecutorCard;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
const QueryExecutortextArea = ({query,setQuery}) => {
|
||||
return (
|
||||
<>
|
||||
<textarea
|
||||
className="w-100 p-3 h5 bg-white"
|
||||
id="text-area-input"
|
||||
placeholder="Enter your query ...."
|
||||
rows="7"
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
></textarea>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default QueryExecutortextArea;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import {Box,Button} from '@mui/material'
|
||||
|
||||
const RecordEditor = () =>{
|
||||
return(
|
||||
<Box>
|
||||
hello
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default RecordEditor
|
||||
|
|
@ -1,57 +1,90 @@
|
|||
import React, { useState,useEffect } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Dialog from "@mui/material/Dialog";
|
||||
import DialogContent from "@mui/material/DialogContent";
|
||||
import DialogContentText from "@mui/material/DialogContentText";
|
||||
import DialogTitle from "@mui/material/DialogTitle";
|
||||
import { Button,Box } from "@mui/material";
|
||||
import { Button, Box } from "@mui/material";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import { NavLink,Link } from "react-router-dom";
|
||||
import { NavLink, Link } from "react-router-dom";
|
||||
|
||||
|
||||
const SimpleDialog = ({dialogBoxConsent,setDialogBoxConsent,showDialogBox,setShowDialogBox,dialogText,batchType}) => {
|
||||
const SimpleDialog = ({
|
||||
dialogBoxConsent,
|
||||
setDialogBoxConsent,
|
||||
showDialogBox,
|
||||
setShowDialogBox,
|
||||
dialogText,
|
||||
batchType,
|
||||
type,
|
||||
rotationResults,
|
||||
setShowDialog,
|
||||
}) => {
|
||||
const [open, setOpen] = useState(true); // Set open state to true by default
|
||||
const [examCentreCode,setExamCentreCode] = useState(null)
|
||||
const [examDate,setExamDate] = useState(null)
|
||||
const [metaDataLink,setMetaDataLink] = useState(null)
|
||||
const MetabaseLink = "http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf"
|
||||
console.log("MetabaseLink : ",MetabaseLink)
|
||||
console.log(import.meta.env)
|
||||
const [examCentreCode, setExamCentreCode] = useState(null);
|
||||
const [examDate, setExamDate] = useState(null);
|
||||
const [metaDataLink, setMetaDataLink] = useState(null);
|
||||
const MetabaseLink =
|
||||
"http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf";
|
||||
console.log("MetabaseLink : ", MetabaseLink);
|
||||
console.log(import.meta.env);
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
console.log("Rotation Results : ", rotationResults);
|
||||
|
||||
const handleYes = () =>{
|
||||
const handleYes = () => {
|
||||
console.log("Consent is : ", dialogBoxConsent);
|
||||
console.log("Dialog text before if condition :: ",dialogText)
|
||||
console.log("showDialog Box : ",showDialogBox)
|
||||
console.log("Setting Conset Yes")
|
||||
setDialogBoxConsent("Yes")
|
||||
setShowDialogBox(false)
|
||||
}
|
||||
const handleNo = () =>{
|
||||
console.log("Dialog text before if condition :: ", dialogText);
|
||||
console.log("showDialog Box : ", showDialogBox);
|
||||
console.log("Setting Conset Yes");
|
||||
setDialogBoxConsent("Yes");
|
||||
setShowDialogBox(false);
|
||||
};
|
||||
const handleNo = () => {
|
||||
console.log("Consent is : ", dialogBoxConsent);
|
||||
console.log("Dialog text before if condition :: ",dialogText)
|
||||
console.log("showDialog Box : ",showDialogBox)
|
||||
console.log("Setting consent NO")
|
||||
setDialogBoxConsent("No")
|
||||
setShowDialogBox(false)
|
||||
}
|
||||
console.log("Dialog text before if condition :: ", dialogText);
|
||||
console.log("showDialog Box : ", showDialogBox);
|
||||
console.log("Setting consent NO");
|
||||
setDialogBoxConsent("No");
|
||||
setShowDialogBox(false);
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
if(examCentreCode && examDate){
|
||||
setMetaDataLink(`http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf?internal_exam_centre_code=${examCentreCode}&ref_exam_date=${examDate}`)
|
||||
const handleKeyPress = (event) => {
|
||||
if (event.key === "n" || event.key === "N") {
|
||||
console.log('The "N" key was pressed!');
|
||||
handleNo();
|
||||
} else if (event.key === "Y" || event.key === "y") {
|
||||
console.log("Y is pressed");
|
||||
handleYes();
|
||||
}
|
||||
},[examDate,examCentreCode])
|
||||
};
|
||||
|
||||
// Use useEffect to add the event listener
|
||||
useEffect(() => {
|
||||
window.addEventListener("keydown", handleKeyPress);
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyPress);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (examCentreCode && examDate) {
|
||||
setMetaDataLink(
|
||||
`http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf?internal_exam_centre_code=${examCentreCode}&ref_exam_date=${examDate}`
|
||||
);
|
||||
}
|
||||
}, [examDate, examCentreCode]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={handleClose}>
|
||||
<DialogTitle>Error :</DialogTitle>
|
||||
<DialogContent>
|
||||
{type !== "rotation_results" ? (
|
||||
<DialogContentText>
|
||||
<h6>Missing Data - {dialogText}</h6>
|
||||
Data Entered Is Not found in the DB.Do you want to Continue editing ??
|
||||
{batchType == "new" && <Box className="d-flex gap-4 my-4">
|
||||
|
||||
Data Entered Is Not found in the DB.Do you want to Continue editing
|
||||
??
|
||||
{batchType == "new" && (
|
||||
<Box className="d-flex gap-4 my-4">
|
||||
{/* <Link to={MetabaseLink} target="_blank">{MetabaseLink}</Link> */}
|
||||
{/* <TextField
|
||||
value={examCentreCode}
|
||||
|
|
@ -69,18 +102,42 @@ const SimpleDialog = ({dialogBoxConsent,setDialogBoxConsent,showDialogBox,setSh
|
|||
label={"Exam Date"}
|
||||
autoComplete="off"
|
||||
/> */}
|
||||
</Box>}
|
||||
</Box>
|
||||
)}
|
||||
{/* {
|
||||
metaDataLink && <iframe width="1000px" height="800px" src={metaDataLink}/>
|
||||
} */}
|
||||
<Box className="d-flex justify-content-end gap-2 my-3">
|
||||
<Button className="bg-primary p-2 text-light" onClick={handleYes}>YES</Button>
|
||||
<Button className="bg-primary p-2 text-light" onClick={handleNo}>NO</Button>
|
||||
<Button className="bg-primary p-2 text-light" onClick={handleYes}>
|
||||
YES
|
||||
</Button>
|
||||
<Button className="bg-primary p-2 text-light" onClick={handleNo}>
|
||||
NO
|
||||
</Button>
|
||||
</Box>
|
||||
</DialogContentText>
|
||||
) : (
|
||||
<Box>
|
||||
<DialogContentText>
|
||||
<Box className="d-flex flex-column">
|
||||
Backage : {rotationResults?.is_backpage}
|
||||
Is EV cover : {rotationResults?.is_cover}
|
||||
Category Found : {rotationResults?.categoryFound}
|
||||
</Box>
|
||||
</DialogContentText>
|
||||
<Box className="py-3 d-flex justify-content-end">
|
||||
<Button
|
||||
className="bg-primary text-white p-2"
|
||||
onClick={() => setShowDialog(false)}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default SimpleDialog;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { Box, Button } from "@mui/material";
|
||||
|
||||
import AntdesignLayout from "./AntdesignLayout";
|
||||
import TextInputField from "./TextInputField";
|
||||
|
||||
const StudentResultsData = () => {
|
||||
const [registerNumber, setRegisterNumber] = useState();
|
||||
const [scannedValue, setScannedValue] = useState();
|
||||
return (
|
||||
<AntdesignLayout>
|
||||
<Box>
|
||||
<Box className="d-flex justify-content-center gap-3 flex-row">
|
||||
<TextInputField
|
||||
placeholder={"Register Number"}
|
||||
value={registerNumber}
|
||||
setValue={setRegisterNumber}
|
||||
/>
|
||||
<TextInputField
|
||||
placeholder={"Scanned Value"}
|
||||
value={scannedValue}
|
||||
setValue={setScannedValue}
|
||||
/>
|
||||
<Box>
|
||||
<Button className="bg-primary text-white p-3 rounded">Search</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</AntdesignLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default StudentResultsData;
|
||||
|
|
@ -11,6 +11,12 @@ 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";
|
||||
|
||||
|
||||
export default function TableComponent({
|
||||
filterSelectedExamCentreCode,
|
||||
|
|
@ -18,7 +24,7 @@ export default function TableComponent({
|
|||
rows,
|
||||
type,
|
||||
distinctExamCentreCodes,
|
||||
batchType
|
||||
batchType,
|
||||
}) {
|
||||
// console.log("Exam centre code in table component : ",distinctExamCentreCodes)
|
||||
console.log("Rows in table component : ", rows);
|
||||
|
|
@ -26,6 +32,33 @@ export default function TableComponent({
|
|||
const [page, setPage] = React.useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = React.useState(5);
|
||||
|
||||
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
||||
const [currentImagePath, setCurrentImagePath] = React.useState('');
|
||||
|
||||
const [openLoader, setOpenLoader] = React.useState(false);
|
||||
const handleCloseLoader = () => {
|
||||
setOpenLoader(false);
|
||||
};
|
||||
const handleOpenLoader = () => {
|
||||
setOpenLoader(true);
|
||||
};
|
||||
|
||||
const [state, setState] = React.useState({
|
||||
open: false,
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
message: ''
|
||||
});
|
||||
const { vertical, horizontal, open, message } = state;
|
||||
|
||||
const handleClick = (newState) => () => {
|
||||
setState({ ...newState, open: true });
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setState({ ...state, open: false });
|
||||
};
|
||||
|
||||
// Avoid a layout jump when reaching the last page with empty rows.
|
||||
const emptyRows =
|
||||
page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0;
|
||||
|
|
@ -44,6 +77,66 @@ export default function TableComponent({
|
|||
setFilterSelectedExamCentreCode(ExamCentreCode);
|
||||
};
|
||||
|
||||
const handleImageClick = (imagePath) => {
|
||||
console.log("imagepath:",imagePath)
|
||||
setCurrentImagePath(imagePath);
|
||||
setIsDialogOpen(true)
|
||||
};
|
||||
|
||||
const handleCloseDialog = () => {
|
||||
setIsDialogOpen(false);
|
||||
setCurrentImagePath('');
|
||||
};
|
||||
|
||||
const [file, setFile] = React.useState(null);
|
||||
const [csvData, setCsvData] = React.useState([]);
|
||||
|
||||
const handleFileChange = (event) => {
|
||||
setFile(event.target.files[0]);
|
||||
console.log("event.target.files[0]: ",event.target.files[0])
|
||||
};
|
||||
|
||||
const handleFileUpload = async () => {
|
||||
if (!file) {
|
||||
alert('Please upload a CSV file first.');
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
try {
|
||||
handleOpenLoader()
|
||||
const response = await fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/uploadAdditionalAttendanceCsv`,
|
||||
{
|
||||
method: "POST",
|
||||
body: formData
|
||||
}
|
||||
)
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
console.log('File uploaded successfully:', data);
|
||||
handleCloseLoader()
|
||||
toast.success(data.message);
|
||||
// handleClick({ vertical: 'top', horizontal: 'right', message:data.message })
|
||||
} else {
|
||||
console.error('File upload failed:', response.statusText);
|
||||
handleCloseLoader()
|
||||
toast.error("failed to upload");
|
||||
// handleClick({ vertical: 'top', horizontal: 'right', message:data.message })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error uploading file:', error);
|
||||
handleCloseLoader()
|
||||
toast.error("failed to upload");
|
||||
// handleClick({ vertical: 'top', horizontal: 'right', message:data.message })
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Root className="overflow-auto" sx={{ maxWidth: "100%", width: 1200 }}>
|
||||
{type === "AnomolyReassigned" && (
|
||||
|
|
@ -90,9 +183,9 @@ export default function TableComponent({
|
|||
<td>{row.attendence_serial_no}</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<Link
|
||||
to={`/anomoly/reassigned/booklet?sno=${row.student_slno}`}
|
||||
to={`/anomoly/reassigned/booklet?sno=${row?.answer_booklet_sno}`}
|
||||
>
|
||||
{row.student_slno}
|
||||
{row.answer_booklet_sno}
|
||||
</Link>
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
|
|
@ -302,7 +395,9 @@ export default function TableComponent({
|
|||
).map((row) => (
|
||||
<tr key={row.exam_centre_code}>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<Link to={`/anomoly/partA/booklet?batchType=${batchType}&barcode=${row.barcode}&s3Path=${row.s3_path}&sysNo=${row.systemNo}`}>
|
||||
<Link
|
||||
to={`/anomoly/partA/booklet?batchType=${batchType}&barcode=${row.barcode}&s3Path=${row.s3_path}&sysNo=${row.systemNo}`}
|
||||
>
|
||||
{row?.s3_path}
|
||||
</Link>
|
||||
</td>
|
||||
|
|
@ -351,6 +446,220 @@ export default function TableComponent({
|
|||
</table>
|
||||
</>
|
||||
)}
|
||||
{type === "AttendenceAdditionalRecord" && (
|
||||
<>
|
||||
<h5 className="py-2">Part-A Anomoly Data :</h5>
|
||||
<table aria-label="custom pagination table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>qrcode</th>
|
||||
<th>Cover A</th>
|
||||
<th>Cover B</th>
|
||||
<th>Subject Code</th>
|
||||
<th>Total Students</th>
|
||||
<th>Total Present</th>
|
||||
<th>Total Absent</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(rowsPerPage > 0
|
||||
? rows.slice(
|
||||
page * rowsPerPage,
|
||||
page * rowsPerPage + rowsPerPage
|
||||
)
|
||||
: rows
|
||||
).map((row) => (
|
||||
<tr key={row.exam_centre_code}>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<Link
|
||||
to={`/anomoly/attendence/additionalRecord/correction?qrcode=${row.qrcode}`}
|
||||
>
|
||||
{row?.qrcode}
|
||||
</Link>
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.coverA}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.coverB}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.subject_code}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.total_students}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.total_present}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.total_absent}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<tr style={{ height: 41 * emptyRows }}>
|
||||
<td colSpan={3} aria-hidden />
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<CustomTablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
|
||||
colSpan={3}
|
||||
count={rows.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
"aria-label": "rows per page",
|
||||
},
|
||||
actions: {
|
||||
showFirstButton: true,
|
||||
showLastButton: true,
|
||||
},
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</>
|
||||
)}
|
||||
{type === "AdditionalSheet" && (
|
||||
<>
|
||||
<h5 className="py-2">Attendance Additional Sheet</h5>
|
||||
<div style={{ width: '200px', height: '50px', backgroundColor: 'lightblue', display: 'flex', justifyContent: 'center', alignItems: 'center', borderRadius: '5px' }}>
|
||||
<a
|
||||
style={{
|
||||
textDecoration: 'none',
|
||||
color: 'black',
|
||||
padding: '10px 20px',
|
||||
backgroundColor: 'white',
|
||||
border: '1px solid black',
|
||||
borderRadius: '5px',
|
||||
textAlign: 'center',
|
||||
display: 'inline-block'
|
||||
}}
|
||||
href={"/src/assets/additional_attendance_template.csv"}
|
||||
download={"additional_attendance_template.csv"}
|
||||
>
|
||||
Download Template CSV
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<p>Please download the CSV file and by verifying the image type appropriately</p>
|
||||
|
||||
<table aria-label="custom pagination table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Image Name</th>
|
||||
<th>upload csv</th>
|
||||
<th>Image</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(rowsPerPage > 0
|
||||
? rows.slice(
|
||||
page * rowsPerPage,
|
||||
page * rowsPerPage + rowsPerPage
|
||||
)
|
||||
: rows
|
||||
).map((row) => (
|
||||
<tr key={row.exam_centre_code}>
|
||||
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.image_name}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<div>
|
||||
<input type="file" accept=".csv" onChange={handleFileChange} />
|
||||
<button style={{width:'130px', height:'30px', fontSize:'12px', textAlign:'center'}} onClick={handleFileUpload}>Upload CSV</button>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<div>
|
||||
<span style={{cursor:'pointer', color:'blue'}} onClick={() => handleImageClick(row.s3_image_path)}>
|
||||
Preview Image
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<a style={{textDecoration: 'none'}} href={`https://docs.exampaper.vidh.ai/${row.s3_image_path}`} download>
|
||||
Download Image
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
{/* <td style={{ width: 160 }} align="right">
|
||||
<Link
|
||||
to={`www.google.com`}
|
||||
>
|
||||
{row?.s3_image_path}
|
||||
</Link>
|
||||
</td> */}
|
||||
</tr>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<tr style={{ height: 41 * emptyRows }}>
|
||||
<td colSpan={3} aria-hidden />
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<CustomTablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
|
||||
colSpan={3}
|
||||
count={rows.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
"aria-label": "rows per page",
|
||||
},
|
||||
actions: {
|
||||
showFirstButton: true,
|
||||
showLastButton: true,
|
||||
},
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</>
|
||||
)}
|
||||
{
|
||||
isDialogOpen && (
|
||||
<ImageDialog
|
||||
imagePath={currentImagePath}
|
||||
setIsDialogOpen={setIsDialogOpen}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<Backdrop
|
||||
sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.drawer + 1 }}
|
||||
open={openLoader}
|
||||
>
|
||||
<CircularProgress color="inherit" />
|
||||
</Backdrop>
|
||||
|
||||
<Box sx={{ width: 500 }}>
|
||||
<Snackbar
|
||||
anchorOrigin={{ vertical, horizontal }}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
message={message}
|
||||
key={vertical + horizontal}
|
||||
/>
|
||||
</Box>
|
||||
<ToastContainer />
|
||||
</Root>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,702 @@
|
|||
import * as React from "react";
|
||||
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 ImageDialog from "./ImageDialog";
|
||||
import { Button } from "bootstrap";
|
||||
|
||||
export default function TableComponentAdditionalSheet({
|
||||
filterSelectedExamCentreCode,
|
||||
setFilterSelectedExamCentreCode,
|
||||
rows,
|
||||
type,
|
||||
distinctExamCentreCodes,
|
||||
batchType,
|
||||
}) {
|
||||
// console.log("Exam centre code in table component : ",distinctExamCentreCodes)
|
||||
console.log("Rows in table component : ", rows);
|
||||
// console.log("Type is : ", type);
|
||||
const [page, setPage] = React.useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = React.useState(5);
|
||||
|
||||
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
||||
const [currentImagePath, setCurrentImagePath] = React.useState('');
|
||||
|
||||
const [openLoader, setOpenLoader] = React.useState(false);
|
||||
const handleCloseLoader = () => {
|
||||
setOpenLoader(false);
|
||||
};
|
||||
const handleOpenLoader = () => {
|
||||
setOpenLoader(true);
|
||||
};
|
||||
|
||||
// Avoid a layout jump when reaching the last page with empty rows.
|
||||
const emptyRows =
|
||||
page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0;
|
||||
|
||||
const handleChangePage = (event, newPage) => {
|
||||
setPage(newPage);
|
||||
};
|
||||
|
||||
const handleChangeRowsPerPage = (event) => {
|
||||
setRowsPerPage(parseInt(event.target.value, 10));
|
||||
setPage(0);
|
||||
};
|
||||
|
||||
const handleFilterExamCentreCode = (e) => {
|
||||
const ExamCentreCode = e.target.value;
|
||||
setFilterSelectedExamCentreCode(ExamCentreCode);
|
||||
};
|
||||
|
||||
const handleImageClick = (imagePath) => {
|
||||
console.log("imagepath:",imagePath)
|
||||
setCurrentImagePath(imagePath);
|
||||
setIsDialogOpen(true)
|
||||
};
|
||||
|
||||
const handleCloseDialog = () => {
|
||||
setIsDialogOpen(false);
|
||||
setCurrentImagePath('');
|
||||
};
|
||||
|
||||
const [file, setFile] = React.useState(null);
|
||||
const [csvData, setCsvData] = React.useState([]);
|
||||
|
||||
const handleFileChange = (event) => {
|
||||
setFile(event.target.files[0]);
|
||||
console.log("event.target.files[0]: ",event.target.files[0])
|
||||
};
|
||||
|
||||
const handleFileUpload = async () => {
|
||||
if (!file) {
|
||||
alert('Please upload a CSV file first.');
|
||||
return;
|
||||
}
|
||||
handleOpenLoader()
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${
|
||||
import.meta.env.VITE_REACT_APP_BACKEND_URL
|
||||
}/uploadAdditionalAttendanceCsv`,
|
||||
{
|
||||
method: "POST",
|
||||
body: formData
|
||||
}
|
||||
)
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
console.log('File uploaded successfully:', data);
|
||||
handleCloseLoader()
|
||||
|
||||
} else {
|
||||
console.error('File upload failed:', response.statusText);
|
||||
handleCloseLoader()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error uploading file:', error);
|
||||
handleCloseLoader()
|
||||
}
|
||||
};
|
||||
|
||||
const parseCSV = (text) => {
|
||||
const rows = text.split('\n');
|
||||
const data = rows.map(row => row.split(','));
|
||||
setCsvData(data);
|
||||
};
|
||||
|
||||
return (
|
||||
<Root className="overflow-auto" sx={{ maxWidth: "100%", width: 1200 }}>
|
||||
{type === "AnomolyReassigned" && (
|
||||
<>
|
||||
<h5 className="py-2">Manual Verification Needed Students :</h5>
|
||||
{/* <Box className="py-2">
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="demo-simple-select-label">Exam Centre Code</InputLabel>
|
||||
<Select
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
label="Exam Centre Code"
|
||||
onChange={handleFilterExamCentreCode}
|
||||
>
|
||||
{distinctExamCentreCodes.length > 0 && (
|
||||
distinctExamCentreCodes.map((exam_centre_code)=>(
|
||||
<MenuItem key={exam_centre_code} value={exam_centre_code}>{exam_centre_code}</MenuItem>
|
||||
))
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box> */}
|
||||
<table aria-label="custom pagination table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Attendance Image</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(rowsPerPage > 0
|
||||
? rows.slice(
|
||||
page * rowsPerPage,
|
||||
page * rowsPerPage + rowsPerPage
|
||||
)
|
||||
: rows
|
||||
).map((row) => (
|
||||
<tr key={row.attendence_serial_no}>
|
||||
<td>{row.attendence_serial_no}</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{/* <Link
|
||||
to={`/anomoly/reassigned/booklet?sno=${row?.answer_booklet_sno}`}
|
||||
>
|
||||
{row.answer_booklet_sno}
|
||||
</Link> */}
|
||||
</td>
|
||||
{/* <td style={{ width: 160 }} align="right">
|
||||
{row.exam_centre_code}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.exam_centre}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.student_name}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.register_number}
|
||||
</td> */}
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.s3_path}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<tr style={{ height: 41 * emptyRows }}>
|
||||
<td colSpan={3} aria-hidden />
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<CustomTablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
|
||||
colSpan={3}
|
||||
count={rows.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
"aria-label": "rows per page",
|
||||
},
|
||||
actions: {
|
||||
showFirstButton: true,
|
||||
showLastButton: true,
|
||||
},
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</>
|
||||
)}
|
||||
{type === "ReassignedStats" && (
|
||||
<>
|
||||
<h5 className="py-2">Exam Centre Code Complete MetaData :</h5>
|
||||
<table aria-label="custom pagination table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Exam Centre Code</th>
|
||||
<th>Total Scanned Count</th>
|
||||
<th>Manual Verification Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(rowsPerPage > 0
|
||||
? rows.slice(
|
||||
page * rowsPerPage,
|
||||
page * rowsPerPage + rowsPerPage
|
||||
)
|
||||
: rows
|
||||
).map((row) => (
|
||||
<tr key={row.exam_centre_code}>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<a
|
||||
href={`/anomoly/reassigned/stats/${row.exam_centre_code}`}
|
||||
>
|
||||
{row.exam_centre_code}
|
||||
</a>
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.total_count}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.manual_verification_count}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<tr style={{ height: 41 * emptyRows }}>
|
||||
<td colSpan={3} aria-hidden />
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<CustomTablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
|
||||
colSpan={3}
|
||||
count={rows.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
"aria-label": "rows per page",
|
||||
},
|
||||
actions: {
|
||||
showFirstButton: true,
|
||||
showLastButton: true,
|
||||
},
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</>
|
||||
)}
|
||||
{type === "IndividualReassignedStats" && (
|
||||
<>
|
||||
<h5 className="py-2">Exam Centre Code-Date Wise MetaData :</h5>
|
||||
<table aria-label="custom pagination table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Exam Centre Code</th>
|
||||
<th>Exam Date</th>
|
||||
<th>Subject Code</th>
|
||||
<th>Total Count</th>
|
||||
<th>Manual Verification Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(rowsPerPage > 0
|
||||
? rows.slice(
|
||||
page * rowsPerPage,
|
||||
page * rowsPerPage + rowsPerPage
|
||||
)
|
||||
: rows
|
||||
).map((row) => (
|
||||
<tr key={row.exam_centre_code}>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.exam_centre_code}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.exam_date}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.subject_code}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.total_count}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.manual_verification_needed_count}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<tr style={{ height: 41 * emptyRows }}>
|
||||
<td colSpan={3} aria-hidden />
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<CustomTablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
|
||||
colSpan={3}
|
||||
count={rows.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
"aria-label": "rows per page",
|
||||
},
|
||||
actions: {
|
||||
showFirstButton: true,
|
||||
showLastButton: true,
|
||||
},
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</>
|
||||
)}
|
||||
{type === "PartAReassigned" && (
|
||||
<>
|
||||
<h5 className="py-2">Part-A Anomoly Data :</h5>
|
||||
<table aria-label="custom pagination table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>s3_path</th>
|
||||
<th>Barcode</th>
|
||||
<th>Subject Code</th>
|
||||
<th>Register Number</th>
|
||||
<th>Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(rowsPerPage > 0
|
||||
? rows.slice(
|
||||
page * rowsPerPage,
|
||||
page * rowsPerPage + rowsPerPage
|
||||
)
|
||||
: rows
|
||||
).map((row) => (
|
||||
<tr key={row.exam_centre_code}>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<Link
|
||||
to={`/anomoly/partA/booklet?batchType=${batchType}&barcode=${row.barcode}&s3Path=${row.s3_path}&sysNo=${row.systemNo}`}
|
||||
>
|
||||
{row?.s3_path}
|
||||
</Link>
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.barcode}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.subject_code}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.register_number}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.type}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<tr style={{ height: 41 * emptyRows }}>
|
||||
<td colSpan={3} aria-hidden />
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<CustomTablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
|
||||
colSpan={3}
|
||||
count={rows.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
"aria-label": "rows per page",
|
||||
},
|
||||
actions: {
|
||||
showFirstButton: true,
|
||||
showLastButton: true,
|
||||
},
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</>
|
||||
)}
|
||||
{type === "AttendenceAdditionalRecord" && (
|
||||
<>
|
||||
<h5 className="py-2">Part-A Anomoly Data :</h5>
|
||||
<table aria-label="custom pagination table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>qrcode</th>
|
||||
<th>Cover A</th>
|
||||
<th>Cover B</th>
|
||||
<th>Subject Code</th>
|
||||
<th>Total Students</th>
|
||||
<th>Total Present</th>
|
||||
<th>Total Absent</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(rowsPerPage > 0
|
||||
? rows.slice(
|
||||
page * rowsPerPage,
|
||||
page * rowsPerPage + rowsPerPage
|
||||
)
|
||||
: rows
|
||||
).map((row) => (
|
||||
<tr key={row.exam_centre_code}>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<Link
|
||||
to={`/anomoly/attendence/additionalRecord/correction?qrcode=${row.qrcode}`}
|
||||
>
|
||||
{row?.qrcode}
|
||||
</Link>
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.coverA}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.coverB}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.subject_code}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.total_students}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.total_present}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.total_absent}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<tr style={{ height: 41 * emptyRows }}>
|
||||
<td colSpan={3} aria-hidden />
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<CustomTablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
|
||||
colSpan={3}
|
||||
count={rows.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
"aria-label": "rows per page",
|
||||
},
|
||||
actions: {
|
||||
showFirstButton: true,
|
||||
showLastButton: true,
|
||||
},
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</>
|
||||
)}
|
||||
{type === "AdditionalSheet" && (
|
||||
<>
|
||||
<h5 className="py-2">Attendance Additional Sheet</h5>
|
||||
<div style={{ width: '200px', height: '50px', backgroundColor: 'lightblue', display: 'flex', justifyContent: 'center', alignItems: 'center', borderRadius: '5px' }}>
|
||||
<a
|
||||
style={{
|
||||
textDecoration: 'none',
|
||||
color: 'black',
|
||||
padding: '10px 20px',
|
||||
backgroundColor: 'white',
|
||||
border: '1px solid black',
|
||||
borderRadius: '5px',
|
||||
textAlign: 'center',
|
||||
display: 'inline-block'
|
||||
}}
|
||||
href="/assets/csv/additional_attedance_sheet_template.csv"
|
||||
download="additional_attedance_sheet_template.csv"
|
||||
>
|
||||
Download Template CSV
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<p>Please download the CSV file and by verifying the image type appropriately</p>
|
||||
|
||||
<table aria-label="custom pagination table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Image Name</th>
|
||||
<th>upload csv</th>
|
||||
<th>Image</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{(rowsPerPage > 0
|
||||
? rows.slice(
|
||||
page * rowsPerPage,
|
||||
page * rowsPerPage + rowsPerPage
|
||||
)
|
||||
: rows
|
||||
).map((row) => (
|
||||
<tr key={row.exam_centre_code}>
|
||||
|
||||
<td style={{ width: 160 }} align="right">
|
||||
{row.image_name}
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<div>
|
||||
<input type="file" accept=".csv" onChange={handleFileChange} />
|
||||
<button style={{width:'130px', height:'30px', fontSize:'12px', textAlign:'center'}} onClick={handleFileUpload}>Upload CSV</button>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
<td style={{ width: 160 }} align="right">
|
||||
<div>
|
||||
<span style={{cursor:'pointer', color:'blue'}} onClick={() => handleImageClick(row.s3_image_path)}>
|
||||
Preview Image
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<a style={{textDecoration: 'none'}} href={`https://docs.exampaper.vidh.ai/${row.s3_image_path}`} download>
|
||||
Download Image
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
{/* <td style={{ width: 160 }} align="right">
|
||||
<Link
|
||||
to={`www.google.com`}
|
||||
>
|
||||
{row?.s3_image_path}
|
||||
</Link>
|
||||
</td> */}
|
||||
</tr>
|
||||
))}
|
||||
{emptyRows > 0 && (
|
||||
<tr style={{ height: 41 * emptyRows }}>
|
||||
<td colSpan={3} aria-hidden />
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<CustomTablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
|
||||
colSpan={3}
|
||||
count={rows.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
slotProps={{
|
||||
select: {
|
||||
"aria-label": "rows per page",
|
||||
},
|
||||
actions: {
|
||||
showFirstButton: true,
|
||||
showLastButton: true,
|
||||
},
|
||||
}}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</>
|
||||
)}
|
||||
{
|
||||
isDialogOpen && (
|
||||
<ImageDialog
|
||||
imagePath={currentImagePath}
|
||||
setIsDialogOpen={setIsDialogOpen}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<Backdrop
|
||||
sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.drawer + 1 }}
|
||||
open={openLoader}
|
||||
>
|
||||
<CircularProgress color="inherit" />
|
||||
</Backdrop>
|
||||
|
||||
</Root>
|
||||
);
|
||||
}
|
||||
|
||||
const grey = {
|
||||
50: "#F3F6F9",
|
||||
100: "#E5EAF2",
|
||||
200: "#DAE2ED",
|
||||
300: "#C7D0DD",
|
||||
400: "#B0B8C4",
|
||||
500: "#9DA8B7",
|
||||
600: "#6B7A90",
|
||||
700: "#434D5B",
|
||||
800: "#303740",
|
||||
900: "#1C2025",
|
||||
};
|
||||
|
||||
const Root = styled("div")(
|
||||
({ theme }) => `
|
||||
table {
|
||||
font-family: 'IBM Plex Sans', sans-serif;
|
||||
font-size: 0.875rem;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
border: 1px solid ${theme.palette.mode === "dark" ? grey[800] : grey[200]};
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: ${theme.palette.mode === "dark" ? grey[900] : "#fff"};
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
const CustomTablePagination = styled(TablePagination)`
|
||||
& .${classes.toolbar} {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
& .${classes.selectLabel} {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& .${classes.displayedRows} {
|
||||
margin: 0;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
& .${classes.spacer} {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& .${classes.actions} {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
`;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { TextField, Box } from "@mui/material";
|
||||
import React from 'react';
|
||||
|
||||
const TextInputField = React.forwardRef(({ placeholder, value, setValue, onKeyDown }, ref) => {
|
||||
return (
|
||||
<Box className="d-flex flex-column">
|
||||
<label htmlFor="limit-input" className="text-left">
|
||||
{placeholder} :-
|
||||
</label>
|
||||
<TextField
|
||||
className="rounded h6 bg-white"
|
||||
type="text"
|
||||
placeholder={placeholder}
|
||||
id="limit-input"
|
||||
autoComplete="off"
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
onKeyDown={onKeyDown}
|
||||
inputRef={ref}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
|
||||
export default TextInputField;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { Box } from "@mui/material";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
|
||||
import AntdesignLayout from "./AntdesignLayout";
|
||||
import QueryExecutortextArea from "./QueryExecutortextArea";
|
||||
|
||||
|
||||
const VerifyMarks = () => {
|
||||
const [query, setQuery] = useState(null);
|
||||
return (
|
||||
<AntdesignLayout>
|
||||
<Box>
|
||||
<QueryExecutortextArea query={query} setQuery={setQuery}/>
|
||||
</Box>
|
||||
</AntdesignLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default VerifyMarks;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
filename*,enter filename,"INSTUCTIONS: Present means mark '0', Absent means mark '1', Assigned means mark as 0, Reassigned means mark '1'. NOTE: all '*' fields are mandatory so please all '*' compulsory. Get filename from the UI which is as Imagename",,,
|
||||
,,,,,
|
||||
subject_code*,enter subject_code,,,,
|
||||
exam_centre_code*,enter exam_centre_code,,,,
|
||||
subject_title*,enter subject_title,,,,
|
||||
degree_with_branch*,enter degree_with_branch,,,,
|
||||
exam_date*,enter exam_date,,,,
|
||||
exam_date_session,enter exam_date_session,,,,
|
||||
cover_a,enter cover_a,,,,
|
||||
cover_b,enter cover_b,,,,
|
||||
,,,,,
|
||||
student_data,,,,,
|
||||
sno*,register_number*,Present/Absent*,Assigned/Reassigned*,reassigned_sno*,signed*
|
||||
1,,,,,
|
||||
|
|
|
@ -66,3 +66,21 @@ button:focus-visible {
|
|||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: 1px solid black !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
th,
|
||||
td {
|
||||
padding: 5px;
|
||||
border: 1px solid black !important;
|
||||
text-align: left;
|
||||
}
|
||||
|
|
@ -1,14 +1,69 @@
|
|||
export const updateAttendenceAnomolyData = (data) =>({
|
||||
type:"UPDATE_ATTENDENCE_ANOMOLY_DATA",
|
||||
payload:data,
|
||||
})
|
||||
export const updateAttendenceAnomolyData = (data) => ({
|
||||
type: "UPDATE_ATTENDENCE_ANOMOLY_DATA",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updatePartAanomolyData = (data) =>({
|
||||
type:"UPDATE_PART-A_ANOMOLY_DATA",
|
||||
payload:data
|
||||
})
|
||||
export const updatePartAanomolyData = (data) => ({
|
||||
type: "UPDATE_PART-A_ANOMOLY_DATA",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updateSystemNo = (data) => ({
|
||||
type:"UPDATE_SYSTEM_NO",
|
||||
payload:data
|
||||
type: "UPDATE_SYSTEM_NO",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updatePlaygroundQuery = (data) => ({
|
||||
type: "UPDATE_PLAYGROUND_QUERY",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updatePlaygroundCurrentPage = (data) => ({
|
||||
type: "UPDATE_PLAYGROUND_PAGENO",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updatePlaygroundTotalPages = (data) => ({
|
||||
type: "UPDATE_PLAYGROUND_TOTAL_PAGES",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updatePlaygroundResults = (data) => ({
|
||||
type: "UPDATE_PLAYGROUND_RESULTS",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updatePartCErrorList = (data) => ({
|
||||
type: "UPDATE_PARTC_ERROR_LIST",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updatePartCErrorData = (data) => ({
|
||||
type: "UPDATE_PARTC_ERROR_DATA",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updateSelectedError = (data) => ({
|
||||
type: "UPDATE_SELECTED_ERROR",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updateSelectedErrorData = (data) => ({
|
||||
type: "UPDATE_SELECTED_ERROR_DATA",
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const updateSelectedJson = (data) => ({
|
||||
type: "UPDATE_SELECTED_ERROR_JSON",
|
||||
payload: data,
|
||||
})
|
||||
|
||||
export const updatePartCDegreeType = (data) => ({
|
||||
type:'UPDATE_PART_C_DEGREE_TYPE',
|
||||
payload: data,
|
||||
})
|
||||
|
||||
export const updateEvQrcodeList = (data) => ({
|
||||
type:'UPDATE_EV_QRCODE_LIST',
|
||||
payload: data,
|
||||
})
|
||||
|
|
@ -2,7 +2,19 @@
|
|||
const initialState = {
|
||||
attendenceAnomolyData : [],
|
||||
partABatchAnomolyData : [],
|
||||
systemNumber : null
|
||||
systemNumber : null,
|
||||
playGroundQuery : null,
|
||||
playGroundResults : [],
|
||||
playGroundtotalPages : 0,
|
||||
playGroundCurrentPage : 0,
|
||||
partCAnomolyList: [],
|
||||
partCErrorList: [],
|
||||
partCErrorData: [],
|
||||
selectedError: null,
|
||||
selectedErrorData: [],
|
||||
selectedErrorJson: {},
|
||||
partCDegreeType : null,
|
||||
evQrcodeList: []
|
||||
};
|
||||
|
||||
const reducer = (state = initialState, action) => {
|
||||
|
|
@ -13,10 +25,32 @@ const initialState = {
|
|||
return { ...state, partABatchAnomolyData:action?.payload};
|
||||
case 'UPDATE_SYSTEM_NO':
|
||||
return { ...state,systemNumber:action?.payload}
|
||||
case 'UPDATE_PLAYGROUND_QUERY':
|
||||
return { ...state,playGroundQuery:action?.payload}
|
||||
case 'UPDATE_PLAYGROUND_RESULTS':
|
||||
return { ...state,playGroundResults:action?.payload}
|
||||
case 'UPDATE_PLAYGROUND_PAGENO':
|
||||
return { ...state,playGroundtotalPages:action?.payload}
|
||||
case 'UPDATE_PLAYGROUND_TOTAL_PAGES':
|
||||
return { ...state,playGroundCurrentPage:action?.payload}
|
||||
case 'UPDATE_PARTC_ERROR_LIST':
|
||||
return { ...state,partCErrorList:action?.payload}
|
||||
case 'UPDATE_PARTC_ERROR_DATA':
|
||||
return { ...state, partCErrorData:action?.payload}
|
||||
case 'UPDATE_SELECTED_ERROR':
|
||||
return { ...state, selectedError:action?.payload}
|
||||
case 'UPDATE_SELECTED_ERROR_DATA':
|
||||
return { ...state, selectedErrorData:action?.payload}
|
||||
case 'UPDATE_SELECTED_ERROR_JSON':
|
||||
return { ...state, selectedErrorJson:action?.payload}
|
||||
case 'UPDATE_PART_C_DEGREE_TYPE':
|
||||
return { ...state, partCDegreeType:action?.payload}
|
||||
case 'UPDATE_EV_QRCODE_LIST':
|
||||
return { ...state,evQrcodeList:action?.payload}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default reducer;
|
||||
|
||||
Loading…
Reference in New Issue