diff --git a/index.html b/index.html index 8e7e0b63..5b005c51 100644 --- a/index.html +++ b/index.html @@ -15,6 +15,17 @@ gtag('config', 'UA-167873271-3'); + + =6.9.0" @@ -329,12 +333,14 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz", - "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -372,10 +378,11 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz", - "integrity": "sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -451,19 +458,21 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz", - "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz", - "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -505,12 +514,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz", - "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -524,6 +534,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -536,6 +547,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -550,6 +562,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -558,13 +571,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -574,6 +589,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -583,6 +599,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -591,10 +608,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz", - "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -823,12 +844,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.6.tgz", - "integrity": "sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2113,10 +2135,11 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.6.tgz", - "integrity": "sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2125,33 +2148,32 @@ } }, "node_modules/@babel/template": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz", - "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.6", - "@babel/parser": "^7.24.6", - "@babel/types": "^7.24.6" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz", - "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.6", - "@babel/generator": "^7.24.6", - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-function-name": "^7.24.6", - "@babel/helper-hoist-variables": "^7.24.6", - "@babel/helper-split-export-declaration": "^7.24.6", - "@babel/parser": "^7.24.6", - "@babel/types": "^7.24.6", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2160,13 +2182,14 @@ } }, "node_modules/@babel/types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", - "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.6", - "@babel/helper-validator-identifier": "^7.24.6", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -10314,13 +10337,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -10676,9 +10700,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -10694,11 +10718,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -10934,9 +10959,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001621", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001621.tgz", - "integrity": "sha512-+NLXZiviFFKX0fk8Piwv3PfLPGtRqJeq2TiNoUff/qB5KJgwecJTvCXDpmlyP/eCI/GUEmp/h/y5j0yckiiZrA==", + "version": "1.0.30001663", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", + "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", "dev": true, "funding": [ { @@ -10951,7 +10976,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chai": { "version": "4.4.1", @@ -11501,12 +11527,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.23.0" + "browserslist": "^4.23.3" }, "funding": { "type": "opencollective", @@ -11770,6 +11797,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -12399,10 +12436,11 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.783", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.783.tgz", - "integrity": "sha512-bT0jEz/Xz1fahQpbZ1D7LgmPYZ3iHVY39NcWWro1+hA2IvjiPeaXtfSqrQ+nXjApMvQRE2ASt1itSLRrebHMRQ==", - "dev": true + "version": "1.5.27", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", + "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.10.2", @@ -20267,10 +20305,11 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "2.5.0", @@ -25056,9 +25095,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -25074,6 +25113,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.1.2", "picocolors": "^1.0.1" diff --git a/package.json b/package.json index 7fa0ae2a..956b3ccc 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@tanstack/react-query": "^5.28.4", "@tanstack/react-query-devtools": "^5.37.1", "axios": "^1.4.0", + "date-fns": "^4.1.0", "dotenv": "^16.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/App.tsx b/src/App.tsx index 93dc26c4..c2db95ef 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,11 +13,9 @@ import MyMentees from './pages/MyMentees/MyMentees.component.tsx'; import EditProfileForm from './pages/EditProfileForm/EditProfileForm.component.tsx'; import MenteeDashboard from './pages/MenteeDashboard'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; -import MenteeApplications from './pages/MenteeApplicationsView/MenteeApplications.component.tsx'; import { LoginModalProvider } from './contexts/LoginModalContext.tsx'; import PasswordReset from './pages/PasswordReset/index.tsx'; import MenteeProfile from './pages/MenteeProfile/MenteeProfile.component.tsx'; -import MenteeCheckIn from './pages/MenteeCheckIn/MenteeCheckIn.component.tsx'; const queryClient = new QueryClient(); @@ -39,16 +37,11 @@ const App: React.FC = () => { element={} /> } /> - } - /> + } /> } /> - } /> } /> } /> } /> - } /> } /> } /> diff --git a/src/assets/svg/Icons/ArrowIcon.tsx b/src/assets/svg/Icons/ArrowIcon.tsx new file mode 100644 index 00000000..d946d350 --- /dev/null +++ b/src/assets/svg/Icons/ArrowIcon.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +interface ArrowIconProps { + isExpanded: boolean; +} + +const ArrowIcon: React.FC = ({ isExpanded }) => { + return ( + + + + ); +}; + +export default ArrowIcon; diff --git a/src/assets/svg/Icons/HistoryClockIcon.tsx b/src/assets/svg/Icons/HistoryClockIcon.tsx new file mode 100644 index 00000000..2c7aa401 --- /dev/null +++ b/src/assets/svg/Icons/HistoryClockIcon.tsx @@ -0,0 +1,27 @@ +import React from 'react'; + +interface HistoryClockIconProps { + className?: string; +} + +const HistoryClockIcon: React.FC = ({ + className = 'w-6 h-6', +}) => ( + + + + + + +); + +export default HistoryClockIcon; diff --git a/src/assets/svg/Icons/NewSubmissionsIcon.tsx b/src/assets/svg/Icons/NewSubmissionsIcon.tsx new file mode 100644 index 00000000..513ad0b7 --- /dev/null +++ b/src/assets/svg/Icons/NewSubmissionsIcon.tsx @@ -0,0 +1,27 @@ +import React from 'react'; + +interface NewSubmissionsIconProps { + className?: string; +} + +const NewSubmissionsIcon: React.FC = ({ + className = 'w-6 h-6', +}) => ( + + + + + + +); + +export default NewSubmissionsIcon; diff --git a/src/assets/svg/Icons/NoCheckInsIcon.tsx b/src/assets/svg/Icons/NoCheckInsIcon.tsx new file mode 100644 index 00000000..18597e4b --- /dev/null +++ b/src/assets/svg/Icons/NoCheckInsIcon.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +const NoCheckInsIcon: React.FC = () => ( + + + +); + +export default NoCheckInsIcon; diff --git a/src/assets/svg/Icons/NotificationBell.tsx b/src/assets/svg/Icons/NotificationBell.tsx new file mode 100644 index 00000000..22e962e7 --- /dev/null +++ b/src/assets/svg/Icons/NotificationBell.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { NotificationProps } from '../../../types'; + +const NotificationBell: React.FC = ({ + iconColor = 'currentColor', + badgeColor = '#EF4444', + textColor = 'white', + count = 0, +}) => { + const displayCount = count > 99 ? '99+' : count.toString(); + + return ( + + + {count > 0 && ( + <> + + + {displayCount} + + + )} + + ); +}; + +export default NotificationBell; diff --git a/src/assets/svg/Icons/OpenIcon.tsx b/src/assets/svg/Icons/OpenIcon.tsx new file mode 100644 index 00000000..fefec2a5 --- /dev/null +++ b/src/assets/svg/Icons/OpenIcon.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +const OpenIcon: React.FC = () => { + return ( +
+ + + +
+ ); +}; + +export default OpenIcon; diff --git a/src/components/Layout/Navbar/index.tsx b/src/components/Layout/Navbar/index.tsx index be88769b..07ad6a5b 100644 --- a/src/components/Layout/Navbar/index.tsx +++ b/src/components/Layout/Navbar/index.tsx @@ -1,6 +1,5 @@ import { RefObject, useContext, useEffect, useRef, useState } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; - import { useLoginModalContext } from '../../../contexts/LoginModalContext'; import { UserContext, UserContextType } from '../../../contexts/UserContext'; import StickyBanner from '../../Banner/StickyBanner'; @@ -84,13 +83,14 @@ const Navbar: React.FC = () => { src="/scholarx-logo.png" className="md:h-12 h-10" alt="ScholarX Logo" + referrerPolicy="no-referrer" /> -
+
  • Find a mentor @@ -99,7 +99,7 @@ const Navbar: React.FC = () => {
  • About @@ -107,7 +107,7 @@ const Navbar: React.FC = () => {
  • Initiatives @@ -115,17 +115,17 @@ const Navbar: React.FC = () => {
  • Join Us
  • {!isUserMentor && ( -
  • +
  • @@ -137,7 +137,7 @@ const Navbar: React.FC = () => { diff --git a/src/components/MenteeApplication/MenteeApplication.component.tsx b/src/components/MenteeApplication/MenteeApplication.component.tsx index c543c0d7..926caac7 100644 --- a/src/components/MenteeApplication/MenteeApplication.component.tsx +++ b/src/components/MenteeApplication/MenteeApplication.component.tsx @@ -143,6 +143,7 @@ const MenteeApplication: React.FC = () => { src={mentee?.mentor.profile.image_url} className="w-14 h-14 rounded-full object-cover" alt="" + referrerPolicy="no-referrer" />

    diff --git a/src/components/MentorCard/MentorCard.component.tsx b/src/components/MentorCard/MentorCard.component.tsx index 3b651555..f836e544 100644 --- a/src/components/MentorCard/MentorCard.component.tsx +++ b/src/components/MentorCard/MentorCard.component.tsx @@ -5,9 +5,47 @@ import ProfilePic from '../ProfilePic/index.tsx'; interface MentorCardProps { mentor: Mentor; + variant?: 'default' | 'profile'; } -const MentorCard: React.FC = ({ mentor }) => { +const MentorCard: React.FC = ({ + mentor, + variant = 'default', +}) => { + if (variant === 'profile') { + return ( + +
    + + {!mentor.availability && ( +
    + ⏳ +
    + )} +
    +
    +
    + {mentor.application.firstName} {mentor.application.lastName} +
    +

    + {mentor.application.position} +

    +

    + {mentor.application.institution} +

    +
    + + ); + } + return ( ; + +const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', +]; + +const MonthlyCheckInModal: React.FC<{ + onClose: () => void; + isOpen: boolean; + menteeId: string; +}> = ({ onClose, isOpen, menteeId }) => { + const { + register, + setValue, + handleSubmit, + reset, + formState: { errors }, + } = useForm({ + resolver: zodResolver(MenteeCheckInSchema), + defaultValues: { + title: '', + progressTowardsGoals: '', + generalUpdatesAndFeedback: '', + mediaContentLinks: [], + }, + }); + + const [mediaLinks, setMediaLinks] = useState([]); + + const handleAddLink = () => { + setMediaLinks([...mediaLinks, '']); + setValue('mediaContentLinks', [...mediaLinks, '']); + }; + + const handleRemoveLink = (index: number) => { + const newLinks = mediaLinks.filter((_, i) => i !== index); + setMediaLinks(newLinks); + setValue('mediaContentLinks', newLinks); + }; + + const handleLinkChange = (index: number, value: string) => { + const newLinks = mediaLinks.map((link, i) => (i === index ? value : link)); + setMediaLinks(newLinks); + setValue('mediaContentLinks', newLinks); + }; + + const { submitCheckIn } = useSubmitCheckIn(); + const [loading, setLoading] = useState(false); + + const onSubmit = async (data: MenteeCheckInForm) => { + const checkInData = { + ...data, + mediaLinks: mediaLinks.filter((link) => link.trim() !== ''), + menteeId, + }; + setLoading(true); + try { + await submitCheckIn(checkInData); + reset(); + onClose(); + } catch (error) { + console.error('Error submitting check-in:', error); + } finally { + setLoading(false); + } + }; + + if (!isOpen) return null; + + return ( + <> +
    +
    +
    +

    Monthly Check-In

    + +
    +
    +
    + +

    + Select the month for which you are submitting the progress. +

    + + {errors.title && ( +

    + {errors.title.message} +

    + )} +
    +
    + +

    + Provide any general updates or feedback you have. +

    + + {errors.mentorFeedback && ( +
    + {errors.mentorFeedback.message} +
    + )} + +
    + + +
    + {errors.isCheckedByMentor && ( +
    + {errors.isCheckedByMentor.message} +
    + )} + {isSuccess && ( +
    + Feedback submitted successfully 🎉 +
    + )} + {isError && ( +
    + Error submitting feedback: {error?.message} +
    + )} + + ); +}; + +export default MentorFeedbackForm; diff --git a/src/components/MonthlyChecking/MentorMonthlyChecking.tsx b/src/components/MonthlyChecking/MentorMonthlyChecking.tsx new file mode 100644 index 00000000..f1f96303 --- /dev/null +++ b/src/components/MonthlyChecking/MentorMonthlyChecking.tsx @@ -0,0 +1,245 @@ +import React, { useState } from 'react'; +import { format } from 'date-fns'; +import MentorFeedbackForm from './MentorFeedbackForm.component'; +import NoCheckInsIcon from '../../assets/svg/Icons/NoCheckInsIcon'; +import { MonthlyCheckIn } from '../../types'; +import NewSubmissionsToggle from '../Toggle/NewSubmissionToggle'; +import HistoryToggle from '../Toggle/HistoryToggle'; +import ArrowIcon from '../../assets/svg/Icons/ArrowIcon'; +import Loading from '../../assets/svg/Loading'; + +interface MentorMonthlyCheckingProps { + menteeId: string; + checkInHistory: MonthlyCheckIn[]; + isLoading: boolean; + refetch: () => Promise; + isAdmin?: boolean; +} + +interface CheckInItemProps { + checkIn: MonthlyCheckIn; + isHistory?: boolean; + onSubmitFeedback: (checkInId: string) => Promise; + isSubmitting: boolean; + menteeId: string; + isAdmin?: boolean; +} + +const CheckInItem: React.FC = ({ + checkIn, + isHistory, + onSubmitFeedback, + isSubmitting, + menteeId, + isAdmin, +}) => { + const [isExpanded, setIsExpanded] = useState(false); + + return ( +
    +
    { + setIsExpanded(!isExpanded); + }} + > +
    +

    + {checkIn.title} +

    + +
    +

    + Submitted on {format(new Date(checkIn.checkInDate), 'MMM dd, yyyy')} +

    +
    + + {isExpanded && ( +
    +
    +
    +
    + General Updates: +
    +

    + {checkIn.generalUpdatesAndFeedback ?? 'No updates provided'} +

    +
    +
    +
    + Progress Towards Goals: +
    +

    + {checkIn.progressTowardsGoals ?? 'No progress updates provided'} +

    +
    +
    +
    Submissions:
    + {checkIn.mediaContentLinks.map((link, index) => ( + + Media Link {index + 1} + + ))} +
    +
    +
    + {isHistory ? ( +
    +
    + Given Feedback: +
    +

    + {checkIn.mentorFeedback} +

    +
    + + ✓ Checked on{' '} + {format( + new Date(checkIn.mentorCheckedDate ?? ''), + 'MMM dd, yyyy' + )} + +
    +
    + ) : ( + <> + {isSubmitting ? ( +
    + +
    + ) : ( + !isAdmin && ( + { + await onSubmitFeedback(checkIn.uuid); + }} + /> + ) + )} + + )} +
    +
    + )} +
    + ); +}; + +const MentorMonthlyChecking: React.FC = ({ + menteeId, + checkInHistory, + isLoading, + refetch, + isAdmin, +}) => { + const [submittingFeedback, setSubmittingFeedback] = useState< + Record + >({}); + const [isNewSubmissionOpen, setNewSubmissionOpen] = useState(true); + const [isHistoryOpen, setIsHistoryOpen] = useState(false); + + const handleFeedbackSubmit = async (checkInId: string) => { + setSubmittingFeedback((prev) => ({ ...prev, [checkInId]: true })); + await refetch(); + setSubmittingFeedback((prev) => ({ ...prev, [checkInId]: false })); + }; + + if (isLoading) { + return ( +
    + +
    + ); + } + + if (checkInHistory.length === 0) { + return ( +
    + +

    + No Check-ins Found +

    +

    + Mentee has not submitted any monthly check-ins yet. +

    +
    + ); + } + + const uncheckedCheckIns = checkInHistory.filter( + (checkIn) => !checkIn.isCheckedByMentor + ); + const checkedCheckIns = checkInHistory.filter( + (checkIn) => checkIn.isCheckedByMentor + ); + + return ( +
    + { + setNewSubmissionOpen(!isNewSubmissionOpen); + }} + newSubmissionsCount={uncheckedCheckIns.length} + /> + {isNewSubmissionOpen && ( +
    + {uncheckedCheckIns.length > 0 ? ( + uncheckedCheckIns.map((checkIn) => ( + + )) + ) : ( +
    + +

    No new check-ins to review.

    +
    + )} +
    + )} + + { + setIsHistoryOpen(!isHistoryOpen); + }} + checkingCount={checkedCheckIns.length} + /> + {isHistoryOpen && ( +
    + {checkedCheckIns.length > 0 ? ( + checkedCheckIns.map((checkIn) => ( + + )) + ) : ( +

    No feedback history available.

    + )} +
    + )} +
    + ); +}; + +export default MentorMonthlyChecking; diff --git a/src/components/MonthlyChecking/MonthlyCheckingHeader.tsx b/src/components/MonthlyChecking/MonthlyCheckingHeader.tsx new file mode 100644 index 00000000..45cca4f4 --- /dev/null +++ b/src/components/MonthlyChecking/MonthlyCheckingHeader.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import ArrowIcon from '../../assets/svg/Icons/ArrowIcon'; + +interface MonthlyCheckingHeaderProps { + isMentorView: boolean; + handleAddCheckIn?: () => void; + toggleGuidelines: () => void; + menteeId?: string; + showGuidelines: boolean; +} + +const MonthlyCheckInHeader: React.FC = ({ + isMentorView, + toggleGuidelines, + showGuidelines, +}) => { + return ( + <> +
    + +
    + {showGuidelines && ( +
    +
    +

    + Monthly Check-in Guidelines +

    +
    +
    +

    + Guidelines: +

    +
      + {isMentorView ? ( + <> +
    • Review monthly updates submitted by your mentees.
    • +
    • Provide constructive feedback on their progress.
    • +
    • + Ensure mentees are meeting their submission + requirements. +
    • + + ) : ( + <> +
    • + Submit monthly updates on your progress via the ScholarX + platform. +
    • +
    • + Make at least 3 media submissions during the 6-month + period. +
    • +
    • + Include links to your media submissions in the monthly + check-ins. +
    • +
    • Share your progress on social media and tag us.
    • + + )} +
    +
    +
    +

    + Types of Media: +

    +
      +
    • 📝 Written: Blogs, Medium
    • +
    • 🎥 Video: YouTube, Facebook
    • +
    • 🎙️ Audio: Podcasts, Spotify
    • +
    • 💻 Code: GitHub repositories
    • +
    +
    +
    +
    +
    + )} + + ); +}; + +export default MonthlyCheckInHeader; diff --git a/src/components/NotificationBadge/index.tsx b/src/components/NotificationBadge/index.tsx new file mode 100644 index 00000000..85695992 --- /dev/null +++ b/src/components/NotificationBadge/index.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import NotificationBell from '../../assets/svg/Icons/NotificationBell'; +import { NotificationProps } from '../../types'; + +const NotificationBadge: React.FC = ({ + count, + className = '', + iconColor = 'currentColor', + badgeColor = '#EF4444', + textColor = 'white', +}) => { + return ( +
    + +
    + ); +}; + +export default NotificationBadge; diff --git a/src/components/TermsAgreementModal/index.tsx b/src/components/TermsAgreementModal/index.tsx new file mode 100644 index 00000000..52a56202 --- /dev/null +++ b/src/components/TermsAgreementModal/index.tsx @@ -0,0 +1,165 @@ +import React from 'react'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import Tooltip from '../Tooltip'; +import OpenIcon from '../../assets/svg/Icons/OpenIcon'; +import { + menteeTermsAgreementModalSchema, + mentorTermsAgreementModalSchema, +} from '../../schemas'; + +type MentorFormData = z.infer; +type MenteeFormData = z.infer; + +interface TermsAgreementModalProps { + isOpen: boolean; + onClose: () => void; + onAgree: (data: MentorFormData | MenteeFormData) => void; + isMentor: boolean; + guideUrl: string; +} + +const TermsAgreementModal: React.FC = ({ + isOpen, + onClose, + onAgree, + isMentor, + guideUrl, +}) => { + const schema = isMentor + ? mentorTermsAgreementModalSchema + : menteeTermsAgreementModalSchema; + const { + register, + handleSubmit, + formState: { errors, isValid }, + } = useForm({ + resolver: zodResolver(schema), + mode: 'onChange', + defaultValues: isMentor + ? { agreed: false, canCommit: false } + : { agreed: false, consentGiven: false }, + }); + + const onSubmit = (data: MentorFormData | MenteeFormData) => { + if (isValid) { + onAgree(data); + } else { + console.error('Form is invalid. Errors:', errors); + } + }; + + if (!isOpen) return null; + + const guideType = isMentor ? 'Mentor' : 'Mentee'; + const title = isMentor + ? 'One Last Step to Join as a ScholarX Mentor' + : 'ScholarX Mentee Terms and Privacy'; + + return ( +
    +
    +
    +
    +

    + {title} +

    + +
    +

    + ScholarX {guideType} Guide +

    +
    + + + + + +
    +
    + +
    + +
    + + {!isMentor && ( + <> +

    + Privacy Statement +

    +

    + Sustainable Foundation Education assures that your video + submission will be used exclusively for application evaluation + purposes. We are committed to protecting your privacy and will + not use your video for any other activities, such as general + AI training or public distribution. Your personal information + and video content will be handled with the utmost + confidentiality. +

    + + )} + +
    + + {errors.agreed && ( +

    + {errors.agreed.message} +

    + )} + + + {(errors.canCommit ?? errors.consentGiven) && ( +

    + {errors.canCommit?.message ?? errors.consentGiven?.message} +

    + )} +
    +
    + +
    + + +
    +
    +
    +
    + ); +}; + +export default TermsAgreementModal; diff --git a/src/components/Toggle/ButtonToggle.tsx b/src/components/Toggle/ButtonToggle.tsx new file mode 100644 index 00000000..0843654e --- /dev/null +++ b/src/components/Toggle/ButtonToggle.tsx @@ -0,0 +1,41 @@ +import React, { ReactElement } from 'react'; +import NotificationBadge from '../NotificationBadge'; +import ArrowIcon from '../../assets/svg/Icons/ArrowIcon'; + +interface ToggleButtonProps { + isOpen: boolean; + toggle: () => void; + icon?: ReactElement; + text: string; + badgeCount?: number; + useNotificationBadge?: boolean; +} + +const ToggleButton: React.FC = ({ + isOpen, + toggle, + text, + badgeCount, + useNotificationBadge = false, +}) => ( + +); + +export default ToggleButton; diff --git a/src/components/Toggle/HistoryToggle.tsx b/src/components/Toggle/HistoryToggle.tsx new file mode 100644 index 00000000..402bce9d --- /dev/null +++ b/src/components/Toggle/HistoryToggle.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import ToggleButton from './ButtonToggle'; + +interface HistoryToggleProps { + isHistoryOpen: boolean; + toggleHistory: () => void; + checkingCount: number; +} + +const HistoryToggle: React.FC = ({ + isHistoryOpen, + toggleHistory, + checkingCount, +}) => ( + +); + +export default HistoryToggle; diff --git a/src/components/Toggle/NewSubmissionToggle.tsx b/src/components/Toggle/NewSubmissionToggle.tsx new file mode 100644 index 00000000..dae242ee --- /dev/null +++ b/src/components/Toggle/NewSubmissionToggle.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import NewSubmissionsIcon from '../../assets/svg/Icons/NewSubmissionsIcon'; +import ToggleButton from './ButtonToggle'; + +interface NewSubmissionsToggleProps { + isNewSubmissionOpen: boolean; + toggleNewSubmission: () => void; + newSubmissionsCount: number; +} + +const NewSubmissionsToggle: React.FC = ({ + isNewSubmissionOpen, + toggleNewSubmission, + newSubmissionsCount, +}) => ( + } + text="New Submissions" + badgeCount={newSubmissionsCount} + useNotificationBadge={true} + /> +); + +export default NewSubmissionsToggle; diff --git a/src/enums.ts b/src/enums.ts index af349f63..d4df8bf5 100644 --- a/src/enums.ts +++ b/src/enums.ts @@ -8,6 +8,7 @@ export enum ApplicationStatus { REJECTED = 'rejected', APPROVED = 'approved', COMPLETED = 'completed', + REVOKED = 'revoked', } export enum StatusUpdatedBy { diff --git a/src/hooks/useSubmitCheckIn.ts b/src/hooks/useSubmitCheckIn.ts new file mode 100644 index 00000000..37d0de39 --- /dev/null +++ b/src/hooks/useSubmitCheckIn.ts @@ -0,0 +1,100 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import axios, { AxiosError } from 'axios'; +import { API_URL } from '../constants'; + +import { + MenteeCheckInForm, + MentorFeedbackForm, + MonthlyCheckIn, +} from '../types'; + +const useSubmitCheckIn = () => { + const queryClient = useQueryClient(); + + const { + mutateAsync: submitCheckIn, + isSuccess, + isError, + error, + } = useMutation({ + mutationFn: async (data: MenteeCheckInForm) => { + await axios.post(`${API_URL}/mentees/checkin`, data, { + withCredentials: true, + }); + }, + onSuccess: () => { + void queryClient.invalidateQueries({ queryKey: ['menteeCheckIns'] }); + }, + }); + + return { + submitCheckIn, + isSuccess, + isError, + error, + }; +}; + +const useMonthlyCheckIns = (menteeId: string) => { + const queryClient = useQueryClient(); + + const { isLoading, error, data, refetch } = useQuery< + MonthlyCheckIn[], + AxiosError, + MonthlyCheckIn[] + >({ + queryKey: ['menteeCheckIns', menteeId], + queryFn: async () => { + if (menteeId != null) { + try { + const { data } = await axios.get( + `${API_URL}/mentees/checkin/${menteeId}`, + { + withCredentials: true, + } + ); + return data.checkIns as MonthlyCheckIn[]; + } catch (error) { + if (axios.isAxiosError(error) && error.response?.status === 401) { + void queryClient.invalidateQueries({ queryKey: ['currentUser'] }); + } + throw error; + } + } + return []; + }, + enabled: menteeId != null, + initialData: undefined, + }); + + return { isLoading, error, data, refetch }; +}; + +const useMentorFeedback = () => { + const queryClient = useQueryClient(); + + const { + mutateAsync: submitMentorFeedback, + isSuccess, + isError, + error, + } = useMutation({ + mutationFn: async (data: MentorFeedbackForm) => { + await axios.put(`${API_URL}/mentees/checking/feedback`, data, { + withCredentials: true, + }); + }, + onSuccess: () => { + void queryClient.invalidateQueries({ queryKey: ['mentorCheckIns'] }); + }, + }); + + return { + submitMentorFeedback, + isSuccess, + isError, + error, + }; +}; + +export { useSubmitCheckIn, useMonthlyCheckIns, useMentorFeedback }; diff --git a/src/pages/Dashboard/Dashboard.tsx b/src/pages/Dashboard/Dashboard.tsx index 582a4ddb..da3bd592 100644 --- a/src/pages/Dashboard/Dashboard.tsx +++ b/src/pages/Dashboard/Dashboard.tsx @@ -70,7 +70,7 @@ const Dashboard: React.FC = () => { element={} /> } /> } /> diff --git a/src/pages/Dashboard/scenes/OngoingMentorshipPrograms/OngoingMentorshipPrograms.tsx b/src/pages/Dashboard/scenes/OngoingMentorshipPrograms/OngoingMentorshipPrograms.tsx index 7cbf5fac..7e0952f6 100644 --- a/src/pages/Dashboard/scenes/OngoingMentorshipPrograms/OngoingMentorshipPrograms.tsx +++ b/src/pages/Dashboard/scenes/OngoingMentorshipPrograms/OngoingMentorshipPrograms.tsx @@ -1,9 +1,98 @@ import React from 'react'; +import { useMentees } from '../../../../hooks/useMentees'; +import { Routes, Route, useParams } from 'react-router'; +import { Link } from 'react-router-dom'; +import UserIcon from '../../../../assets/svg/Icons/UserIcon'; +import MentorMonthlyChecking from '../../../../components/MonthlyChecking/MentorMonthlyChecking'; +import { ApplicationStatus } from '../../../../enums'; +import { useMonthlyCheckIns } from '../../../../hooks/useSubmitCheckIn'; +import { Mentee } from '../../../../types'; +import MenteeProfile from '../../../MenteeProfile/MenteeProfile.component'; const OngoingMentorshipPrograms: React.FC = () => { + const { data: mentees } = useMentees(); + + const approvedMentees = + mentees?.filter((mentee) => mentee.state === ApplicationStatus.APPROVED) || + []; + + const renderMenteeLink = (mentee: Mentee) => ( + +
    +
    + {mentee.profile.image_url ? ( + {`${mentee.application.firstName} + ) : ( +
    + +
    + )} +
    +
    +
    +

    + {mentee.application.firstName} {mentee.application.lastName} +

    +
    +
    +
    + + ); + + return ( +
    +
    +

    Approved Mentees

    +
    + {approvedMentees.map(renderMenteeLink)} + {approvedMentees.length === 0 && ( +

    No approved mentees available.

    + )} +
    +
    +
    + + } /> + +
    +
    + ); +}; + +const AdminMenteeDetails: React.FC = () => { + const { menteeId } = useParams<{ menteeId: string }>(); + + const { + data: checkInHistory = [], + isLoading, + refetch, + } = useMonthlyCheckIns(menteeId ?? ''); + return (
    -

    Ongoing Mentorship Programs

    + +
    +

    + Monthly Check-Ins +

    +
    + +
    ); }; diff --git a/src/pages/EditProfileForm/EditProfileForm.component.tsx b/src/pages/EditProfileForm/EditProfileForm.component.tsx index 75dae3e0..6cb85e60 100644 --- a/src/pages/EditProfileForm/EditProfileForm.component.tsx +++ b/src/pages/EditProfileForm/EditProfileForm.component.tsx @@ -141,6 +141,7 @@ const EditProfileForm: React.FC = () => { src={profile.profilePic} alt="Profile" className="w-[90px] h-[90px] rounded-full object-cover" + referrerPolicy="no-referrer" /> ) : (
    diff --git a/src/pages/MenteeApplicationsView/MenteeApplications.component.tsx b/src/pages/MenteeApplicationsView/MenteeApplications.component.tsx index c88cccbb..0ef7b44c 100644 --- a/src/pages/MenteeApplicationsView/MenteeApplications.component.tsx +++ b/src/pages/MenteeApplicationsView/MenteeApplications.component.tsx @@ -9,6 +9,7 @@ const MenteeApplications: React.FC = () => { const { mentor } = useContext(UserContext) as UserContextType; const { data: mentees } = useMyMentees(); const [isAvailable, setIsAvailable] = useState(mentor?.availability); + const { updateAvailability } = useMentor(mentor?.uuid); const handleAvailability = async (availability: boolean) => { diff --git a/src/pages/MenteeCheckIn/MenteeCheckIn.component.tsx b/src/pages/MenteeCheckIn/MenteeCheckIn.component.tsx deleted file mode 100644 index 6652fa62..00000000 --- a/src/pages/MenteeCheckIn/MenteeCheckIn.component.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import React from 'react'; -import { useForm } from 'react-hook-form'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { z } from 'zod'; -import { MenteeCheckInSchema } from '../../schemas'; - -type MenteeCheckInForm = z.infer; - -const MenteeCheckIn: React.FC = () => { - const { - register, - handleSubmit, - setValue, - formState: { errors }, - } = useForm({ - resolver: zodResolver(MenteeCheckInSchema), - }); - - const onSubmit = async (data: MenteeCheckInForm) => { - console.log(data); - //! TODO : Handle form submission - }; - - return ( -
    -

    - Monthly Progress -

    -
    -
    - -