Compare commits
No commits in common. "869e857f2cc4e313c7120d49276ac64057664fa6" and "42bbdebf6f341f9de4e9d5c3c4df6d2fc0df4e68" have entirely different histories.
869e857f2c
...
42bbdebf6f
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
|
@ -10,8 +10,6 @@
|
|||
"Groupbutton",
|
||||
"handelnavigate",
|
||||
"Karim",
|
||||
"katex",
|
||||
"Latext",
|
||||
"Popconfirm",
|
||||
"queryqlent",
|
||||
"registraion",
|
||||
|
|
|
|||
|
|
@ -8,16 +8,11 @@
|
|||
<link rel="icon" type="image/png" sizes="32x32" href="/App/Logo2.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/App/Logo2.png" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<link
|
||||
href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/katex.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<meta
|
||||
name="description"
|
||||
content="social networking platform with automated content moderation and context-based authentication system"
|
||||
/>
|
||||
|
||||
|
||||
<script type="module" src="/src/index.tsx"></script>
|
||||
|
||||
<title>NERD DASHBOARD</title>
|
||||
|
|
|
|||
418
package-lock.json
generated
418
package-lock.json
generated
|
|
@ -13,31 +13,21 @@
|
|||
"@dnd-kit/modifiers": "^7.0.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@types/katex": "^0.16.7",
|
||||
"antd": "^5.17.4",
|
||||
"axios": "^1.7.2",
|
||||
"better-react-mathjax": "^2.0.3",
|
||||
"bootstrap": "^5.3.3",
|
||||
"dayjs": "^1.11.11",
|
||||
"formik": "^2.4.6",
|
||||
"i18next": "^23.11.5",
|
||||
"katex": "^0.16.11",
|
||||
"lottie-react": "^2.4.0",
|
||||
"mathjax-full": "^3.2.2",
|
||||
"mathml-to-latex": "^1.4.1",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-i18next": "^13.5.0",
|
||||
"react-icons": "^4.12.0",
|
||||
"react-katex": "^3.0.1",
|
||||
"react-latex": "^2.0.0",
|
||||
"react-latex-next": "^3.0.0",
|
||||
"react-query": "^3.39.3",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"react-toastify": "^9.1.3",
|
||||
"react-window": "^1.8.10",
|
||||
"react-window-dynamic": "^1.8.0-alpha.2",
|
||||
"reactstrap": "^9.2.2",
|
||||
"sass": "^1.77.4",
|
||||
"yup": "^1.4.0",
|
||||
|
|
@ -52,9 +42,6 @@
|
|||
"@types/react-beautiful-dnd": "^13.1.8",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"@types/react-katex": "^3.0.4",
|
||||
"@types/react-latex": "^2.0.3",
|
||||
"@types/react-window": "^1.8.8",
|
||||
"@vitejs/plugin-legacy": "^5.4.1",
|
||||
"@vitejs/plugin-react": "^4.3.0",
|
||||
"jest": "^29.7.0",
|
||||
|
|
@ -3579,11 +3566,6 @@
|
|||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/katex": {
|
||||
"version": "0.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
|
||||
"integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ=="
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.14.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz",
|
||||
|
|
@ -3634,24 +3616,6 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-katex": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-katex/-/react-katex-3.0.4.tgz",
|
||||
"integrity": "sha512-aLkykKzSKLpXI6REJ3uClao6P47HAFfR1gcHOZwDeTuALsyjgMhz+oynLV4gX0kiJVnvHrBKF/TLXqyNTpHDUg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-latex": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-latex/-/react-latex-2.0.3.tgz",
|
||||
"integrity": "sha512-PdH5UI5AT2aj+sBJkQbmXc/0S7pR/7i/u5oFhDrFHTeI2TedMk+RwQsVNcHMXleT1L7RqyNjm0FE4AtUHsv/DA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-redux": {
|
||||
"version": "7.1.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.33.tgz",
|
||||
|
|
@ -3663,15 +3627,6 @@
|
|||
"redux": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-window": {
|
||||
"version": "1.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
|
||||
"integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/stack-utils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
||||
|
|
@ -3937,14 +3892,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.8.10",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
|
||||
"integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
|
||||
|
|
@ -4378,17 +4325,6 @@
|
|||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/better-react-mathjax": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/better-react-mathjax/-/better-react-mathjax-2.0.3.tgz",
|
||||
"integrity": "sha512-wfifT8GFOKb1TWm2+E50I6DJpLZ5kLbch283Lu043EJtwSv0XvZDjr4YfR4d2MjAhqP6SH4VjjrKgbX8R00oCQ==",
|
||||
"dependencies": {
|
||||
"mathjax-full": "^3.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/big-integer": {
|
||||
"version": "1.6.52",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
|
||||
|
|
@ -4765,14 +4701,6 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/compute-scroll-into-view": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz",
|
||||
|
|
@ -5280,14 +5208,6 @@
|
|||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/esm": {
|
||||
"version": "3.2.25",
|
||||
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
|
||||
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
|
|
@ -7452,21 +7372,6 @@
|
|||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/katex": {
|
||||
"version": "0.16.11",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz",
|
||||
"integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==",
|
||||
"funding": [
|
||||
"https://opencollective.com/katex",
|
||||
"https://github.com/sponsors/katex"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "^8.3.0"
|
||||
},
|
||||
"bin": {
|
||||
"katex": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
|
|
@ -7649,25 +7554,6 @@
|
|||
"remove-accents": "0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mathjax-full": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
|
||||
"integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
|
||||
"dependencies": {
|
||||
"esm": "^3.2.25",
|
||||
"mhchemparser": "^4.1.0",
|
||||
"mj-context-menu": "^0.6.1",
|
||||
"speech-rule-engine": "^4.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mathml-to-latex": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mathml-to-latex/-/mathml-to-latex-1.4.1.tgz",
|
||||
"integrity": "sha512-3B+q88sVnQCqWG0UN5scYZRsUE0O2GFNfqCA0AMY/+iNkrwm3n4eiqFNKpJQ0lguHhbLfuKKoJuPixDKuqiLCQ==",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.10"
|
||||
}
|
||||
},
|
||||
"node_modules/memoize-one": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
||||
|
|
@ -7691,11 +7577,6 @@
|
|||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/mhchemparser": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
|
||||
"integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ=="
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
|
||||
|
|
@ -7762,11 +7643,6 @@
|
|||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/mj-context-menu": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
|
||||
"integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
|
|
@ -8933,58 +8809,6 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/react-katex": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-katex/-/react-katex-3.0.1.tgz",
|
||||
"integrity": "sha512-wIUW1fU5dHlkKvq4POfDkHruQsYp3fM8xNb/jnc8dnQ+nNCnaj0sx5pw7E6UyuEdLRyFKK0HZjmXBo+AtXXy0A==",
|
||||
"dependencies": {
|
||||
"katex": "^0.16.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prop-types": "^15.8.1",
|
||||
"react": ">=15.3.2 <=18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-latex": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-latex/-/react-latex-2.0.0.tgz",
|
||||
"integrity": "sha512-x17uDCfqBgR+5ZF/zplRCuHdEbX22CJlVipOqMUinRMoiOwh5fr3jbjD4zqVQ8pIs4AnF0BWPDR2S7Fyd8Snxw==",
|
||||
"dependencies": {
|
||||
"katex": "^0.10.2"
|
||||
}
|
||||
},
|
||||
"node_modules/react-latex-next": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-latex-next/-/react-latex-next-3.0.0.tgz",
|
||||
"integrity": "sha512-x70f1b1G7TronVigsRgKHKYYVUNfZk/3bciFyYX1lYLQH2y3/TXku3+5Vap8MDbJhtopePSYBsYWS6jhzIdz+g==",
|
||||
"dependencies": {
|
||||
"katex": "^0.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-latex/node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"node_modules/react-latex/node_modules/katex": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.10.2.tgz",
|
||||
"integrity": "sha512-cQOmyIRoMloCoSIOZ1+gEwsksdJZ1EW4SWm3QzxSza/QsnZr6D4U1V9S4q+B/OLm2OQ8TCBecQ8MaIfnScI7cw==",
|
||||
"dependencies": {
|
||||
"commander": "^2.19.0"
|
||||
},
|
||||
"bin": {
|
||||
"katex": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/react-popper": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
|
||||
|
|
@ -9124,38 +8948,6 @@
|
|||
"react-dom": ">=16.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-window": {
|
||||
"version": "1.8.10",
|
||||
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz",
|
||||
"integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"memoize-one": ">=3.1.1 <6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-window-dynamic": {
|
||||
"version": "1.8.0-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/react-window-dynamic/-/react-window-dynamic-1.8.0-alpha.2.tgz",
|
||||
"integrity": "sha512-PYR1nu5kzEr+PDg9/+19uTqO1OqUCckYE5dDpjFpEGBtVTcq4smxE3jXhk+zLi4AOZlLVr9pJIjwPL68zwq5Ww==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"memoize-one": ">=3.1.1 <6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.0.0 || ^16.0.0",
|
||||
"react-dom": "^15.0.0 || ^16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reactstrap": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-9.2.2.tgz",
|
||||
|
|
@ -9691,27 +9483,6 @@
|
|||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/speech-rule-engine": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
|
||||
"integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
|
||||
"dependencies": {
|
||||
"commander": "9.2.0",
|
||||
"wicked-good-xpath": "1.3.0",
|
||||
"xmldom-sre": "0.1.31"
|
||||
},
|
||||
"bin": {
|
||||
"sre": "bin/sre"
|
||||
}
|
||||
},
|
||||
"node_modules/speech-rule-engine/node_modules/commander": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
|
||||
"integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
|
|
@ -10768,11 +10539,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/wicked-good-xpath": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
|
||||
"integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
|
||||
},
|
||||
"node_modules/wildcard": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
|
||||
|
|
@ -10850,14 +10616,6 @@
|
|||
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/xmldom-sre": {
|
||||
"version": "0.1.31",
|
||||
"resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
|
||||
"integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
|
||||
"engines": {
|
||||
"node": ">=0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
|
@ -13396,11 +13154,6 @@
|
|||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/katex": {
|
||||
"version": "0.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
|
||||
"integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.14.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz",
|
||||
|
|
@ -13451,24 +13204,6 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-katex": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-katex/-/react-katex-3.0.4.tgz",
|
||||
"integrity": "sha512-aLkykKzSKLpXI6REJ3uClao6P47HAFfR1gcHOZwDeTuALsyjgMhz+oynLV4gX0kiJVnvHrBKF/TLXqyNTpHDUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-latex": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-latex/-/react-latex-2.0.3.tgz",
|
||||
"integrity": "sha512-PdH5UI5AT2aj+sBJkQbmXc/0S7pR/7i/u5oFhDrFHTeI2TedMk+RwQsVNcHMXleT1L7RqyNjm0FE4AtUHsv/DA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-redux": {
|
||||
"version": "7.1.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.33.tgz",
|
||||
|
|
@ -13480,15 +13215,6 @@
|
|||
"redux": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/react-window": {
|
||||
"version": "1.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
|
||||
"integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/stack-utils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
||||
|
|
@ -13715,11 +13441,6 @@
|
|||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@xmldom/xmldom": {
|
||||
"version": "0.8.10",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
|
||||
"integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="
|
||||
},
|
||||
"@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
|
||||
|
|
@ -14064,14 +13785,6 @@
|
|||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"better-react-mathjax": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/better-react-mathjax/-/better-react-mathjax-2.0.3.tgz",
|
||||
"integrity": "sha512-wfifT8GFOKb1TWm2+E50I6DJpLZ5kLbch283Lu043EJtwSv0XvZDjr4YfR4d2MjAhqP6SH4VjjrKgbX8R00oCQ==",
|
||||
"requires": {
|
||||
"mathjax-full": "^3.2.2"
|
||||
}
|
||||
},
|
||||
"big-integer": {
|
||||
"version": "1.6.52",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
|
||||
|
|
@ -14318,11 +14031,6 @@
|
|||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="
|
||||
},
|
||||
"compute-scroll-into-view": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz",
|
||||
|
|
@ -14710,11 +14418,6 @@
|
|||
"estraverse": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"esm": {
|
||||
"version": "3.2.25",
|
||||
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
|
||||
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA=="
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
|
|
@ -16281,14 +15984,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"katex": {
|
||||
"version": "0.16.11",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz",
|
||||
"integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==",
|
||||
"requires": {
|
||||
"commander": "^8.3.0"
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
|
|
@ -16436,25 +16131,6 @@
|
|||
"remove-accents": "0.5.0"
|
||||
}
|
||||
},
|
||||
"mathjax-full": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
|
||||
"integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
|
||||
"requires": {
|
||||
"esm": "^3.2.25",
|
||||
"mhchemparser": "^4.1.0",
|
||||
"mj-context-menu": "^0.6.1",
|
||||
"speech-rule-engine": "^4.0.6"
|
||||
}
|
||||
},
|
||||
"mathml-to-latex": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mathml-to-latex/-/mathml-to-latex-1.4.1.tgz",
|
||||
"integrity": "sha512-3B+q88sVnQCqWG0UN5scYZRsUE0O2GFNfqCA0AMY/+iNkrwm3n4eiqFNKpJQ0lguHhbLfuKKoJuPixDKuqiLCQ==",
|
||||
"requires": {
|
||||
"@xmldom/xmldom": "^0.8.10"
|
||||
}
|
||||
},
|
||||
"memoize-one": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
||||
|
|
@ -16472,11 +16148,6 @@
|
|||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
},
|
||||
"mhchemparser": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
|
||||
"integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ=="
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
|
||||
|
|
@ -16525,11 +16196,6 @@
|
|||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"mj-context-menu": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
|
||||
"integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
|
|
@ -17335,45 +17001,6 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"react-katex": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-katex/-/react-katex-3.0.1.tgz",
|
||||
"integrity": "sha512-wIUW1fU5dHlkKvq4POfDkHruQsYp3fM8xNb/jnc8dnQ+nNCnaj0sx5pw7E6UyuEdLRyFKK0HZjmXBo+AtXXy0A==",
|
||||
"requires": {
|
||||
"katex": "^0.16.0"
|
||||
}
|
||||
},
|
||||
"react-latex": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-latex/-/react-latex-2.0.0.tgz",
|
||||
"integrity": "sha512-x17uDCfqBgR+5ZF/zplRCuHdEbX22CJlVipOqMUinRMoiOwh5fr3jbjD4zqVQ8pIs4AnF0BWPDR2S7Fyd8Snxw==",
|
||||
"requires": {
|
||||
"katex": "^0.10.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"katex": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.10.2.tgz",
|
||||
"integrity": "sha512-cQOmyIRoMloCoSIOZ1+gEwsksdJZ1EW4SWm3QzxSza/QsnZr6D4U1V9S4q+B/OLm2OQ8TCBecQ8MaIfnScI7cw==",
|
||||
"requires": {
|
||||
"commander": "^2.19.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-latex-next": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-latex-next/-/react-latex-next-3.0.0.tgz",
|
||||
"integrity": "sha512-x70f1b1G7TronVigsRgKHKYYVUNfZk/3bciFyYX1lYLQH2y3/TXku3+5Vap8MDbJhtopePSYBsYWS6jhzIdz+g==",
|
||||
"requires": {
|
||||
"katex": "^0.16.0"
|
||||
}
|
||||
},
|
||||
"react-popper": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
|
||||
|
|
@ -17462,24 +17089,6 @@
|
|||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"react-window": {
|
||||
"version": "1.8.10",
|
||||
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz",
|
||||
"integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"memoize-one": ">=3.1.1 <6"
|
||||
}
|
||||
},
|
||||
"react-window-dynamic": {
|
||||
"version": "1.8.0-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/react-window-dynamic/-/react-window-dynamic-1.8.0-alpha.2.tgz",
|
||||
"integrity": "sha512-PYR1nu5kzEr+PDg9/+19uTqO1OqUCckYE5dDpjFpEGBtVTcq4smxE3jXhk+zLi4AOZlLVr9pJIjwPL68zwq5Ww==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"memoize-one": ">=3.1.1 <6"
|
||||
}
|
||||
},
|
||||
"reactstrap": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-9.2.2.tgz",
|
||||
|
|
@ -17888,23 +17497,6 @@
|
|||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"speech-rule-engine": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
|
||||
"integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
|
||||
"requires": {
|
||||
"commander": "9.2.0",
|
||||
"wicked-good-xpath": "1.3.0",
|
||||
"xmldom-sre": "0.1.31"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
|
||||
"integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
|
|
@ -18602,11 +18194,6 @@
|
|||
"has-tostringtag": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"wicked-good-xpath": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
|
||||
"integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
|
||||
},
|
||||
"wildcard": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
|
||||
|
|
@ -18658,11 +18245,6 @@
|
|||
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
|
||||
"dev": true
|
||||
},
|
||||
"xmldom-sre": {
|
||||
"version": "0.1.31",
|
||||
"resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
|
||||
"integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw=="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
|
|
|||
13
package.json
13
package.json
|
|
@ -8,31 +8,21 @@
|
|||
"@dnd-kit/modifiers": "^7.0.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@types/katex": "^0.16.7",
|
||||
"antd": "^5.17.4",
|
||||
"axios": "^1.7.2",
|
||||
"better-react-mathjax": "^2.0.3",
|
||||
"bootstrap": "^5.3.3",
|
||||
"dayjs": "^1.11.11",
|
||||
"formik": "^2.4.6",
|
||||
"i18next": "^23.11.5",
|
||||
"katex": "^0.16.11",
|
||||
"lottie-react": "^2.4.0",
|
||||
"mathjax-full": "^3.2.2",
|
||||
"mathml-to-latex": "^1.4.1",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-i18next": "^13.5.0",
|
||||
"react-icons": "^4.12.0",
|
||||
"react-katex": "^3.0.1",
|
||||
"react-latex": "^2.0.0",
|
||||
"react-latex-next": "^3.0.0",
|
||||
"react-query": "^3.39.3",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"react-toastify": "^9.1.3",
|
||||
"react-window": "^1.8.10",
|
||||
"react-window-dynamic": "^1.8.0-alpha.2",
|
||||
"reactstrap": "^9.2.2",
|
||||
"sass": "^1.77.4",
|
||||
"yup": "^1.4.0",
|
||||
|
|
@ -73,9 +63,6 @@
|
|||
"@types/react-beautiful-dnd": "^13.1.8",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"@types/react-katex": "^3.0.4",
|
||||
"@types/react-latex": "^2.0.3",
|
||||
"@types/react-window": "^1.8.8",
|
||||
"@vitejs/plugin-legacy": "^5.4.1",
|
||||
"@vitejs/plugin-react": "^4.3.0",
|
||||
"jest": "^29.7.0",
|
||||
|
|
|
|||
8743
pnpm-lock.yaml
8743
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -62,7 +62,6 @@ const ImageBoxField = ({ name }: any) => {
|
|||
fileInputRef.current.value = "";
|
||||
}
|
||||
};
|
||||
console.log(name);
|
||||
|
||||
return (
|
||||
<div className="ImageBoxField">
|
||||
|
|
|
|||
|
|
@ -1,105 +0,0 @@
|
|||
import "./ImageBoxField.scss";
|
||||
import { useState, useRef, useEffect,memo } from "react";
|
||||
import ImageIcon from "./ImageIcon";
|
||||
import ImageCancelIcon from "./ImageCancelIcon";
|
||||
import { getNestedValue } from "../../../utils/getNestedValue";
|
||||
import { generateImagePreview } from "./generateImagePreview";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { areFieldPropsEqual } from "../../../utils/areFieldPropsEqual";
|
||||
|
||||
// Helper function to generate image preview from a File
|
||||
|
||||
const ImageBoxFieldMemo = memo(({ form,field }: any) => {
|
||||
const {values,setFieldValue} = form
|
||||
const {name} = field;
|
||||
const value = getNestedValue(values, name);
|
||||
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [t] = useTranslation();
|
||||
useEffect(() => {
|
||||
if (value instanceof File) {
|
||||
generateImagePreview(value, setImagePreview);
|
||||
} else if (typeof value === "string") {
|
||||
setImagePreview(value);
|
||||
} else {
|
||||
setImagePreview(null);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
const handleFileChange = (event: any) => {
|
||||
const file = event.target.files[0];
|
||||
|
||||
if (file) {
|
||||
const maxSize = 2 * 1024 * 1024;
|
||||
|
||||
if (file.size > maxSize) {
|
||||
alert(t('validation.File_size_exceeds_2_MB_limit.'));
|
||||
event.target.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// Process the file
|
||||
}
|
||||
|
||||
if (file) {
|
||||
generateImagePreview(file, setImagePreview);
|
||||
|
||||
setFieldValue(name, file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleButtonClick = () => {
|
||||
const fileInput = fileInputRef.current;
|
||||
if (fileInput) {
|
||||
fileInput.click();
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setImagePreview("");
|
||||
setFieldValue(name, null);
|
||||
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
console.log(name);
|
||||
|
||||
return (
|
||||
<div className="ImageBoxField">
|
||||
<div className="ImageHeader">
|
||||
{imagePreview ? (
|
||||
<>
|
||||
<ImageCancelIcon
|
||||
onClick={handleCancel}
|
||||
className="ImageCancelIcon"
|
||||
/>
|
||||
<ImageIcon onClick={handleButtonClick} className="ImageBoxIcon" />
|
||||
</>
|
||||
) : (
|
||||
<div className="VisibleHidden">hidden</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="ImageBox" onClick={handleButtonClick}>
|
||||
{imagePreview ? (
|
||||
<img src={imagePreview} alt="Preview" className="imagePreview" />
|
||||
) : (
|
||||
<ImageIcon className="ImageBoxIcon" />
|
||||
)}
|
||||
</div>
|
||||
<input
|
||||
id={`file-input-${name}`}
|
||||
type="file"
|
||||
accept="image/png, image/jpeg, image/webp"
|
||||
style={{ display: "none" }}
|
||||
onChange={handleFileChange}
|
||||
ref={fileInputRef}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, (prevProps, nextProps) => {
|
||||
return areFieldPropsEqual(prevProps, nextProps)
|
||||
});
|
||||
|
||||
export default ImageBoxFieldMemo;
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
import React from 'react';
|
||||
import 'katex/dist/katex.min.css';
|
||||
import { BlockMath } from 'react-katex';
|
||||
import { convertMathMLToLaTeX } from '../../utils/convertMathMLToLaTeX';
|
||||
|
||||
|
||||
const LatexPreview = ({Latex}:{Latex:string}) => {
|
||||
|
||||
return(
|
||||
<BlockMath math={Latex} />
|
||||
)
|
||||
};
|
||||
|
||||
export default LatexPreview;
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
import React, { useState } from "react";
|
||||
import { Select, Spin } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useDebounce } from "../../utils/useDebounce";
|
||||
import { useGetAllTag } from "../../api/tags";
|
||||
import { useFormikContext } from "formik";
|
||||
|
||||
const SelectTagV2: React.FC = () => {
|
||||
const [searchValue, setSearchValue] = useState<string>("");
|
||||
const [fieldValue, setFieldValue] = useState<string>("");
|
||||
const formik = useFormikContext<any>();
|
||||
|
||||
// Fetch tags based on search value
|
||||
const { data, isLoading } = useGetAllTag({ name: searchValue });
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
||||
// Get selected tags from Formik
|
||||
const CurrentTags = formik.values.tags ?? []; // Assuming tags are stored as array of objects
|
||||
console.log(CurrentTags,"CurrentTags");
|
||||
|
||||
const NewShapeTags = CurrentTags?.map((item:any)=> {return item?.name ?? item })
|
||||
|
||||
const handleChange = (_value: any[],option:any) => {
|
||||
console.log(option,"option");
|
||||
const NewShapeOption = option?.map((item:any)=> {return ({name:item?.name,id:item?.id})})
|
||||
console.log(NewShapeOption);
|
||||
|
||||
formik.setFieldValue("tags", NewShapeOption);
|
||||
setSearchValue("");
|
||||
setFieldValue("");
|
||||
};
|
||||
|
||||
const handleSearch = useDebounce((value: string) => {
|
||||
setSearchValue(value);
|
||||
});
|
||||
|
||||
const handleBlur = () => {
|
||||
setSearchValue("");
|
||||
setFieldValue("");
|
||||
};
|
||||
|
||||
const options = data?.data ?? [];
|
||||
|
||||
const additionalData =
|
||||
options.length < 1 && searchValue.length >= 1 && !isLoading
|
||||
? [{ id: searchValue, name: searchValue }]
|
||||
: options;
|
||||
|
||||
console.log(additionalData);
|
||||
|
||||
|
||||
return (
|
||||
<div className="SelectTag">
|
||||
<label>{t("models.tag")}</label>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: "100%", height: "40px" }}
|
||||
placeholder=""
|
||||
fieldNames={{ label: "name", value: "name" }}
|
||||
onChange={handleChange}
|
||||
options={additionalData}
|
||||
filterOption={false}
|
||||
loading={isLoading}
|
||||
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
|
||||
onSearch={(value) => {
|
||||
handleSearch(value);
|
||||
setFieldValue(value);
|
||||
}}
|
||||
searchValue={fieldValue}
|
||||
onDropdownVisibleChange={(open) => {
|
||||
if (!open) {
|
||||
handleBlur();
|
||||
}
|
||||
}}
|
||||
value={NewShapeTags}
|
||||
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectTagV2;
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
import { Modal } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { useFormikContext } from 'formik';
|
||||
import React, { useState } from 'react'
|
||||
import { convertMathMLToLaTeX } from '../../utils/convertMathMLToLaTeX';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
const AddLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
|
||||
name:string,
|
||||
setLatex: (value:string)=> void,
|
||||
Latex:string,
|
||||
setIsModalOpen: (value:boolean)=> void ,
|
||||
isModalOpen:boolean,
|
||||
|
||||
}) => {
|
||||
const {values,setFieldValue} = useFormikContext<any>()
|
||||
|
||||
|
||||
const handleOk = () => {
|
||||
console.log(1);
|
||||
|
||||
const oldValue = values?.[name];
|
||||
const newLatex = convertMathMLToLaTeX(Latex);
|
||||
console.log(newLatex,'Latex');
|
||||
console.log(newLatex);
|
||||
|
||||
if(newLatex){
|
||||
setFieldValue(name, oldValue + " $$ " +newLatex +" $$ ");
|
||||
setLatex("")
|
||||
setIsModalOpen(false);
|
||||
}else{
|
||||
setLatex("")
|
||||
toast.error(t("validation.that_is_not_a_valid_mml"))
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setIsModalOpen(false);
|
||||
setLatex("")
|
||||
};
|
||||
|
||||
const handleChangeInputLatex = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
const newValue = e.target.value;
|
||||
setLatex(newValue)
|
||||
};
|
||||
|
||||
const [t] = useTranslation()
|
||||
return (
|
||||
|
||||
<Modal footer={false} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
|
||||
<div className='latexModal'>
|
||||
<label className='mb-3'> {t("header.past_your_MMl_text")} </label>
|
||||
<TextArea
|
||||
size="large"
|
||||
showCount
|
||||
maxLength={1000}
|
||||
autoSize={{ minRows: 4, maxRows: 10 }}
|
||||
style={{height:"400px"}}
|
||||
onChange={handleChangeInputLatex}
|
||||
value={Latex}
|
||||
/>
|
||||
<div className="buttons">
|
||||
<div className="back_button pointer" onClick={handleCancel}>
|
||||
{t("practical.cancel")}
|
||||
</div>
|
||||
<div
|
||||
className="add_button"
|
||||
onClick={handleOk}
|
||||
>
|
||||
{t(`practical.${ "add"}`)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default AddLaTexModal
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
import { Modal } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { useFormikContext } from 'formik';
|
||||
import React, { useState } from 'react'
|
||||
import { convertMathMLToLaTeX } from '../../utils/convertMathMLToLaTeX';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { toast } from 'react-toastify';
|
||||
import { parseTextAndLatex } from '../../utils/parseTextAndLatex';
|
||||
|
||||
const EditLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
|
||||
name:string,
|
||||
setLatex: (value:string)=> void,
|
||||
Latex:any,
|
||||
setIsModalOpen: (value:boolean)=> void ,
|
||||
isModalOpen:boolean,
|
||||
|
||||
}) => {
|
||||
const {values} = useFormikContext<any>()
|
||||
const [Value, setValue] = useState(Latex?.text ?? Latex)
|
||||
|
||||
const handleOk = () => {
|
||||
console.log(1);
|
||||
|
||||
const oldValue = values?.[name];
|
||||
const currentKey = Latex?.key ;
|
||||
const Preview = parseTextAndLatex(oldValue ?? "") ;
|
||||
console.log(Latex);
|
||||
|
||||
const newLatex = convertMathMLToLaTeX(Latex);
|
||||
console.log(newLatex);
|
||||
|
||||
if(newLatex){
|
||||
const newArray = Preview?.map((item:any,index:number)=>{
|
||||
if(item?.key)
|
||||
return item
|
||||
})
|
||||
|
||||
}else{
|
||||
toast.error(t("validation.that_is_not_a_valid_mml"))
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setIsModalOpen(false);
|
||||
setLatex("")
|
||||
};
|
||||
|
||||
const handleChangeInputLatex = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
const newValue = e.target.value;
|
||||
console.log(newValue,"newValue");
|
||||
setValue(newValue)
|
||||
};
|
||||
|
||||
const [t] = useTranslation()
|
||||
return (
|
||||
|
||||
<Modal footer={false} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
|
||||
<div className='latexModal'>
|
||||
<label className='mb-3'> {t("header.past_your_MMl_text")} </label>
|
||||
<TextArea
|
||||
size="large"
|
||||
showCount
|
||||
maxLength={1000}
|
||||
autoSize={{ minRows: 4, maxRows: 10 }}
|
||||
style={{height:"400px"}}
|
||||
onChange={handleChangeInputLatex}
|
||||
value={Value
|
||||
}
|
||||
/>
|
||||
<div className="buttons">
|
||||
<div className="back_button pointer" onClick={handleCancel}>
|
||||
{t("practical.cancel")}
|
||||
</div>
|
||||
<div
|
||||
className="add_button"
|
||||
onClick={handleOk}
|
||||
>
|
||||
{t(`practical.${ "edit"}`)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default EditLaTexModal
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { useFormikContext } from 'formik';
|
||||
import React, { Suspense, useState } from 'react'
|
||||
import { parseTextAndLatex } from '../../utils/parseTextAndLatex';
|
||||
import LatexPreview from '../../Components/CustomFields/MathComponent';
|
||||
import { Checkbox } from 'antd';
|
||||
import { CheckboxProps } from 'antd/lib';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaPlus } from 'react-icons/fa';
|
||||
import { useObjectToEdit } from '../../zustand/ObjectToEditState';
|
||||
import { TextAreaProps } from 'antd/lib/input';
|
||||
import SpinContainer from '../Layout/SpinContainer';
|
||||
const AddLazyModal = React.lazy(()=> import("./AddLaTexModal"));
|
||||
const EditLazyModal = React.lazy(()=> import("./EditLaTexModal"));
|
||||
interface ILaTeXInput extends TextAreaProps {
|
||||
name:string,label:string
|
||||
}
|
||||
const LaTeXInput = ({name,label,...props}:ILaTeXInput) => {
|
||||
|
||||
|
||||
const {values,setFieldValue,getFieldProps} = useFormikContext<any>()
|
||||
const { ShowLatexOption } = useObjectToEdit();
|
||||
const [showPreview, setShowPreview] = useState(false) ;
|
||||
const value = getFieldProps(name)?.value
|
||||
const handleChangeInput =
|
||||
(
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
setFieldValue(name,e.target.value);
|
||||
};
|
||||
|
||||
const Preview = parseTextAndLatex(value ?? "") ;
|
||||
|
||||
const onPreviewChange: CheckboxProps['onChange'] = (e) => {
|
||||
const value = e.target.checked
|
||||
setShowPreview(value)
|
||||
};
|
||||
const [t] = useTranslation()
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
|
||||
|
||||
const [Latex, setLatex] = useState<string>("")
|
||||
|
||||
|
||||
const showModal = () => {
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
|
||||
const handelEditModal = (item:any)=>{
|
||||
console.log(item);
|
||||
|
||||
setLatex(item)
|
||||
setIsEditModalOpen(true)
|
||||
}
|
||||
return (
|
||||
<div className='LaTeXInput'>
|
||||
|
||||
<label htmlFor={name} className="text">
|
||||
{t(`${label ? label : name}`)}
|
||||
</label>
|
||||
|
||||
<div className='LaTeXInputArea'>
|
||||
<TextArea
|
||||
size="large"
|
||||
showCount
|
||||
maxLength={1000}
|
||||
autoSize={{ minRows: 6, maxRows: 10 }}
|
||||
style={{height:"400px"}}
|
||||
onChange={handleChangeInput}
|
||||
value={value}
|
||||
{...props}
|
||||
|
||||
/>
|
||||
{ShowLatexOption &&
|
||||
<div className='LaTeXInputOptions'>
|
||||
|
||||
<Checkbox onChange={onPreviewChange}>{t("header.show_preview")}</Checkbox>
|
||||
<button type='button' className='addMML' onClick={showModal}> <FaPlus/> {t("MML")} </button>
|
||||
|
||||
</div>
|
||||
|
||||
}
|
||||
{showPreview &&
|
||||
<div className='showPreviewInput'>
|
||||
{Preview?.map((item:any,index:number)=>{
|
||||
if(item?.isLatex){
|
||||
return <div key={index} onClick={()=>handelEditModal(item)} className='LatexPreview'> <LatexPreview Latex={item?.text} /> </div>
|
||||
}
|
||||
return <div key={index}>
|
||||
{item?.text}
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
<Suspense fallback={<SpinContainer/>}>
|
||||
<AddLazyModal name={name} Latex={Latex} isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} setLatex={setLatex} />
|
||||
|
||||
<EditLazyModal name={name} Latex={Latex} isModalOpen={isEditModalOpen} setIsModalOpen={setIsEditModalOpen} setLatex={setLatex} />
|
||||
</Suspense>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LaTeXInput
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
import TextArea from 'antd/es/input/TextArea';
|
||||
import { useFormikContext } from 'formik';
|
||||
import React, { Suspense, useState } from 'react';
|
||||
import { parseTextAndLatex } from '../../utils/parseTextAndLatex';
|
||||
import LatexPreview from '../CustomFields/MathComponent';
|
||||
import { Checkbox } from 'antd';
|
||||
import { CheckboxProps } from 'antd/lib';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaPlus } from 'react-icons/fa';
|
||||
import { useObjectToEdit } from '../../zustand/ObjectToEditState';
|
||||
import SpinContainer from '../Layout/SpinContainer';
|
||||
import { areFieldPropsEqual } from './areFieldPropsEqual';
|
||||
|
||||
const AddLazyModal = React.lazy(() => import("./AddLaTexModal"));
|
||||
const EditLazyModal = React.lazy(() => import("./EditLaTexModal"));
|
||||
|
||||
|
||||
const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...props }) => {
|
||||
const { name ,value} = field;
|
||||
|
||||
const { setFieldValue } = form;
|
||||
|
||||
const { ShowLatexOption } = useObjectToEdit();
|
||||
const [showPreview, setShowPreview] = useState(false);
|
||||
|
||||
const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
setFieldValue(name, e.target.value);
|
||||
};
|
||||
console.log(name,"name");
|
||||
|
||||
const Preview = parseTextAndLatex(value ?? "");
|
||||
|
||||
const onPreviewChange: CheckboxProps['onChange'] = (e) => {
|
||||
setShowPreview(e.target.checked);
|
||||
};
|
||||
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
|
||||
const [Latex, setLatex] = useState<string>("");
|
||||
|
||||
const showModal = () => {
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
const handleEditModal = (item: any) => {
|
||||
console.log(item);
|
||||
setLatex(item);
|
||||
setIsEditModalOpen(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='LaTeXInput'>
|
||||
<label htmlFor={name} className="text">
|
||||
{t(label || name)}
|
||||
</label>
|
||||
|
||||
<div className='LaTeXInputArea'>
|
||||
<TextArea
|
||||
size="large"
|
||||
showCount
|
||||
maxLength={1000}
|
||||
autoSize={{ minRows: 6, maxRows: 10 }}
|
||||
style={{ height: "400px" }}
|
||||
onChange={handleChangeInput}
|
||||
value={value}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
{ShowLatexOption && (
|
||||
<div className='LaTeXInputOptions'>
|
||||
<Checkbox onChange={onPreviewChange}>{t("header.show_preview")}</Checkbox>
|
||||
<button type='button' className='addMML' onClick={showModal}>
|
||||
<FaPlus/> {t("MML")}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showPreview && (
|
||||
<div className='showPreviewInput'>
|
||||
{Preview?.map((item: any, index: number) => {
|
||||
if (item?.isLatex) {
|
||||
return (
|
||||
<div key={index} onClick={() => handleEditModal(item)} className='LatexPreview'>
|
||||
<LatexPreview Latex={item?.text} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <div key={index}>{item?.text}</div>;
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Suspense fallback={<SpinContainer />}>
|
||||
<AddLazyModal name={name} Latex={Latex} isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} setLatex={setLatex} />
|
||||
<EditLazyModal name={name} Latex={Latex} isModalOpen={isEditModalOpen} setIsModalOpen={setIsEditModalOpen} setLatex={setLatex} />
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
}, (prevProps, nextProps) => {
|
||||
return areFieldPropsEqual(prevProps, nextProps)
|
||||
});
|
||||
|
||||
export default LaTeXInputMemo;
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// utilityFunctions.ts
|
||||
import { FieldProps } from 'formik';
|
||||
|
||||
export const areFieldPropsEqual = (
|
||||
prevProps: any,
|
||||
nextProps: any
|
||||
): boolean => {
|
||||
const prevError = prevProps.form.errors[prevProps.field.name];
|
||||
const nextError = nextProps.form.errors[nextProps.field.name];
|
||||
|
||||
const prevTouched = prevProps.form.touched[prevProps.field.name];
|
||||
const nextTouched = nextProps.form.touched[nextProps.field.name];
|
||||
|
||||
const prevValue = prevProps.field.value;
|
||||
const nextValue = nextProps.field.value;
|
||||
|
||||
return (
|
||||
prevValue === nextValue
|
||||
&&
|
||||
prevError === nextError &&
|
||||
prevTouched === nextTouched
|
||||
);
|
||||
};
|
||||
|
|
@ -11,7 +11,6 @@ import {
|
|||
SearchField,
|
||||
TextField,
|
||||
DropFile,
|
||||
TextAreaMML,
|
||||
Default,
|
||||
} from "./View";
|
||||
import { ValidationFieldProps, ValidationFieldType } from "./utils/types";
|
||||
|
|
@ -24,7 +23,6 @@ const components: { [key: string]: React.FC<any> } = {
|
|||
LocalSearch: LocalSearchField,
|
||||
DataRange: DataRange,
|
||||
TextArea: TextField,
|
||||
TextAreaMML: TextAreaMML,
|
||||
Date: Date,
|
||||
Time: Time,
|
||||
File: File,
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
import { Input } from "antd";
|
||||
import React from "react";
|
||||
import useFormField from "../../../Hooks/useFormField";
|
||||
import { ValidationFieldLabel } from "../components/ValidationFieldLabel";
|
||||
import { ValidationFieldContainer } from "../components/ValidationFieldContainer";
|
||||
import LatexPreview from "../../CustomFields/MathComponent";
|
||||
const { TextArea } = Input;
|
||||
|
||||
const TextFieldMML = ({
|
||||
name,
|
||||
label,
|
||||
placeholder,
|
||||
isDisabled,
|
||||
onChange,
|
||||
no_label,
|
||||
label_icon,
|
||||
className,
|
||||
mathContent, // Add mathContent prop
|
||||
...props
|
||||
}: any) => {
|
||||
const { formik, isError, errorMsg, t } = useFormField(name, props);
|
||||
|
||||
const TextFilehandleChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
formik.setFieldValue(name, e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`ValidationField w-100 ${className ?? ""} `}>
|
||||
<ValidationFieldLabel
|
||||
name={name}
|
||||
label={label}
|
||||
label_icon={label_icon}
|
||||
no_label={no_label}
|
||||
placeholder={placeholder}
|
||||
t={t}
|
||||
/>
|
||||
|
||||
<ValidationFieldContainer isError={isError} errorMsg={errorMsg}>
|
||||
<TextArea
|
||||
placeholder={t(`input.${placeholder ? placeholder : name}`)}
|
||||
name={name}
|
||||
disabled={isDisabled}
|
||||
size="large"
|
||||
showCount
|
||||
maxLength={1000}
|
||||
autoSize={{ minRows: 4, maxRows: 10 }}
|
||||
onChange={onChange || TextFilehandleChange}
|
||||
id={name}
|
||||
{...props}
|
||||
|
||||
/>
|
||||
|
||||
|
||||
</ValidationFieldContainer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(TextFieldMML);
|
||||
|
|
@ -9,7 +9,6 @@ import MaltyFile from "./MaltyFile";
|
|||
import SearchField from "./SearchField";
|
||||
import TextField from "./TextField";
|
||||
import DropFile from "./DropFile.tsx";
|
||||
import TextAreaMML from "./TextFieldMML";
|
||||
|
||||
export {
|
||||
Time,
|
||||
|
|
@ -23,5 +22,4 @@ export {
|
|||
SearchField,
|
||||
TextField,
|
||||
DropFile,
|
||||
TextAreaMML
|
||||
};
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ export type FieldProps = BaseFieldProps &
|
|||
| "password"
|
||||
| "email"
|
||||
| "TextArea"
|
||||
| "TextAreaMML"
|
||||
| "NumberFormate";
|
||||
label2?: string;
|
||||
Group?: boolean;
|
||||
|
|
|
|||
|
|
@ -7,12 +7,11 @@ import { Checkbox, CheckboxProps, Popconfirm, Popover } from "antd";
|
|||
import { CombinationKeyEnum } from "../../enums/CombinationKeyEnum";
|
||||
import { PopconfirmProps } from "antd/lib";
|
||||
import { SettingFilled } from "@ant-design/icons";
|
||||
import { LocalStorageEnum } from "../../enums/LocalStorageEnum";
|
||||
|
||||
const Header = () => {
|
||||
const [t] = useTranslation();
|
||||
const { values, setValues } = useFormikContext<any>();
|
||||
const { isBseQuestion, setIsBseQuestion,ShowHint,setShowHint,ShowLatexOption,setShowLatexOption } = useObjectToEdit();
|
||||
const { isBseQuestion, setIsBseQuestion,ShowHint,setShowHint } = useObjectToEdit();
|
||||
// const [Setting, setSetting] = useState(false)
|
||||
const isEdited = ()=>{
|
||||
|
||||
|
|
@ -74,32 +73,24 @@ const Header = () => {
|
|||
);
|
||||
|
||||
|
||||
const onChangeHint: CheckboxProps['onChange'] = (e) => {
|
||||
setShowHint(e.target.checked);
|
||||
localStorage?.setItem(LocalStorageEnum.HINT_INPUT,e.target.checked ? "true" : "false" )
|
||||
const handleOpenChange = (newOpen: boolean) => {
|
||||
// setSetting(newOpen);
|
||||
};
|
||||
|
||||
const onChangeLatexOption: CheckboxProps['onChange'] = (e) => {
|
||||
setShowLatexOption(e.target.checked);
|
||||
localStorage?.setItem(LocalStorageEnum.LATEX_OPTION_INPUT,e.target.checked ? "true" : "false" )
|
||||
const onChange: CheckboxProps['onChange'] = (e) => {
|
||||
setShowHint(e.target.checked);
|
||||
};
|
||||
|
||||
|
||||
const contentSetting = (
|
||||
<div>
|
||||
|
||||
<Checkbox checked={ShowHint} onChange={onChangeHint}>
|
||||
<Checkbox checked={ShowHint} onChange={onChange}>
|
||||
{ t("header.show_hint")}
|
||||
</Checkbox>
|
||||
|
||||
<Checkbox checked={ShowLatexOption} onChange={onChangeLatexOption}>
|
||||
{ t("header.show_MMl")}
|
||||
</Checkbox>
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<header className="exercise_add_header mb-4">
|
||||
<article>
|
||||
|
|
@ -114,7 +105,7 @@ const Header = () => {
|
|||
<div>
|
||||
|
||||
<div className="question_header_setting">
|
||||
<Popover trigger="click" content={contentSetting}>
|
||||
<Popover onOpenChange={handleOpenChange} trigger="click" content={contentSetting}>
|
||||
<SettingFilled/>
|
||||
|
||||
</Popover>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ export const useColumns = () => {
|
|||
key: "name",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.name,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: t("columns.image"),
|
||||
|
|
|
|||
81
src/Pages/Admin/Tags/field/SelectTag.tsx
Normal file
81
src/Pages/Admin/Tags/field/SelectTag.tsx
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import React, { useState, useMemo } from "react";
|
||||
import { Select, Spin } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useFormikContext } from "formik";
|
||||
import { useDebounce } from "../../../../utils/useDebounce";
|
||||
import { useGetAllTag } from "../../../../api/tags";
|
||||
|
||||
const SelectTag: React.FC = () => {
|
||||
const [searchValue, setSearchValue] = useState<string>("");
|
||||
|
||||
const [fieldValue, setFieldValue] = useState<string>("");
|
||||
const formik = useFormikContext<any>();
|
||||
const handleChange = (value: string[]) => {
|
||||
console.log(value,"value");
|
||||
|
||||
formik.setFieldValue("tags", value);
|
||||
setSearchValue("");
|
||||
setFieldValue("");
|
||||
};
|
||||
|
||||
const handleSearch = useDebounce((value: string) => {
|
||||
setSearchValue(value);
|
||||
});
|
||||
|
||||
const handleFieldChange = (value: string) => {
|
||||
setFieldValue(value);
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
setSearchValue("");
|
||||
setFieldValue("");
|
||||
};
|
||||
|
||||
const { data, isLoading } = useGetAllTag({
|
||||
name: searchValue,
|
||||
});
|
||||
|
||||
const [t] = useTranslation();
|
||||
|
||||
const options = data?.data ?? [];
|
||||
const additionalData =
|
||||
options.length < 1 && searchValue.length > 1 && !isLoading
|
||||
? [{ id: searchValue, name: searchValue }]
|
||||
: [];
|
||||
|
||||
const value =
|
||||
formik?.values?.tags?.map((item: any) => item?.id ?? item) ?? [];
|
||||
|
||||
const AllOptions = [...options, ...additionalData];
|
||||
|
||||
return (
|
||||
<div className="SelectTag">
|
||||
<label htmlFor="">{t("models.tag")}</label>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: "100%", height: "40px" }}
|
||||
placeholder=""
|
||||
fieldNames={{ label: "name", value: "id" }}
|
||||
onChange={handleChange}
|
||||
options={AllOptions}
|
||||
filterOption={false}
|
||||
loading={isLoading}
|
||||
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
|
||||
onSearch={(value) => {
|
||||
handleSearch(value);
|
||||
handleFieldChange(value);
|
||||
}}
|
||||
searchValue={fieldValue}
|
||||
onDropdownVisibleChange={(open) => {
|
||||
if (!open) {
|
||||
handleBlur();
|
||||
}
|
||||
}}
|
||||
value={value}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectTag;
|
||||
|
|
@ -34,7 +34,6 @@ export const useColumns = () => {
|
|||
dataIndex: "name",
|
||||
key: "name",
|
||||
align: "center",
|
||||
ellipsis:true
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ export const useColumns = () => {
|
|||
key: "name",
|
||||
align: "center",
|
||||
render: (text) => text,
|
||||
ellipsis:true
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ export const useColumns = () => {
|
|||
key: "name",
|
||||
align: "center",
|
||||
render: (text, record) => record?.name,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
// canAddLesson ? (
|
||||
|
|
|
|||
|
|
@ -20,19 +20,20 @@ import ModelForm from "./Model/ModelForm";
|
|||
import { toast } from "react-toastify";
|
||||
import { Form, Formik } from "formik";
|
||||
import { MdOutlineArrowForwardIos } from "react-icons/md";
|
||||
import { getCharFromNumber } from "../../../utils/getCharFromNumber";
|
||||
|
||||
const AddPage: React.FC = () => {
|
||||
const location = useLocation();
|
||||
|
||||
const { mutateAsync,isLoading:LoadingAsync } = useAddQuestionAsync();
|
||||
const { mutate, isLoading, isSuccess } = useAddQuestion();
|
||||
const { isBseQuestion, setTagsSearch, setSuccess } =
|
||||
const { isBseQuestion, setTagsSearch, setSuccess , ShowHint,setShowHint } =
|
||||
useObjectToEdit();
|
||||
|
||||
const [t] = useTranslation();
|
||||
const { subject_id, lesson_id } = useParams<ParamsEnum>();
|
||||
|
||||
const handleFormSubmit = ( values: any) => {
|
||||
const handleSubmit = ( values: any) => {
|
||||
const DataToSend = structuredClone(values);
|
||||
setTagsSearch(null);
|
||||
|
||||
|
|
@ -99,14 +100,14 @@ const AddPage: React.FC = () => {
|
|||
mutate(NewQuestion);
|
||||
}
|
||||
};
|
||||
|
||||
const handleValidateSingleQuestion = (values:any,isValid:boolean,handleSubmit:any)=>{
|
||||
const handleValidateSingleQuestion = (values:any)=>{
|
||||
const haveMoreThanOneAnswer = values?.answers?.length > 1;
|
||||
const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item:any)=> item?.isCorrect === 1 || item.isCorrect === true )
|
||||
const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
|
||||
const content = values.content ;
|
||||
const content_image = values.content_image ;
|
||||
const haveContentOrContentImage = !!content || !!content_image ;
|
||||
|
||||
console.log(haveImageOrContent,"haveImageOrContent");
|
||||
if(!haveContentOrContentImage){
|
||||
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
|
||||
|
|
@ -122,30 +123,22 @@ const AddPage: React.FC = () => {
|
|||
return false ;
|
||||
}
|
||||
if(haveImageOrContent){
|
||||
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
|
||||
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer_in_answer"))
|
||||
return false
|
||||
}
|
||||
|
||||
console.log(1);
|
||||
|
||||
if(isValid){
|
||||
handleSubmit(values)
|
||||
}
|
||||
|
||||
}
|
||||
const handleValidateBaseQuestion = (values: any,isValid:boolean,handleSubmit:any) => {
|
||||
const handleValidateBaseQuestion = (values: any) => {
|
||||
const content = values.content ;
|
||||
const content_image = values.content_image ;
|
||||
const haveContentOrContentImage = !!content || !!content_image ;
|
||||
console.log(2);
|
||||
|
||||
if(!haveContentOrContentImage){
|
||||
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
|
||||
return false;
|
||||
}
|
||||
console.log(1);
|
||||
|
||||
const isValidate = values?.Questions?.every((Question: any, QuestionsIndex: number) => {
|
||||
values?.Questions?.every((Question: any, QuestionsIndex: number) => {
|
||||
|
||||
|
||||
const content = Question.content ;
|
||||
|
|
@ -187,15 +180,9 @@ const AddPage: React.FC = () => {
|
|||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return true;
|
||||
});
|
||||
|
||||
console.log(1);
|
||||
|
||||
if(isValid && isValidate){
|
||||
console.log(2);
|
||||
handleSubmit(values)
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -226,13 +213,12 @@ const AddPage: React.FC = () => {
|
|||
|
||||
<div className="exercise_add">
|
||||
<Formik
|
||||
onSubmit={handleFormSubmit}
|
||||
onSubmit={handleSubmit}
|
||||
initialValues={getInitialValuesBase({} as any)}
|
||||
validationSchema={getValidationSchemaBase}
|
||||
enableReinitialize
|
||||
|
||||
>
|
||||
{({ values,isValid,handleSubmit }) => (
|
||||
{({ values,handleSubmit }) => (
|
||||
|
||||
<Form className="w-100">
|
||||
<main className="w-100 exercise_add_main">
|
||||
|
|
@ -241,9 +227,9 @@ const AddPage: React.FC = () => {
|
|||
|
||||
<div className="exercise_add_buttons">
|
||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
||||
<button disabled={Loading} className="relative" type="button"
|
||||
onClick={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
|
||||
onSubmit={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
|
||||
<button disabled={Loading} className="relative" type="submit"
|
||||
onClick={()=>{handleValidateBaseQuestion(values) ;handleSubmit(values)}}
|
||||
onSubmit={()=>{handleValidateBaseQuestion(values) ;handleSubmit(values) }}
|
||||
>
|
||||
{t("practical.add")}
|
||||
|
||||
|
|
@ -276,12 +262,11 @@ const AddPage: React.FC = () => {
|
|||
enableReinitialize={true}
|
||||
initialValues={getInitialValues({} as any)}
|
||||
validationSchema={getValidationSchema}
|
||||
validateOnMount={true}
|
||||
onSubmit={(values) => {
|
||||
handleFormSubmit(values);
|
||||
handleSubmit(values);
|
||||
}}
|
||||
>
|
||||
{({ values,isValid ,handleSubmit}) => (
|
||||
{({ values,handleSubmit }) => (
|
||||
<Form className="w-100">
|
||||
<main className="w-100 exercise_add_main">
|
||||
<Header />
|
||||
|
|
@ -289,9 +274,12 @@ const AddPage: React.FC = () => {
|
|||
|
||||
<div className="exercise_add_buttons">
|
||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
||||
<div
|
||||
<button
|
||||
disabled={Loading}
|
||||
className="relative"
|
||||
onClick={()=>{ Loading ? ()=>{} : handleValidateSingleQuestion(values,isValid,handleSubmit) }}
|
||||
onClick={()=>{handleValidateSingleQuestion(values) ;handleSubmit(values)}}
|
||||
onSubmit={()=>{handleValidateSingleQuestion(values) ;handleSubmit(values) }}
|
||||
type="submit"
|
||||
>
|
||||
{t("practical.add")}
|
||||
|
||||
|
|
@ -300,7 +288,7 @@ const AddPage: React.FC = () => {
|
|||
<Spin />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
</Form>
|
||||
|
|
|
|||
|
|
@ -28,11 +28,10 @@ import { Form, Formik } from "formik";
|
|||
import { MdOutlineArrowForwardIos } from "react-icons/md";
|
||||
import { SettingFilled } from "@ant-design/icons";
|
||||
import { CheckboxProps } from "antd/lib";
|
||||
import { LocalStorageEnum } from "../../../enums/LocalStorageEnum";
|
||||
|
||||
const EditPage: React.FC = () => {
|
||||
const { subject_id, lesson_id, question_id } = useParams<ParamsEnum>();
|
||||
const { isBseQuestion, setIsBseQuestion, setTagsSearch, DeletedQuestions , ShowHint,setShowHint , ShowLatexOption,setShowLatexOption } =
|
||||
const { isBseQuestion, setIsBseQuestion, setTagsSearch, DeletedQuestions , ShowHint,setShowHint } =
|
||||
useObjectToEdit();
|
||||
|
||||
const { mutate, isSuccess, isLoading } = useUpdateQuestion();
|
||||
|
|
@ -46,7 +45,6 @@ const EditPage: React.FC = () => {
|
|||
const { data: Questions, isLoading: QuestionsDataLoading } =
|
||||
useGetAllQuestion({
|
||||
parent_id: question_id,
|
||||
isPaginated:false
|
||||
});
|
||||
|
||||
const objectToEdit = { ...data?.data, Questions: Questions?.data };
|
||||
|
|
@ -191,19 +189,20 @@ const EditPage: React.FC = () => {
|
|||
navigate(-1);
|
||||
};
|
||||
|
||||
const handleValidateSingleQuestion = (values:any,isValid:boolean,handleSubmit:any)=>{
|
||||
|
||||
const handleValidateSingleQuestion = (values:any)=>{
|
||||
const haveMoreThanOneAnswer = values?.answers?.length > 1;
|
||||
const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item:any)=> item?.isCorrect === 1 || item.isCorrect === true )
|
||||
const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
|
||||
const content = values.content ;
|
||||
const content_image = values.content_image ;
|
||||
const haveContentOrContentImage = !!content || !!content_image ;
|
||||
|
||||
console.log(haveImageOrContent,"haveImageOrContent");
|
||||
if(!haveContentOrContentImage){
|
||||
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!haveMoreThanOneAnswer){
|
||||
toast.error(t("validation.it_should_have_more_than_one_answers")) ;
|
||||
return false ;
|
||||
|
|
@ -217,26 +216,10 @@ const EditPage: React.FC = () => {
|
|||
return false
|
||||
}
|
||||
|
||||
console.log(1);
|
||||
|
||||
if(isValid){
|
||||
handleSubmit(values)
|
||||
}
|
||||
|
||||
}
|
||||
const handleValidateBaseQuestion = (values: any,isValid:boolean,handleSubmit:any) => {
|
||||
const content = values.content ;
|
||||
const content_image = values.content_image ;
|
||||
const haveContentOrContentImage = !!content || !!content_image ;
|
||||
console.log(2);
|
||||
|
||||
if(!haveContentOrContentImage){
|
||||
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
|
||||
return false;
|
||||
}
|
||||
console.log(1);
|
||||
|
||||
const isValidate = values?.Questions?.every((Question: any, QuestionsIndex: number) => {
|
||||
const handleValidateBaseQuestion = (values: any) => {
|
||||
const haveAnswers = values?.Questions?.every((Question: any, QuestionsIndex: number) => {
|
||||
|
||||
|
||||
const content = Question.content ;
|
||||
|
|
@ -252,12 +235,10 @@ const handleValidateBaseQuestion = (values: any,isValid:boolean,handleSubmit:any
|
|||
const answers = Question?.answers;
|
||||
const haveAnswers = answers?.length > 0;
|
||||
const haveMoreThanOneAnswer = haveAnswers && answers?.length > 1;
|
||||
const haveOneAnswerRight = haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true);
|
||||
const haveOneAnswerRight =
|
||||
haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true);
|
||||
const haveImageOrContent = haveOneAnswerRight && answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
|
||||
|
||||
|
||||
|
||||
|
||||
if (!haveAnswers) {
|
||||
toast.error(t("validation.it_should_have_more_than_one_answers"));
|
||||
return false;
|
||||
|
|
@ -278,18 +259,14 @@ const handleValidateBaseQuestion = (values: any,isValid:boolean,handleSubmit:any
|
|||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
console.log(1);
|
||||
|
||||
if(isValid && isValidate){
|
||||
console.log(2);
|
||||
handleSubmit(values)
|
||||
}
|
||||
|
||||
console.log(haveAnswers, "haveAnswers");
|
||||
};
|
||||
|
||||
|
||||
const handleNavigateToPage = () => {
|
||||
const cleanedUrl = location.pathname.replace(/\/Question\/\d+$/, "");
|
||||
navigate(cleanedUrl);
|
||||
|
|
@ -302,29 +279,17 @@ const handleNavigateToPage = () => {
|
|||
}
|
||||
}, [isSuccess]);
|
||||
|
||||
const onChangeHint: CheckboxProps['onChange'] = (e) => {
|
||||
const onChange: CheckboxProps['onChange'] = (e) => {
|
||||
setShowHint(e.target.checked);
|
||||
localStorage?.setItem(LocalStorageEnum.HINT_INPUT,e.target.checked ? "true" : "false" )
|
||||
};
|
||||
|
||||
const onChangeLatexOption: CheckboxProps['onChange'] = (e) => {
|
||||
setShowLatexOption(e.target.checked);
|
||||
localStorage?.setItem(LocalStorageEnum.LATEX_OPTION_INPUT,e.target.checked ? "true" : "false" )
|
||||
};
|
||||
|
||||
|
||||
const contentSetting = (
|
||||
<div>
|
||||
|
||||
<Checkbox checked={ShowHint} onChange={onChangeHint}>
|
||||
<Checkbox checked={ShowHint} onChange={onChange}>
|
||||
{ t("header.show_hint")}
|
||||
</Checkbox>
|
||||
|
||||
<Checkbox checked={ShowLatexOption} onChange={onChangeLatexOption}>
|
||||
{ t("header.show_MMl")}
|
||||
</Checkbox>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
@ -351,7 +316,7 @@ const handleNavigateToPage = () => {
|
|||
validationSchema={getValidationSchemaBase}
|
||||
enableReinitialize
|
||||
>
|
||||
{({ values,isValid,handleSubmit }) => (
|
||||
{({ values,handleSubmit }) => (
|
||||
|
||||
<Form className="w-100">
|
||||
<main className="w-100 exercise_add_main">
|
||||
|
|
@ -371,9 +336,9 @@ const handleNavigateToPage = () => {
|
|||
<BaseForm />
|
||||
<div className="exercise_add_buttons">
|
||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
||||
<button disabled={Loading} className="relative" type="button"
|
||||
onClick={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
|
||||
onSubmit={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
|
||||
<button disabled={Loading} className="relative" type="submit"
|
||||
onClick={()=>{handleValidateBaseQuestion(values) ;handleSubmit(values)}}
|
||||
onSubmit={()=>{handleValidateBaseQuestion(values) ;handleSubmit(values) }}
|
||||
> {t("practical.edit")}
|
||||
|
||||
{Loading && (
|
||||
|
|
@ -410,7 +375,7 @@ const handleNavigateToPage = () => {
|
|||
handleSubmit(values);
|
||||
}}
|
||||
>
|
||||
{({ values , dirty,isValid,handleSubmit }) => (
|
||||
{({ values,handleSubmit , dirty }) => (
|
||||
<Form className="w-100">
|
||||
<main className="w-100 exercise_add_main">
|
||||
{/* <Header/> */}
|
||||
|
|
@ -418,28 +383,25 @@ const handleNavigateToPage = () => {
|
|||
<div>
|
||||
{t("practical.edit")} {t("models.exercise")}{" "}
|
||||
</div>
|
||||
<div className="SettingEdit">
|
||||
|
||||
<Popover trigger="click" content={contentSetting}>
|
||||
<SettingFilled/>
|
||||
|
||||
</Popover>
|
||||
<div>{t("header.exercise")}</div>
|
||||
</div>
|
||||
</header>
|
||||
<ModelForm />
|
||||
<div className="exercise_add_buttons">
|
||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
||||
<div
|
||||
<button
|
||||
disabled={Loading || !dirty}
|
||||
className="relative"
|
||||
onClick={()=>{ Loading ? ()=>{} : handleValidateSingleQuestion(values,isValid,handleSubmit) }}
|
||||
onClick={()=>{handleValidateSingleQuestion(values) ;handleSubmit(values)}}
|
||||
onSubmit={()=>{handleValidateSingleQuestion(values) ;handleSubmit(values) }}
|
||||
type="submit"
|
||||
|
||||
> {t("practical.edit")}
|
||||
{Loading && (
|
||||
<span className="Spinier_Div">
|
||||
<Spin />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
import React from "react";
|
||||
import { Choice } from "../../../../../types/Item";
|
||||
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||
import { Field, useFormikContext } from "formik";
|
||||
import { useFormikContext } from "formik";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { getCharFromNumber } from "../../../../../utils/getCharFromNumber";
|
||||
import CheckboxField from "./CheckboxField";
|
||||
import TextField from "./TextField";
|
||||
import ImageBoxField from "../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
|
||||
import { GoTrash } from "react-icons/go";
|
||||
import { Popconfirm } from "antd";
|
||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
||||
import LaTeXInputMemo from "../../../../../Components/LatextInput/LaTeXInputMemo";
|
||||
import ImageBoxFieldMemo from "../../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo";
|
||||
|
||||
const ChoiceFields = ({ index }: { index: number; data: Choice }) => {
|
||||
const formik = useFormikContext<any>();
|
||||
|
|
@ -42,15 +43,22 @@ const ChoiceFields = ({ index }: { index: number; data: Choice }) => {
|
|||
return (
|
||||
<>
|
||||
<div id={`ChoiceField_${index}`} className="ChoiceFields">
|
||||
<Field
|
||||
component={LaTeXInputMemo}
|
||||
id={`choice_${index + 1}`} name={`answers.${index}.content`} label={t(`input.choice`) + ` ` +`( ${index + 1} )`}
|
||||
/>
|
||||
<Field
|
||||
component={ImageBoxFieldMemo}
|
||||
name={`answers.${index}.content_image`}
|
||||
<TextField
|
||||
className="textarea_exercise"
|
||||
placeholder={"choice"}
|
||||
label2={
|
||||
t(`input.choice`) +
|
||||
` ` +
|
||||
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
|
||||
}
|
||||
name={index}
|
||||
id={`choice_${index + 1}`}
|
||||
type="TextArea"
|
||||
|
||||
/>
|
||||
|
||||
<ImageBoxField name={`answers.${index}.content_image`} />
|
||||
|
||||
<div className="answer_status">
|
||||
<CheckboxField
|
||||
className=""
|
||||
|
|
|
|||
72
src/Pages/Admin/question/Model/Field/TextField.tsx
Normal file
72
src/Pages/Admin/question/Model/Field/TextField.tsx
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { Form, Input } from "antd";
|
||||
import React from "react";
|
||||
import useFormField from "../../../../../Hooks/useFormField";
|
||||
import { MdOutlineEdit } from "react-icons/md";
|
||||
import { Field } from "formik";
|
||||
const { TextArea } = Input;
|
||||
|
||||
const TextField = ({
|
||||
name,
|
||||
label,
|
||||
label2,
|
||||
placeholder,
|
||||
isDisabled,
|
||||
onChange,
|
||||
props,
|
||||
no_label,
|
||||
label_icon,
|
||||
id,
|
||||
className,
|
||||
}: any) => {
|
||||
const newName = `answers[${name}].content`;
|
||||
const { formik, isError, errorMsg, t } = useFormField(newName, props);
|
||||
const TextFilehandleChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
// console.log('Change:', e.target.value);
|
||||
formik.setFieldValue(newName, e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`ValidationField w-100 ${className ?? ""} `}>
|
||||
{no_label ? (
|
||||
<label htmlFor={name} className="text">
|
||||
<span>empty</span>
|
||||
</label>
|
||||
) : label_icon ? (
|
||||
<div className="LabelWithIcon">
|
||||
<label htmlFor={name} className="text">
|
||||
{label2 ? label2 : t(`input.${label ? label : name}`)}
|
||||
</label>
|
||||
<MdOutlineEdit size={22} style={{ color: "#A098AE" }} />
|
||||
</div>
|
||||
) : (
|
||||
<label htmlFor={name} className="text">
|
||||
{label2 ? label2 : t(`input.${label ? label : name}`)}
|
||||
</label>
|
||||
)}
|
||||
|
||||
<Form.Item
|
||||
hasFeedback
|
||||
validateStatus={isError ? "error" : ""}
|
||||
help={isError ? errorMsg : ""}
|
||||
>
|
||||
<Field
|
||||
as={TextArea}
|
||||
placeholder={t(`input.${placeholder ? placeholder : name}`)}
|
||||
name={newName}
|
||||
disabled={isDisabled}
|
||||
size="large"
|
||||
showCount
|
||||
maxLength={1000}
|
||||
onChange={onChange || TextFilehandleChange}
|
||||
autoSize={{ minRows: 4, maxRows: 10 }}
|
||||
|
||||
id={id}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(TextField);
|
||||
|
|
@ -16,7 +16,7 @@ const CheckboxField = ({
|
|||
const [t] = useTranslation();
|
||||
const CheckboxhandleChange = (value: any) => {
|
||||
const allAreZero = formik?.values?.Questions?.[parent_index]?.answers?.some(
|
||||
(item: any) => item.isCorrect === 1 || item.isCorrect === true,
|
||||
(item: any) => item.isCorrect === 1,
|
||||
);
|
||||
if (allAreZero) {
|
||||
formik?.values?.Questions?.[parent_index]?.answers.forEach(
|
||||
|
|
|
|||
|
|
@ -1,47 +1,48 @@
|
|||
import React from "react";
|
||||
import { Choice } from "../../../../../../types/Item";
|
||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
||||
import { Field } from "formik";
|
||||
import { useFormikContext } from "formik";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { getCharFromNumber } from "../../../../../../utils/getCharFromNumber";
|
||||
import CheckboxField from "./CheckboxField";
|
||||
import TextField from "./TextField";
|
||||
import { toast } from "react-toastify";
|
||||
import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
|
||||
import { GoTrash } from "react-icons/go";
|
||||
import { Popconfirm } from "antd";
|
||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
||||
import LaTeXInputMemo from "../../../../../../Components/LatextInput/LaTeXInputMemo";
|
||||
import ImageBoxFieldMemo from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo";
|
||||
|
||||
const ChoiceFields = React.memo(
|
||||
({
|
||||
const ChoiceFields = ({
|
||||
index,
|
||||
parent_index,
|
||||
setFieldValue,
|
||||
values
|
||||
data,
|
||||
}: {
|
||||
index: number;
|
||||
parent_index: number;
|
||||
setFieldValue:any;
|
||||
values:any
|
||||
data: Choice;
|
||||
}) => {
|
||||
console.log(567)
|
||||
const formik = useFormikContext<any>();
|
||||
|
||||
const [t] = useTranslation();
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
const handleDeleteChoice = () => {
|
||||
document.getElementById(`ChoiceField_${parent_index}_${index}`)?.classList.add("exit")
|
||||
|
||||
const updatedAnswers = values.Questions?.[
|
||||
const updatedAnswers = formik.values.Questions?.[
|
||||
parent_index
|
||||
].answers.filter((_: any, i: any) => i !== index);
|
||||
setTimeout(() => {
|
||||
setFieldValue(`Questions[${parent_index}].answers`, updatedAnswers);
|
||||
formik.setFieldValue(`Questions[${parent_index}].answers`, updatedAnswers);
|
||||
document.getElementById(`ChoiceField_${parent_index}_${index}`)?.classList.remove("exit")
|
||||
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const value = values.Questions?.[parent_index]?.answers?.[index] ;
|
||||
const values = formik.values.Questions?.[parent_index]?.answers?.[index] ;
|
||||
|
||||
const handelCanDeleteAnswers = ()=>{
|
||||
const content = value?.content ;
|
||||
const content_image = value?.content_image ;
|
||||
const content = values?.content ;
|
||||
const content_image = values?.content_image ;
|
||||
if(!content && !content_image ){
|
||||
return true
|
||||
}
|
||||
|
|
@ -52,22 +53,23 @@ const ChoiceFields = React.memo(
|
|||
return (
|
||||
<>
|
||||
<div id={`ChoiceField_${parent_index}_${index}`} className="ChoiceFields">
|
||||
|
||||
<Field
|
||||
component={LaTeXInputMemo}
|
||||
name={`Questions[${parent_index}].answers[${index}].content`} label={
|
||||
<TextField
|
||||
className="textarea_exercise"
|
||||
placeholder={"choice"}
|
||||
label2={
|
||||
t(`input.choice`) +
|
||||
` ` +
|
||||
`( ${index + 1} )`
|
||||
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
|
||||
}
|
||||
name={index}
|
||||
parent_index={parent_index}
|
||||
type="TextArea"
|
||||
/>
|
||||
|
||||
<Field
|
||||
component={ImageBoxFieldMemo}
|
||||
<ImageBoxField
|
||||
name={`Questions.${parent_index}.answers.${index}.content_image`}
|
||||
/>
|
||||
|
||||
|
||||
<div className="answer_status">
|
||||
<CheckboxField
|
||||
className=""
|
||||
|
|
@ -114,15 +116,23 @@ const ChoiceFields = React.memo(
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint &&
|
||||
<ValidationField
|
||||
className="hint"
|
||||
placeholder="_"
|
||||
name={`Questions.${parent_index}.answers.${index}.hint`}
|
||||
label="hint"
|
||||
type="TextArea"
|
||||
style={{ width: "100%" , height: 60,resize:"none" }}
|
||||
showCount={false}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
/>
|
||||
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
, (prevProps, nextProps) => {
|
||||
console.log(prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[prevProps?.index] === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[prevProps?.index]);
|
||||
console.log(2255);
|
||||
|
||||
return prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[prevProps?.index] === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[prevProps?.index];
|
||||
});
|
||||
};
|
||||
|
||||
export default ChoiceFields;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import React from "react";
|
||||
import ChoiceFields from "./ChoiceFields";
|
||||
import { Choice } from "../../../../../../types/Item";
|
||||
// import { useFormikContext } from "formik";
|
||||
// import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
|
||||
// import { HolderOutlined } from "@ant-design/icons";
|
||||
import { useFormikContext } from "formik";
|
||||
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
|
||||
import { HolderOutlined } from "@ant-design/icons";
|
||||
|
||||
const Choices = React.memo( ({setFieldValue ,values,parent_index }:any) => {
|
||||
const Choices = ({ parent_index }: { parent_index: number }) => {
|
||||
const formik = useFormikContext<any>();
|
||||
|
||||
const handleDragEnd = (result: any) => {
|
||||
// Check if the item was dropped outside the list
|
||||
|
|
@ -14,11 +15,11 @@ const Choices = React.memo( ({setFieldValue ,values,parent_index }:any) => {
|
|||
|
||||
if (!result.destination) return;
|
||||
|
||||
console.log(values?.Questions?.[parent_index]?.answers);
|
||||
console.log(formik?.values?.Questions?.[parent_index]?.answers);
|
||||
|
||||
// Create a new array from the current answers
|
||||
const items = Array.from(
|
||||
values?.Questions?.[parent_index]?.answers,
|
||||
formik?.values?.Questions?.[parent_index]?.answers,
|
||||
);
|
||||
console.log(items);
|
||||
// Remove the item from the original position
|
||||
|
|
@ -35,21 +36,18 @@ const Choices = React.memo( ({setFieldValue ,values,parent_index }:any) => {
|
|||
order: index + 1, // Update order to be 1-based index
|
||||
}));
|
||||
|
||||
// Update the state with the new order
|
||||
// Update the formik state with the new order
|
||||
console.log(updatedItems, "updatedItems");
|
||||
|
||||
setFieldValue(`Questions.${parent_index}.answers`, updatedItems);
|
||||
formik.setFieldValue(`Questions.${parent_index}.answers`, updatedItems);
|
||||
};
|
||||
console.log(123);
|
||||
console.log(setFieldValue);
|
||||
console.log(values?.Questions?.[parent_index]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<div>
|
||||
{(
|
||||
values?.Questions?.[parent_index]?.answers ||
|
||||
(formik?.values as any)?.Questions?.[parent_index]?.answers ||
|
||||
[]
|
||||
).map((item: Choice, index: number) => {
|
||||
return (
|
||||
|
|
@ -61,8 +59,7 @@ const Choices = React.memo( ({setFieldValue ,values,parent_index }:any) => {
|
|||
key={index}
|
||||
parent_index={parent_index}
|
||||
index={index}
|
||||
setFieldValue={setFieldValue}
|
||||
values={values}
|
||||
data={item}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -115,11 +112,6 @@ const Choices = React.memo( ({setFieldValue ,values,parent_index }:any) => {
|
|||
</DragDropContext> */}
|
||||
</>
|
||||
);
|
||||
}, (prevProps, nextProps) => {
|
||||
console.log(prevProps.values?.Questions?.[prevProps?.parent_index]?.answers === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers);
|
||||
console.log(22);
|
||||
|
||||
return prevProps.values?.Questions?.[prevProps?.parent_index]?.answers === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers;
|
||||
});
|
||||
};
|
||||
|
||||
export default Choices;
|
||||
|
|
|
|||
|
|
@ -1,19 +1,27 @@
|
|||
import { Row } from "reactstrap";
|
||||
import { Col, Row } from "reactstrap";
|
||||
import React, { useEffect } from "react";
|
||||
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||
import { useFormikContext } from "formik";
|
||||
import { FaCirclePlus } from "react-icons/fa6";
|
||||
import { Choice } from "../../../../../types/Item";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import QuestionFIeld from "./QuestionFIeld/QuestionFIeld";
|
||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
||||
import Choices from "./ChoiceField/Choices";
|
||||
import ImageBoxField from "../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
|
||||
import MaltySelectTag from "./Tags/MaltySelectTag";
|
||||
import useKeyCombination from "../../../../../Hooks/useKeyCombination";
|
||||
import { CombinationKeyEnum } from "../../../../../enums/CombinationKeyEnum";
|
||||
import { toast } from "react-toastify";
|
||||
import MainInputs from "./components/MainInputs";
|
||||
import Questions from "./components/Questions";
|
||||
|
||||
const Form = () => {
|
||||
const formik = useFormikContext<any>();
|
||||
const { setSuccess, Success ,ShowHint} = useObjectToEdit();
|
||||
const { setSuccess, Success, setSavedQuestionData ,ShowHint} = useObjectToEdit();
|
||||
console.log(formik.errors);
|
||||
|
||||
useEffect(() => {
|
||||
setSavedQuestionData(formik.values);
|
||||
}, [formik?.values]);
|
||||
|
||||
const handleAddChoice = (
|
||||
parent_index: number,
|
||||
|
|
@ -62,7 +70,6 @@ const Form = () => {
|
|||
};
|
||||
const [t] = useTranslation();
|
||||
|
||||
|
||||
const lastQuestions = formik?.values?.Questions?.length - 1;
|
||||
useKeyCombination(
|
||||
{ ctrlKey: true, shiftKey: true, code: CombinationKeyEnum.CHOICE },
|
||||
|
|
@ -93,9 +100,65 @@ const lastQuestions = formik?.values?.Questions?.length - 1;
|
|||
|
||||
return (
|
||||
<Row className="w-100 exercise_form_container">
|
||||
<MainInputs/>
|
||||
<div className="exercise_form">
|
||||
<ValidationField
|
||||
className="textarea_exercise"
|
||||
name="content"
|
||||
label="main_question"
|
||||
type="TextArea"
|
||||
/>
|
||||
<ImageBoxField name="content_image" />
|
||||
|
||||
<div></div>
|
||||
</div>
|
||||
<div className="flex"></div>
|
||||
<Questions setFieldValue={formik.setFieldValue} values={formik.values} />
|
||||
|
||||
{((formik?.values as any)?.Questions || [])?.map(
|
||||
(item: Choice, parent_index: number) => {
|
||||
return (
|
||||
<div key={parent_index}>
|
||||
<div className="exercise_form QuestionFIeld">
|
||||
<QuestionFIeld
|
||||
key={parent_index}
|
||||
index={parent_index}
|
||||
data={item}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Choices parent_index={parent_index} />
|
||||
|
||||
{formik?.values?.Questions?.[parent_index]?.answers?.length <
|
||||
5 && (
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus
|
||||
onClick={() => handleAddChoice(parent_index)}
|
||||
size={23}
|
||||
/>{" "}
|
||||
{t("header.add_new_choice")}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint &&
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${parent_index}.hint`}
|
||||
label="hint_question"
|
||||
type="TextArea"
|
||||
style={{ width: "100%" , height: 60,resize:"none" }}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
showCount={false}
|
||||
/>
|
||||
|
||||
}
|
||||
<MaltySelectTag parent_index={parent_index} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
)}
|
||||
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus onClick={() => handleAddQuestion()} size={23} />{" "}
|
||||
{t("header.add_new_question")}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect } from "react";
|
||||
import { Choice } from "../../../../../../types/Item";
|
||||
import { Field, useFormikContext } from "formik";
|
||||
import { useFormikContext } from "formik";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { getCharFromNumber } from "../../../../../../utils/getCharFromNumber";
|
||||
import TextField from "./TextField";
|
||||
|
|
@ -8,11 +8,8 @@ import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|||
import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
|
||||
import { GoTrash } from "react-icons/go";
|
||||
import { Popconfirm } from "antd";
|
||||
import LaTeXInput from "../../../../../../Components/LatextInput/LaTeXInput";
|
||||
import LaTeXInputMemo from "../../../../../../Components/LatextInput/LaTeXInputMemo";
|
||||
import ImageBoxFieldMemo from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo";
|
||||
|
||||
const QuestionFIeld = ({ index , setFieldValue,values }: { index: number , setFieldValue:any,values:any }) => {
|
||||
const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
|
||||
const formik = useFormikContext<any>();
|
||||
const { setDeletedQuestions, DeletedQuestions } = useObjectToEdit();
|
||||
|
||||
|
|
@ -34,11 +31,11 @@ const QuestionFIeld = ({ index , setFieldValue,values }: { index: number , setFi
|
|||
|
||||
|
||||
|
||||
const value = formik.values.Questions?.[index] ;
|
||||
const values = formik.values.Questions?.[index] ;
|
||||
|
||||
const handelCanDeleteAnswers = ()=>{
|
||||
const content = value?.content ;
|
||||
const content_image = value?.content_image ;
|
||||
const content = values?.content ;
|
||||
const content_image = values?.content_image ;
|
||||
if(!content && !content_image ){
|
||||
return true
|
||||
}
|
||||
|
|
@ -51,18 +48,21 @@ const QuestionFIeld = ({ index , setFieldValue,values }: { index: number , setFi
|
|||
<>
|
||||
<div className="exercise_forms">
|
||||
<div className="ChoiceFields">
|
||||
<Field
|
||||
component={LaTeXInputMemo}
|
||||
id={`question_${index + 1}`} name={`Questions[${index}].content`} label={
|
||||
<TextField
|
||||
className="textarea_exercise"
|
||||
placeholder={"question"}
|
||||
label2={
|
||||
t(`input.question`) +
|
||||
` ` +
|
||||
`( ${index + 1} )`
|
||||
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
|
||||
}
|
||||
name={index}
|
||||
id={`question_${index + 1}`}
|
||||
type="TextArea"
|
||||
/>
|
||||
<Field
|
||||
component={ImageBoxFieldMemo}
|
||||
name={`Questions.${index}.content_image`}
|
||||
/>
|
||||
|
||||
<ImageBoxField name={`Questions.${index}.content_image`} />
|
||||
|
||||
{handelCanDeleteAnswers() ?
|
||||
<div className="answer_status" >
|
||||
<p className="delete_question_options" onClick={()=>{handleDeleteQuestion()}}>
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
import React from 'react'
|
||||
|
||||
const QuestionList = () => {
|
||||
return (
|
||||
<div>QuestionList</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default QuestionList
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import { Field } from 'formik'
|
||||
import React from 'react'
|
||||
import LaTeXInputMemo from '../../../../../../Components/LatextInput/LaTeXInputMemo'
|
||||
import ImageBoxFieldMemo from '../../../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const MainInputs = () => {
|
||||
const [t] = useTranslation()
|
||||
return (
|
||||
<div className="exercise_form">
|
||||
<Field
|
||||
name="content"
|
||||
component={LaTeXInputMemo}
|
||||
label={t("input.answer_content")}
|
||||
/>
|
||||
|
||||
<Field
|
||||
component={ImageBoxFieldMemo}
|
||||
name="content_image"
|
||||
/>
|
||||
|
||||
<div></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MainInputs
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
import React, { useCallback, useMemo } from 'react';
|
||||
import { FixedSizeList as List, areEqual } from 'react-window';
|
||||
import { Choice } from '../../../../../../types/Item';
|
||||
import QuestionFIeld from '../QuestionFIeld/QuestionFIeld';
|
||||
import Choices from '../ChoiceField/Choices';
|
||||
import { FaCirclePlus } from 'react-icons/fa6';
|
||||
import ValidationField from '../../../../../../Components/ValidationField/ValidationField';
|
||||
import MaltySelectTag from '../Tags/MaltySelectTag';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useObjectToEdit } from '../../../../../../zustand/ObjectToEditState';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
interface QuestionsProps {
|
||||
setFieldValue: (field: string, value: any) => void;
|
||||
values: {
|
||||
Questions: Choice[];
|
||||
};
|
||||
}
|
||||
|
||||
const Row: React.FC<any> = React.memo(({ index, data }) => {
|
||||
const { values, setFieldValue } = data;
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleAddChoice = useCallback((
|
||||
parent_index: number,
|
||||
fromKeyCombination: boolean = false,
|
||||
) => {
|
||||
setFieldValue(`Questions.[${parent_index}].answers`, [
|
||||
...(values?.Questions?.[parent_index]?.answers as Choice[]),
|
||||
{
|
||||
answer: null,
|
||||
content_image: null,
|
||||
content: null,
|
||||
isCorrect: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
if (fromKeyCombination) {
|
||||
toast.success(t("header.new_choice_have_been_added"));
|
||||
}
|
||||
}, [setFieldValue, values, t]);
|
||||
|
||||
return (
|
||||
<div key={index}>
|
||||
<div className="exercise_form QuestionFIeld">
|
||||
<QuestionFIeld setFieldValue={setFieldValue} values={values} key={index} index={index} />
|
||||
</div>
|
||||
|
||||
<Choices setFieldValue={setFieldValue} values={values} parent_index={index} />
|
||||
|
||||
{values?.Questions?.[index]?.answers?.length < 5 && (
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus
|
||||
onClick={() => handleAddChoice(index)}
|
||||
size={23}
|
||||
/>{" "}
|
||||
{t("header.add_new_choice")}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint && (
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${index}.hint`}
|
||||
label="hint_question"
|
||||
type="TextArea"
|
||||
style={{ width: "100%", height: 60, resize: "none" }}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
showCount={false}
|
||||
/>
|
||||
)}
|
||||
<MaltySelectTag parent_index={index} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}, areEqual);
|
||||
|
||||
const Questions: React.FC<QuestionsProps> = React.memo(({ setFieldValue, values }) => {
|
||||
const questions = values.Questions || [];
|
||||
|
||||
const itemData = useMemo(() => ({ values, setFieldValue }), [values, setFieldValue]);
|
||||
const itemSize = 1100;
|
||||
const listHeight = useMemo(() => {
|
||||
return Math.min(1300, questions.length * itemSize); // Adjust 400 to your desired max height
|
||||
}, [questions.length]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<List
|
||||
height={listHeight}
|
||||
itemCount={questions.length}
|
||||
itemSize={itemSize}
|
||||
width="100%"
|
||||
itemData={itemData}
|
||||
direction='rtl'
|
||||
>
|
||||
{Row}
|
||||
</List>
|
||||
|
||||
{/* {(values?.Questions || [])?.map(
|
||||
(item: Choice, parent_index: number) => {
|
||||
return (
|
||||
<Row key={parent_index} index={parent_index} data={{values, setFieldValue}} />
|
||||
);
|
||||
}
|
||||
)} */}
|
||||
|
||||
</>
|
||||
);
|
||||
}, (prevProps, nextProps) => prevProps.values.Questions === nextProps.values.Questions);
|
||||
|
||||
export default Questions;
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
import React from 'react'
|
||||
import QuestionFIeld from '../QuestionFIeld/QuestionFIeld';
|
||||
import { Choice } from '../../../../../../types/Item';
|
||||
import Choices from '../ChoiceField/Choices';
|
||||
import { FaCirclePlus } from 'react-icons/fa6';
|
||||
import ValidationField from '../../../../../../Components/ValidationField/ValidationField';
|
||||
import MaltySelectTag from '../Tags/MaltySelectTag';
|
||||
import { useObjectToEdit } from '../../../../../../zustand/ObjectToEditState';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
// Memoized Questions Component
|
||||
const Questions = React.memo(({setFieldValue,values}:any) => {
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleAddChoice = (
|
||||
parent_index: number,
|
||||
fromKeyCombination: boolean = false,
|
||||
) => {
|
||||
setFieldValue(`Questions.[${parent_index}].answers`, [
|
||||
...((values as any)?.Questions?.[parent_index]
|
||||
?.answers as Choice[]),
|
||||
{
|
||||
answer: null,
|
||||
content_image: null,
|
||||
content: null,
|
||||
isCorrect: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
if (fromKeyCombination) {
|
||||
toast.success(t("header.new_choice_have_been_added"));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{(values?.Questions || [])?.map(
|
||||
(item: Choice, parent_index: number) => {
|
||||
return (
|
||||
<div key={parent_index}>
|
||||
<div className="exercise_form QuestionFIeld">
|
||||
<QuestionFIeld setFieldValue={setFieldValue} values={values} key={parent_index} index={parent_index} />
|
||||
</div>
|
||||
|
||||
<Choices setFieldValue={setFieldValue} values={values} parent_index={parent_index} />
|
||||
|
||||
{values?.Questions?.[parent_index]?.answers?.length < 5 && (
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus
|
||||
onClick={() => handleAddChoice(parent_index)}
|
||||
size={23}
|
||||
/>{" "}
|
||||
{t("header.add_new_choice")}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint && (
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${parent_index}.hint`}
|
||||
label="hint_question"
|
||||
type="TextArea"
|
||||
style={{ width: "100%", height: 60, resize: "none" }}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
showCount={false}
|
||||
/>
|
||||
)}
|
||||
<MaltySelectTag parent_index={parent_index} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}, (prevProps, nextProps) => {
|
||||
|
||||
return prevProps.values.Questions === nextProps.values.Questions;
|
||||
});
|
||||
|
||||
export default Questions;
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
import React, { useCallback, useMemo, useRef, useEffect } from 'react';
|
||||
import { VariableSizeList as List } from 'react-window';
|
||||
import { Choice } from '../../../../../../types/Item';
|
||||
import QuestionFIeld from '../QuestionFIeld/QuestionFIeld';
|
||||
import Choices from '../ChoiceField/Choices';
|
||||
import { FaCirclePlus } from 'react-icons/fa6';
|
||||
import ValidationField from '../../../../../../Components/ValidationField/ValidationField';
|
||||
import MaltySelectTag from '../Tags/MaltySelectTag';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useObjectToEdit } from '../../../../../../zustand/ObjectToEditState';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
interface QuestionsProps {
|
||||
setFieldValue: (field: string, value: any) => void;
|
||||
values: {
|
||||
Questions: any[];
|
||||
};
|
||||
}
|
||||
|
||||
const Row: React.FC<any> = React.memo(({ index, style, data }) => {
|
||||
const { values, setFieldValue, ShowHint, t } = data;
|
||||
|
||||
const handleAddChoice = useCallback((
|
||||
parent_index: number,
|
||||
fromKeyCombination: boolean = false,
|
||||
) => {
|
||||
setFieldValue(`Questions.[${parent_index}].answers`, [
|
||||
...(values?.Questions?.[parent_index]?.answers as Choice[]),
|
||||
{
|
||||
answer: null,
|
||||
content_image: null,
|
||||
content: null,
|
||||
isCorrect: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
if (fromKeyCombination) {
|
||||
toast.success(t("header.new_choice_have_been_added"));
|
||||
}
|
||||
}, [setFieldValue, values, t]);
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<div className="exercise_form QuestionFIeld">
|
||||
<QuestionFIeld setFieldValue={setFieldValue} values={values} key={index} index={index} />
|
||||
</div>
|
||||
|
||||
<Choices setFieldValue={setFieldValue} values={values} parent_index={index} />
|
||||
|
||||
{values?.Questions?.[index]?.answers?.length < 5 && (
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus
|
||||
onClick={() => handleAddChoice(index)}
|
||||
size={23}
|
||||
/>{" "}
|
||||
{t("header.add_new_choice")}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint && (
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${index}.hint`}
|
||||
label="hint_question"
|
||||
type="TextArea"
|
||||
style={{ width: "100%", height: 60, resize: "none" }}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
showCount={false}
|
||||
/>
|
||||
)}
|
||||
<MaltySelectTag parent_index={index} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const Questions: React.FC<QuestionsProps> = React.memo(({ setFieldValue, values }) => {
|
||||
const questions = values.Questions || [];
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
const [t] = useTranslation();
|
||||
const listRef = useRef<List>(null);
|
||||
|
||||
const getItemSize = useCallback((index: number) => {
|
||||
const question = questions[index];
|
||||
let height = 300; // Base height for QuestionField
|
||||
|
||||
height += (question.answers?.length || 0) * 212; // Height for each answer
|
||||
if (question.answers?.length < 5) height += 40; // "Add new choice" button
|
||||
if (ShowHint) height += 80; // Hint field
|
||||
height += 50; // MaltySelectTag
|
||||
|
||||
return height;
|
||||
}, [questions, ShowHint]);
|
||||
|
||||
const itemData = useMemo(() => ({
|
||||
values,
|
||||
setFieldValue,
|
||||
ShowHint,
|
||||
t
|
||||
}), [values, setFieldValue, ShowHint, t]);
|
||||
|
||||
useEffect(() => {
|
||||
if (listRef.current) {
|
||||
listRef.current.resetAfterIndex(0);
|
||||
}
|
||||
}, [questions, ShowHint]);
|
||||
|
||||
return (
|
||||
<List
|
||||
ref={listRef}
|
||||
height={window.innerHeight - 20} // Adjust based on your layout
|
||||
itemCount={questions.length}
|
||||
itemSize={getItemSize}
|
||||
width="100%"
|
||||
itemData={itemData}
|
||||
direction='rtl'
|
||||
className='ListQuestions'
|
||||
>
|
||||
{Row}
|
||||
</List>
|
||||
);
|
||||
}, (prevProps, nextProps) => prevProps.values.Questions === nextProps.values.Questions);
|
||||
|
||||
export default Questions;
|
||||
|
|
@ -1,18 +1,17 @@
|
|||
import { Row } from "reactstrap";
|
||||
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||
import { Field, useFormikContext } from "formik";
|
||||
import { useFormikContext } from "formik";
|
||||
import { FaCirclePlus } from "react-icons/fa6";
|
||||
import { Choice } from "../../../../types/Item";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
||||
import { useEffect } from "react";
|
||||
import Choices from "./Field/Choices";
|
||||
import ImageBoxField from "../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
|
||||
import SelectTag from "../../../../Components/CustomFields/SelectTag";
|
||||
import useKeyCombination from "../../../../Hooks/useKeyCombination";
|
||||
import { CombinationKeyEnum } from "../../../../enums/CombinationKeyEnum";
|
||||
import { toast } from "react-toastify";
|
||||
import LaTeXInput from "../../../../Components/LatextInput/LaTeXInput";
|
||||
import LaTeXInputMemo from "../../../../Components/LatextInput/LaTeXInputMemo";
|
||||
import ImageBoxFieldMemo from "../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo";
|
||||
|
||||
const Form = () => {
|
||||
const [t] = useTranslation();
|
||||
|
|
@ -52,16 +51,13 @@ const Form = () => {
|
|||
return (
|
||||
<Row className="w-100 exercise_form_container">
|
||||
<div className="exercise_form">
|
||||
<Field
|
||||
<ValidationField
|
||||
className="textarea_exercise"
|
||||
name="content"
|
||||
component={LaTeXInputMemo}
|
||||
label={t("input.answer_content")}
|
||||
/>
|
||||
|
||||
<Field
|
||||
component={ImageBoxFieldMemo}
|
||||
name="content_image"
|
||||
label="answer_content"
|
||||
type="TextArea"
|
||||
/>
|
||||
<ImageBoxField name="content_image" />
|
||||
</div>
|
||||
|
||||
<Choices />
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ export const getValidationSchema = () => {
|
|||
"At least one of content or content_image must be provided",
|
||||
(obj:any) => {
|
||||
const isValid = !!obj.content || !!obj.content_image;
|
||||
console.log(isValid,"isValid");
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
|
@ -82,7 +83,7 @@ export const getInitialValuesBase = (objectToEdit: Question): any => {
|
|||
|
||||
return {
|
||||
id: objectToEdit?.id ?? null,
|
||||
content: objectToEdit?.content ?? null,
|
||||
content: objectToEdit?.content ?? "",
|
||||
content_image: objectToEdit?.content_image ?? "",
|
||||
subject_id: objectToEdit?.subject_id ?? "",
|
||||
isBase: 1,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ const TableWithHeader = () => {
|
|||
const deleteMutation = useDeleteSubject();
|
||||
|
||||
const { grade_id } = useParams<ParamsEnum>();
|
||||
console.log(grade_id);
|
||||
|
||||
const { data: grade } = useGetAllGrade({
|
||||
show: grade_id,
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ export const useColumns = () => {
|
|||
dataIndex: "name",
|
||||
key: "name",
|
||||
align: "center",
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: t("columns.icon"),
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useFilter from "../../Components/FilterField/components/useFilter";
|
||||
import { Select } from "antd";
|
||||
|
||||
const Dummy = () => {
|
||||
const [t] = useTranslation();
|
||||
// const { FilterButton, FilterBody } = useFilter();
|
||||
return (
|
||||
<div className="DummyHomePage">
|
||||
|
||||
|
||||
|
||||
{/* <FilterButton/>
|
||||
<FilterBody>
|
||||
karim
|
||||
</FilterBody>
|
||||
<Select
|
||||
style={{width:"200px"}}
|
||||
showSearch
|
||||
/>
|
||||
*/}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -110,8 +110,3 @@ svg{
|
|||
scale: 1.1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.LaTeXRenderer{
|
||||
direction: ltr;
|
||||
}
|
||||
|
|
@ -17,6 +17,3 @@
|
|||
@import "../DataTable/index.scss";
|
||||
|
||||
@import "../Pages/index.scss";
|
||||
|
||||
|
||||
@import '../components/index.scss';
|
||||
|
|
@ -8,9 +8,6 @@
|
|||
margin-bottom: 30px;
|
||||
// background: #000 !important;
|
||||
}
|
||||
.exercise_form{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.exercise_form,
|
||||
.ChoiceFields {
|
||||
.upload_image_button {
|
||||
|
|
@ -45,7 +42,7 @@
|
|||
.exercise_add_main {
|
||||
background: var(--bg);
|
||||
padding: 10px 2vw;
|
||||
// max-height: 84vh;
|
||||
max-height: 84vh;
|
||||
overflow-y: scroll;
|
||||
@include Scrollbar();
|
||||
}
|
||||
|
|
@ -179,7 +176,7 @@
|
|||
.answer_status {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
justify-content: space-between;
|
||||
padding-block: 30px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
|
@ -354,8 +351,3 @@
|
|||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ListQuestions{
|
||||
@include Scrollbar()
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
.DummyHomePage{
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.LaTeXInputArea{
|
||||
|
||||
width: 50vw;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
|
||||
|
||||
}
|
||||
.showPreviewInput{
|
||||
background-color: var(--bg);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: calc(100% - 44px);
|
||||
word-wrap: break-word;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: baseline;
|
||||
align-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #d9d9d9;
|
||||
padding: 5px 10px;
|
||||
row-gap: 0px;
|
||||
|
||||
|
||||
}
|
||||
.addMML{
|
||||
all: unset;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
background: var(--primary);
|
||||
color: var(--white);
|
||||
padding: 2px 14px;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.latexModal{
|
||||
padding: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.buttons{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 20px;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
.LatexPreview{
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.LaTeXInputOptions{
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
}
|
||||
.text{
|
||||
margin-bottom: 7px !important;
|
||||
font-weight: bold;
|
||||
font-size: 19px;
|
||||
> span {
|
||||
color: transparent;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
@import './LaTeXInput.scss' ;
|
||||
|
|
@ -3,6 +3,4 @@ export enum LocalStorageEnum {
|
|||
LANGUAGE_KEY = LocalStorageEnum.PROJECT_NAME + "_LANGUAGE",
|
||||
TOKEN_KEY = LocalStorageEnum.PROJECT_NAME + "_TOKEN_KEY",
|
||||
USER_KEY = LocalStorageEnum.PROJECT_NAME + "_USER_KEY",
|
||||
HINT_INPUT = LocalStorageEnum.PROJECT_NAME + "HINT_INPUT",
|
||||
LATEX_OPTION_INPUT = LocalStorageEnum.PROJECT_NAME + "LATEX_OPTION_INPUT",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,8 +51,7 @@
|
|||
"it_should_have_more_than_one_correct_answers": "يجب أن يحتوي على إجابة صحيحة",
|
||||
"File_size_exceeds_2_MB_limit.":"حجم الملف يتجاوز الحد الأقصى البالغ 2 ميجابايت",
|
||||
"one_of_image_and_content_should_be_enter_in_answer":"يجب إدخال صورة أو محتوى واحد على الأقل في الاجابة",
|
||||
"one_of_image_and_content_should_be_enter_in_question":"يجب إدخال صورة أو محتوى واحد على الأقل في السؤال",
|
||||
"that_is_not_a_valid_mml":"هذا ليس mml صالح"
|
||||
"one_of_image_and_content_should_be_enter_in_question":"يجب إدخال صورة أو محتوى واحد على الأقل في السؤال"
|
||||
},
|
||||
"header": {
|
||||
"register_students": "تسجيل الطلاب",
|
||||
|
|
@ -143,11 +142,7 @@
|
|||
"managers":"مدراء",
|
||||
"sales":"المبيعات",
|
||||
"hide_hint":"اخفاء الشرح",
|
||||
"show_hint":"عرض الشرح",
|
||||
"past_your_MMl_text":"ضع نص MMl الخاص بك",
|
||||
"add_MML":"إضافة MML",
|
||||
"show_preview":"عرض المعاينة",
|
||||
"show_MMl":" MML عرض"
|
||||
"show_hint":"عرض الشرح"
|
||||
},
|
||||
"columns": {
|
||||
"id": "الرقم التعريفي",
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
// utilityFunctions.ts
|
||||
import { FieldProps } from 'formik';
|
||||
|
||||
export const areFieldPropsEqual = (
|
||||
prevProps: any,
|
||||
nextProps: any
|
||||
): boolean => {
|
||||
const prevError = prevProps.form.errors[prevProps.field.name];
|
||||
const nextError = nextProps.form.errors[nextProps.field.name];
|
||||
|
||||
const prevTouched = prevProps.form.touched[prevProps.field.name];
|
||||
const nextTouched = nextProps.form.touched[nextProps.field.name];
|
||||
|
||||
const prevValue = prevProps.field.value;
|
||||
const nextValue = nextProps.field.value;
|
||||
|
||||
return (
|
||||
prevValue === nextValue
|
||||
&&
|
||||
prevError === nextError &&
|
||||
prevTouched === nextTouched
|
||||
);
|
||||
};
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
import { MathMLToLaTeX } from 'mathml-to-latex';
|
||||
|
||||
export function convertMathMLToLaTeX(mathml: string): string {
|
||||
return MathMLToLaTeX.convert(mathml);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
interface TextLatexPart {
|
||||
text: string;
|
||||
isLatex: boolean;
|
||||
key:number
|
||||
}
|
||||
|
||||
export const parseTextAndLatex = (input: string): TextLatexPart[] => {
|
||||
const result: TextLatexPart[] = [];
|
||||
|
||||
const parts = input?.split(/(\$\$[^$]+\$\$)/g);
|
||||
|
||||
parts.forEach((part,index) => {
|
||||
if (part.startsWith('$$') && part.endsWith('$$')) {
|
||||
|
||||
result.push({ text: part.slice(2, -2), isLatex: true , key:index });
|
||||
} else if (part.trim()) {
|
||||
|
||||
result.push({ text: part, isLatex: false,key:index });
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { create } from "zustand";
|
||||
import { LocalStorageEnum } from "../enums/LocalStorageEnum";
|
||||
|
||||
interface ModelState {
|
||||
objectToEdit: any;
|
||||
|
|
@ -28,9 +27,6 @@ interface ModelState {
|
|||
|
||||
ShowHint: any;
|
||||
setShowHint: (data: any) => void;
|
||||
|
||||
ShowLatexOption: any;
|
||||
setShowLatexOption: (data: any) => void;
|
||||
}
|
||||
|
||||
export const useObjectToEdit = create<ModelState>((set) => ({
|
||||
|
|
@ -56,8 +52,6 @@ export const useObjectToEdit = create<ModelState>((set) => ({
|
|||
setDeletedQuestions: (data) => set(() => ({ DeletedQuestions: data })),
|
||||
SavedQuestionData: [],
|
||||
setSavedQuestionData: (data) => set(() => ({ SavedQuestionData: data })),
|
||||
ShowHint: localStorage?.getItem(LocalStorageEnum.HINT_INPUT) === "true",
|
||||
ShowHint: false,
|
||||
setShowHint: (data) => set(() => ({ ShowHint: data })),
|
||||
ShowLatexOption: localStorage?.getItem(LocalStorageEnum.LATEX_OPTION_INPUT) === "true" ,
|
||||
setShowLatexOption: (data) => set(() => ({ ShowLatexOption: data })),
|
||||
}));
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user