codeforlife 2.8.3 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/dist/Countdown-DFI1RljW.js +28 -0
  2. package/dist/Countdown-DFI1RljW.js.map +1 -0
  3. package/dist/Countdown-zY3nMzmi.cjs +2 -0
  4. package/dist/Countdown-zY3nMzmi.cjs.map +1 -0
  5. package/dist/Image-D5jC9UoX.js +21 -0
  6. package/dist/Image-D5jC9UoX.js.map +1 -0
  7. package/dist/Image-mgT45r_B.cjs +2 -0
  8. package/dist/Image-mgT45r_B.cjs.map +1 -0
  9. package/dist/LinkButton-BYFkvL_O.cjs +2 -0
  10. package/dist/LinkButton-BYFkvL_O.cjs.map +1 -0
  11. package/dist/LinkButton-oK0RThqn.js +12 -0
  12. package/dist/LinkButton-oK0RThqn.js.map +1 -0
  13. package/dist/Navigate-Dq47aqC8.js +25 -0
  14. package/dist/Navigate-Dq47aqC8.js.map +1 -0
  15. package/dist/Navigate-dQocLhzN.cjs +2 -0
  16. package/dist/Navigate-dQocLhzN.cjs.map +1 -0
  17. package/dist/api/endpoints/index.cjs.js +2 -0
  18. package/dist/api/endpoints/index.cjs.js.map +1 -0
  19. package/dist/api/endpoints/index.d.ts +81 -0
  20. package/dist/api/endpoints/index.es.js +78 -0
  21. package/dist/api/endpoints/index.es.js.map +1 -0
  22. package/dist/api/index.cjs.js +4 -0
  23. package/dist/api/index.cjs.js.map +1 -0
  24. package/dist/api/index.d.ts +77 -0
  25. package/dist/api/index.es.js +541 -0
  26. package/dist/api/index.es.js.map +1 -0
  27. package/dist/api-Cbyt3rw0.js +92 -0
  28. package/dist/api-Cbyt3rw0.js.map +1 -0
  29. package/dist/api-CnMfjRk3.cjs +2 -0
  30. package/dist/api-CnMfjRk3.cjs.map +1 -0
  31. package/dist/api-Cs4Y-WeI.js +20 -0
  32. package/dist/api-Cs4Y-WeI.js.map +1 -0
  33. package/dist/api-DIgp_6Vr.cjs +2 -0
  34. package/dist/api-DIgp_6Vr.cjs.map +1 -0
  35. package/dist/api.d.ts +123 -0
  36. package/dist/auth-BPfUPjmM.js +237 -0
  37. package/dist/auth-BPfUPjmM.js.map +1 -0
  38. package/dist/auth-Vf1MgMci.cjs +2 -0
  39. package/dist/auth-Vf1MgMci.cjs.map +1 -0
  40. package/dist/auth.d.ts +40 -0
  41. package/dist/components/form/index.cjs.js +2 -0
  42. package/dist/components/form/index.cjs.js.map +1 -0
  43. package/dist/components/form/index.d.ts +86 -0
  44. package/dist/components/form/index.es.js +18 -0
  45. package/dist/components/form/index.es.js.map +1 -0
  46. package/dist/components/index.cjs.js +11 -0
  47. package/dist/components/index.cjs.js.map +1 -0
  48. package/dist/components/index.d.ts +90 -0
  49. package/dist/components/index.es.js +383 -0
  50. package/dist/components/index.es.js.map +1 -0
  51. package/dist/components/page/index.cjs.js +2 -0
  52. package/dist/components/page/index.cjs.js.map +1 -0
  53. package/dist/components/page/index.d.ts +77 -0
  54. package/dist/components/page/index.es.js +9 -0
  55. package/dist/components/page/index.es.js.map +1 -0
  56. package/dist/components/router/index.cjs.js +2 -0
  57. package/dist/components/router/index.cjs.js.map +1 -0
  58. package/dist/components/router/index.d.ts +78 -0
  59. package/dist/components/router/index.es.js +11 -0
  60. package/dist/components/router/index.es.js.map +1 -0
  61. package/dist/components/table/index.cjs.js +2 -0
  62. package/dist/components/table/index.cjs.js.map +1 -0
  63. package/dist/components/table/index.d.ts +75 -0
  64. package/dist/components/table/index.es.js +9 -0
  65. package/dist/components/table/index.es.js.map +1 -0
  66. package/dist/en-gb-B_rK7Jx1.js +20 -0
  67. package/dist/en-gb-B_rK7Jx1.js.map +1 -0
  68. package/dist/en-gb-CpyEkKq3.cjs +2 -0
  69. package/dist/en-gb-CpyEkKq3.cjs.map +1 -0
  70. package/dist/features/index.cjs.js +2 -0
  71. package/dist/features/index.cjs.js.map +1 -0
  72. package/dist/features/index.d.ts +76 -0
  73. package/dist/features/index.es.js +47 -0
  74. package/dist/features/index.es.js.map +1 -0
  75. package/dist/form.d.ts +40 -0
  76. package/dist/general-BPbbmkeX.cjs +2 -0
  77. package/dist/general-BPbbmkeX.cjs.map +1 -0
  78. package/dist/general-CtTJPCJn.js +58 -0
  79. package/dist/general-CtTJPCJn.js.map +1 -0
  80. package/dist/general.d.ts +53 -0
  81. package/dist/hooks/index.cjs.js +2 -0
  82. package/dist/hooks/index.cjs.js.map +1 -0
  83. package/dist/hooks/index.d.ts +77 -0
  84. package/dist/hooks/index.es.js +25 -0
  85. package/dist/hooks/index.es.js.map +1 -0
  86. package/dist/index-2W--_sNE.js +30 -0
  87. package/dist/index-2W--_sNE.js.map +1 -0
  88. package/dist/index-BUMdUVBH.cjs +5 -0
  89. package/dist/index-BUMdUVBH.cjs.map +1 -0
  90. package/dist/index-B_Zy_zwA.cjs +2 -0
  91. package/dist/index-B_Zy_zwA.cjs.map +1 -0
  92. package/dist/index-BgsynEGX.cjs +2 -0
  93. package/dist/index-BgsynEGX.cjs.map +1 -0
  94. package/dist/index-CA-ugBSa.cjs +2 -0
  95. package/dist/index-CA-ugBSa.cjs.map +1 -0
  96. package/dist/index-CNtOlJ49.js +572 -0
  97. package/dist/index-CNtOlJ49.js.map +1 -0
  98. package/dist/index-DkM_cG3a.js +237 -0
  99. package/dist/index-DkM_cG3a.js.map +1 -0
  100. package/dist/index-Dqp7dpn3.js +1111 -0
  101. package/dist/index-Dqp7dpn3.js.map +1 -0
  102. package/dist/index.cjs.js +2 -0
  103. package/dist/index.cjs.js.map +1 -0
  104. package/dist/index.d.ts +78 -0
  105. package/dist/index.es.js +7 -0
  106. package/dist/index.es.js.map +1 -0
  107. package/dist/jsx-runtime-CeSfJrVB.cjs +31 -0
  108. package/dist/jsx-runtime-CeSfJrVB.cjs.map +1 -0
  109. package/dist/jsx-runtime-Dpn_P65e.js +634 -0
  110. package/dist/jsx-runtime-Dpn_P65e.js.map +1 -0
  111. package/dist/middlewares/index.cjs.js +2 -0
  112. package/dist/middlewares/index.cjs.js.map +1 -0
  113. package/dist/middlewares/index.d.ts +73 -0
  114. package/dist/middlewares/index.es.js +10 -0
  115. package/dist/middlewares/index.es.js.map +1 -0
  116. package/dist/palette-CE2mKYse.cjs +2 -0
  117. package/dist/palette-CE2mKYse.cjs.map +1 -0
  118. package/dist/palette-C_L0akN_.js +43 -0
  119. package/dist/palette-C_L0akN_.js.map +1 -0
  120. package/dist/router.d.ts +48 -0
  121. package/dist/rtk-query.modern-CjetfYPg.js +3038 -0
  122. package/dist/rtk-query.modern-CjetfYPg.js.map +1 -0
  123. package/dist/rtk-query.modern-PBCErCqb.cjs +15 -0
  124. package/dist/rtk-query.modern-PBCErCqb.cjs.map +1 -0
  125. package/dist/schema.d.ts +89 -0
  126. package/dist/schemas-BZbJpkD5.cjs +2 -0
  127. package/dist/schemas-BZbJpkD5.cjs.map +1 -0
  128. package/dist/schemas-DlOtf2vf.js +162 -0
  129. package/dist/schemas-DlOtf2vf.js.map +1 -0
  130. package/dist/server.cjs.js +6 -0
  131. package/dist/server.cjs.js.map +1 -0
  132. package/dist/server.d.ts +129 -0
  133. package/dist/server.es.js +127 -0
  134. package/dist/server.es.js.map +1 -0
  135. package/dist/session-CE2U7oL1.cjs +2 -0
  136. package/dist/session-CE2U7oL1.cjs.map +1 -0
  137. package/dist/session-CacrgFSv.cjs +2 -0
  138. package/dist/session-CacrgFSv.cjs.map +1 -0
  139. package/dist/session-D312kYKk.js +32 -0
  140. package/dist/session-D312kYKk.js.map +1 -0
  141. package/dist/session-oI-Ht2C8.js +30 -0
  142. package/dist/session-oI-Ht2C8.js.map +1 -0
  143. package/dist/settings/index.cjs.js +2 -0
  144. package/dist/settings/index.cjs.js.map +1 -0
  145. package/dist/settings/index.d.ts +76 -0
  146. package/dist/settings/index.es.js +17 -0
  147. package/dist/settings/index.es.js.map +1 -0
  148. package/dist/slices/index.cjs.js +2 -0
  149. package/dist/slices/index.cjs.js.map +1 -0
  150. package/dist/slices/index.d.ts +74 -0
  151. package/dist/slices/index.es.js +6 -0
  152. package/dist/slices/index.es.js.map +1 -0
  153. package/dist/store.d.ts +17 -0
  154. package/dist/style.css +1 -0
  155. package/dist/test.d.ts +75 -0
  156. package/dist/theme/components/index.cjs.js +2 -0
  157. package/dist/theme/components/index.cjs.js.map +1 -0
  158. package/dist/theme/components/index.d.ts +75 -0
  159. package/dist/theme/components/index.es.js +6 -0
  160. package/dist/theme/components/index.es.js.map +1 -0
  161. package/dist/theme/index.cjs.js +2 -0
  162. package/dist/theme/index.cjs.js.map +1 -0
  163. package/dist/theme/index.d.ts +79 -0
  164. package/dist/theme/index.es.js +222 -0
  165. package/dist/theme/index.es.js.map +1 -0
  166. package/dist/theme.d.ts +19 -0
  167. package/dist/urls-DtHr1d3H.js +14 -0
  168. package/dist/urls-DtHr1d3H.js.map +1 -0
  169. package/dist/urls-MaVXL_C2.cjs +2 -0
  170. package/dist/urls-MaVXL_C2.cjs.map +1 -0
  171. package/dist/utils/api.cjs.js +2 -0
  172. package/dist/utils/api.cjs.js.map +1 -0
  173. package/dist/utils/api.d.ts +144 -0
  174. package/dist/utils/api.es.js +16 -0
  175. package/dist/utils/api.es.js.map +1 -0
  176. package/dist/utils/auth.cjs.js +2 -0
  177. package/dist/utils/auth.cjs.js.map +1 -0
  178. package/dist/utils/auth.d.ts +100 -0
  179. package/dist/utils/auth.es.js +117 -0
  180. package/dist/utils/auth.es.js.map +1 -0
  181. package/dist/utils/form.cjs.js +2 -0
  182. package/dist/utils/form.cjs.js.map +1 -0
  183. package/dist/utils/form.d.ts +97 -0
  184. package/dist/utils/form.es.js +76 -0
  185. package/dist/utils/form.es.js.map +1 -0
  186. package/dist/utils/general.cjs.js +2 -0
  187. package/dist/utils/general.cjs.js.map +1 -0
  188. package/dist/utils/general.d.ts +102 -0
  189. package/{src/utils/general.ts → dist/utils/general.es.js} +87 -165
  190. package/dist/utils/general.es.js.map +1 -0
  191. package/dist/utils/router.cjs.js +2 -0
  192. package/dist/utils/router.cjs.js.map +1 -0
  193. package/dist/utils/router.d.ts +91 -0
  194. package/dist/utils/router.es.js +33 -0
  195. package/dist/utils/router.es.js.map +1 -0
  196. package/dist/utils/schema.cjs.js +2 -0
  197. package/dist/utils/schema.cjs.js.map +1 -0
  198. package/dist/utils/schema.d.ts +115 -0
  199. package/dist/utils/schema.es.js +123 -0
  200. package/dist/utils/schema.es.js.map +1 -0
  201. package/dist/utils/store.cjs.js +2 -0
  202. package/dist/utils/store.cjs.js.map +1 -0
  203. package/dist/utils/store.d.ts +82 -0
  204. package/dist/utils/store.es.js +20 -0
  205. package/dist/utils/store.es.js.map +1 -0
  206. package/dist/utils/test.cjs.js +2 -0
  207. package/dist/utils/test.cjs.js.map +1 -0
  208. package/dist/utils/test.d.ts +125 -0
  209. package/dist/utils/test.es.js +60 -0
  210. package/dist/utils/test.es.js.map +1 -0
  211. package/dist/utils/theme.cjs.js +2 -0
  212. package/dist/utils/theme.cjs.js.map +1 -0
  213. package/dist/utils/theme.d.ts +83 -0
  214. package/dist/utils/theme.es.js +12 -0
  215. package/dist/utils/theme.es.js.map +1 -0
  216. package/dist/utils/window.cjs.js +2 -0
  217. package/dist/utils/window.cjs.js.map +1 -0
  218. package/dist/utils/window.d.ts +74 -0
  219. package/dist/utils/window.es.js +11 -0
  220. package/dist/utils/window.es.js.map +1 -0
  221. package/dist/window.d.ts +5 -0
  222. package/package.json +142 -37
  223. package/.github/workflows/main.yml +0 -55
  224. package/.prettierignore +0 -1
  225. package/CHANGELOG.md +0 -2027
  226. package/CONTRIBUTING.md +0 -3
  227. package/eslint.config.js +0 -17
  228. package/src/api/createApi.ts +0 -91
  229. package/src/api/endpoints/authFactor.ts +0 -31
  230. package/src/api/endpoints/index.ts +0 -9
  231. package/src/api/endpoints/klass.ts +0 -87
  232. package/src/api/endpoints/school.ts +0 -34
  233. package/src/api/endpoints/session.ts +0 -47
  234. package/src/api/endpoints/user.ts +0 -70
  235. package/src/api/index.ts +0 -5
  236. package/src/api/models.ts +0 -145
  237. package/src/api/schemas.ts +0 -243
  238. package/src/api/tagTypes.ts +0 -12
  239. package/src/api/urls.ts +0 -13
  240. package/src/components/App.css +0 -38
  241. package/src/components/App.tsx +0 -152
  242. package/src/components/ClickableTooltip.tsx +0 -43
  243. package/src/components/CopyIconButton.test.tsx +0 -16
  244. package/src/components/CopyIconButton.tsx +0 -27
  245. package/src/components/Countdown.tsx +0 -42
  246. package/src/components/DownloadFileButton.tsx +0 -55
  247. package/src/components/ElevatedAppBar.tsx +0 -41
  248. package/src/components/Image.tsx +0 -41
  249. package/src/components/InputFileButton.tsx +0 -27
  250. package/src/components/ItemizedList.tsx +0 -63
  251. package/src/components/OrderedGrid.tsx +0 -92
  252. package/src/components/ScrollIntoViewLink.tsx +0 -22
  253. package/src/components/SyncError.tsx +0 -14
  254. package/src/components/TablePagination.tsx +0 -142
  255. package/src/components/YouTubeVideo.tsx +0 -26
  256. package/src/components/form/ApiAutocompleteField.tsx +0 -187
  257. package/src/components/form/AutocompleteField.tsx +0 -135
  258. package/src/components/form/CheckboxField.tsx +0 -86
  259. package/src/components/form/CountryField.tsx +0 -75
  260. package/src/components/form/DatePickerField.tsx +0 -126
  261. package/src/components/form/EmailField.tsx +0 -38
  262. package/src/components/form/FirstNameField.tsx +0 -40
  263. package/src/components/form/Form.tsx +0 -165
  264. package/src/components/form/OtpField.tsx +0 -28
  265. package/src/components/form/PasswordField.tsx +0 -71
  266. package/src/components/form/RepeatField.tsx +0 -123
  267. package/src/components/form/SubmitButton.tsx +0 -57
  268. package/src/components/form/TextField.tsx +0 -150
  269. package/src/components/form/UkCountyField.tsx +0 -68
  270. package/src/components/form/index.tsx +0 -35
  271. package/src/components/index.ts +0 -28
  272. package/src/components/page/Banner.tsx +0 -95
  273. package/src/components/page/Notification.tsx +0 -71
  274. package/src/components/page/Page.tsx +0 -73
  275. package/src/components/page/Section.tsx +0 -21
  276. package/src/components/page/TabBar.tsx +0 -131
  277. package/src/components/page/index.ts +0 -10
  278. package/src/components/router/Link.tsx +0 -23
  279. package/src/components/router/LinkButton.tsx +0 -22
  280. package/src/components/router/LinkIconButton.tsx +0 -22
  281. package/src/components/router/LinkListItem.tsx +0 -22
  282. package/src/components/router/LinkTab.tsx +0 -22
  283. package/src/components/router/Navigate.tsx +0 -33
  284. package/src/components/router/index.tsx +0 -9
  285. package/src/components/table/CellStack.tsx +0 -19
  286. package/src/components/table/Table.tsx +0 -55
  287. package/src/components/table/index.tsx +0 -8
  288. package/src/features/InactiveDialog.tsx +0 -40
  289. package/src/features/ScreenTimeDialog.tsx +0 -30
  290. package/src/features/index.ts +0 -4
  291. package/src/fonts/ttf/Inter-VariableFont_slnt,wght.ttf +0 -0
  292. package/src/fonts/ttf/SpaceGrotesk-VariableFont_wght.ttf +0 -0
  293. package/src/hooks/api.tsx +0 -39
  294. package/src/hooks/auth.tsx +0 -397
  295. package/src/hooks/form.tsx +0 -11
  296. package/src/hooks/general.tsx +0 -110
  297. package/src/hooks/index.ts +0 -5
  298. package/src/hooks/router.tsx +0 -168
  299. package/src/images/svg/brain.svg +0 -1
  300. package/src/index.ts +0 -2
  301. package/src/middlewares/index.ts +0 -1
  302. package/src/middlewares/session.ts +0 -21
  303. package/src/scripts/freshDesk.js +0 -473
  304. package/src/scripts/index.ts +0 -1
  305. package/src/server.js +0 -187
  306. package/src/settings/custom.ts +0 -22
  307. package/src/settings/index.ts +0 -7
  308. package/src/settings/vite.ts +0 -26
  309. package/src/setupTests.ts +0 -2
  310. package/src/slices/createSlice.ts +0 -8
  311. package/src/slices/index.ts +0 -2
  312. package/src/slices/session.ts +0 -32
  313. package/src/theme/ThemedBox.tsx +0 -265
  314. package/src/theme/colors.ts +0 -57
  315. package/src/theme/components/MuiAccordion.tsx +0 -13
  316. package/src/theme/components/MuiAutocomplete.tsx +0 -11
  317. package/src/theme/components/MuiButton.ts +0 -70
  318. package/src/theme/components/MuiCardActions.tsx +0 -12
  319. package/src/theme/components/MuiCheckbox.ts +0 -12
  320. package/src/theme/components/MuiContainer.ts +0 -19
  321. package/src/theme/components/MuiDialog.tsx +0 -16
  322. package/src/theme/components/MuiFormControlLabel.ts +0 -18
  323. package/src/theme/components/MuiFormHelperText.ts +0 -12
  324. package/src/theme/components/MuiGrid2.ts +0 -16
  325. package/src/theme/components/MuiInputBase.ts +0 -14
  326. package/src/theme/components/MuiLink.ts +0 -41
  327. package/src/theme/components/MuiList.ts +0 -12
  328. package/src/theme/components/MuiListItemText.ts +0 -18
  329. package/src/theme/components/MuiMenu.ts +0 -14
  330. package/src/theme/components/MuiMenuItem.ts +0 -15
  331. package/src/theme/components/MuiSelect.ts +0 -16
  332. package/src/theme/components/MuiTab.ts +0 -29
  333. package/src/theme/components/MuiTable.ts +0 -29
  334. package/src/theme/components/MuiTableBody.ts +0 -15
  335. package/src/theme/components/MuiTableHead.ts +0 -26
  336. package/src/theme/components/MuiTabs.ts +0 -26
  337. package/src/theme/components/MuiTextField.ts +0 -86
  338. package/src/theme/components/MuiToolbar.ts +0 -11
  339. package/src/theme/components/MuiTypography.ts +0 -12
  340. package/src/theme/components/_components.ts +0 -95
  341. package/src/theme/components/index.ts +0 -57
  342. package/src/theme/index.ts +0 -25
  343. package/src/theme/palette.ts +0 -98
  344. package/src/theme/spacing.ts +0 -8
  345. package/src/theme/typography.ts +0 -101
  346. package/src/utils/api.test.ts +0 -19
  347. package/src/utils/api.tsx +0 -339
  348. package/src/utils/auth.ts +0 -78
  349. package/src/utils/form.test.ts +0 -50
  350. package/src/utils/form.ts +0 -193
  351. package/src/utils/general.test.ts +0 -55
  352. package/src/utils/router.test.ts +0 -156
  353. package/src/utils/router.ts +0 -67
  354. package/src/utils/schema.ts +0 -290
  355. package/src/utils/store.ts +0 -31
  356. package/src/utils/test.tsx +0 -82
  357. package/src/utils/theme.tsx +0 -83
  358. package/src/utils/window.ts +0 -11
  359. package/src/vite-env.d.ts +0 -1
  360. package/tsconfig.app.json +0 -4
  361. package/tsconfig.json +0 -7
  362. package/tsconfig.node.json +0 -4
  363. package/types/fixes.d.ts +0 -18
  364. package/vite.config.ts +0 -23
@@ -1,243 +0,0 @@
1
- import * as yup from "yup"
2
-
3
- import type {
4
- AdminSchoolTeacher,
5
- AdminSchoolTeacherUser,
6
- AuthFactor,
7
- Class,
8
- IndependentUser,
9
- NonAdminSchoolTeacher,
10
- NonAdminSchoolTeacherUser,
11
- NonSchoolTeacher,
12
- NonSchoolTeacherUser,
13
- OtpBypassToken,
14
- School,
15
- SchoolTeacher,
16
- SchoolTeacherUser,
17
- Student,
18
- StudentUser,
19
- Teacher,
20
- TeacherUser,
21
- User,
22
- } from "./models"
23
- import { COUNTRY_ISO_CODES, UK_COUNTIES } from "../utils/general"
24
- import {
25
- lowercaseAsciiAlphanumericString,
26
- numericId,
27
- unicodeAlphanumericString,
28
- uppercaseAsciiAlphanumericString,
29
- } from "../utils/schema"
30
- import { type Schemas } from "../utils/api"
31
-
32
- // NOTE: do not use .required() here.
33
- const id = {
34
- user: numericId(),
35
- teacher: numericId(),
36
- student: numericId(),
37
- school: numericId(),
38
- klass: uppercaseAsciiAlphanumericString().length(5),
39
- authFactor: numericId(),
40
- otpBypassToken: numericId(),
41
- }
42
-
43
- // -----------------------------------------------------------------------------
44
- // User Schemas
45
- // -----------------------------------------------------------------------------
46
-
47
- const _userTeacher: Omit<Schemas<Teacher>, "user"> = {
48
- id: id.teacher.required(),
49
- school: id.school,
50
- is_admin: yup.bool().required(),
51
- }
52
-
53
- const _userStudent: Omit<Schemas<Student>, "user"> = {
54
- id: id.student.required(),
55
- school: id.school.required(),
56
- klass: id.klass.required(),
57
- auto_gen_password: yup.string().required(),
58
- }
59
-
60
- export const user: Schemas<User> = {
61
- id: id.user.required(),
62
- requesting_to_join_class: id.klass,
63
- first_name: unicodeAlphanumericString({
64
- spaces: true,
65
- specialChars: "-'",
66
- })
67
- .required()
68
- .max(150),
69
- last_name: unicodeAlphanumericString({
70
- spaces: true,
71
- specialChars: "-'",
72
- }).max(150),
73
- last_login: yup.date(),
74
- email: yup.string().email(),
75
- password: yup.string().required(),
76
- is_staff: yup.bool().required(),
77
- is_active: yup.bool().required(),
78
- date_joined: yup.date().required(),
79
- teacher: yup.object(_userTeacher).optional(),
80
- student: yup.object(_userStudent).optional(),
81
- }
82
-
83
- export const teacherUser: Schemas<TeacherUser> = {
84
- ...user,
85
- password: user.password
86
- .min(10, "must be at least 10 characters long")
87
- .matches(/[A-Z]/, "must contain at least one uppercase letter")
88
- .matches(/[a-z]/, "must contain at least one lowercase letter")
89
- .matches(/[0-9]/, "must contain at least one digit")
90
- .matches(
91
- /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
92
- "must contain at least one special character",
93
- ),
94
- email: user.email.required(),
95
- last_name: user.last_name.required(),
96
- teacher: user.teacher.required(),
97
- student: yup.string().oneOf([undefined]),
98
- }
99
-
100
- const _userSchoolTeacher: Omit<Schemas<SchoolTeacher>, "user"> = {
101
- ..._userTeacher,
102
- school: _userTeacher.school.required(),
103
- }
104
-
105
- export const schoolTeacherUser: Schemas<SchoolTeacherUser> = {
106
- ...teacherUser,
107
- teacher: yup.object(_userSchoolTeacher),
108
- }
109
-
110
- const _userAdminSchoolTeacher: Omit<Schemas<AdminSchoolTeacher>, "user"> = {
111
- ..._userSchoolTeacher,
112
- is_admin: _userSchoolTeacher.is_admin.isTrue(),
113
- }
114
-
115
- export const adminSchoolTeacherUser: Schemas<AdminSchoolTeacherUser> = {
116
- ...schoolTeacherUser,
117
- teacher: yup.object(_userAdminSchoolTeacher),
118
- }
119
-
120
- const _userNonAdminSchoolTeacher: Omit<
121
- Schemas<NonAdminSchoolTeacher>,
122
- "user"
123
- > = {
124
- ..._userSchoolTeacher,
125
- is_admin: _userSchoolTeacher.is_admin.isFalse(),
126
- }
127
-
128
- export const nonAdminSchoolTeacherUser: Schemas<NonAdminSchoolTeacherUser> = {
129
- ...schoolTeacherUser,
130
- teacher: yup.object(_userNonAdminSchoolTeacher),
131
- }
132
-
133
- const _userNonSchoolTeacher: Omit<Schemas<NonSchoolTeacher>, "user"> = {
134
- ..._userTeacher,
135
- school: yup.string().oneOf([undefined]),
136
- is_admin: _userTeacher.is_admin.isFalse(),
137
- }
138
-
139
- export const nonSchoolTeacherUser: Schemas<NonSchoolTeacherUser> = {
140
- ...teacherUser,
141
- teacher: yup.object(_userNonSchoolTeacher),
142
- }
143
-
144
- export const studentUser: Schemas<StudentUser> = {
145
- ...user,
146
- password: user.password.min(6, "must be at least 6 characters long"),
147
- email: user.email.oneOf([undefined]),
148
- last_name: user.last_name.oneOf([undefined]),
149
- teacher: yup.string().oneOf([undefined]),
150
- student: user.student.required(),
151
- }
152
-
153
- export const indyUser: Schemas<IndependentUser> = {
154
- ...user,
155
- password: user.password
156
- .min(8, "must be at least 8 characters long")
157
- .matches(/[A-Z]/, "must contain at least one uppercase letter")
158
- .matches(/[a-z]/, "must contain at least one lowercase letter")
159
- .matches(/[0-9]/, "must contain at least one digit"),
160
- email: user.email.required(),
161
- last_name: user.last_name.required(),
162
- teacher: yup.string().oneOf([undefined]),
163
- student: yup.string().oneOf([undefined]),
164
- }
165
-
166
- // -----------------------------------------------------------------------------
167
- // Teacher Schemas
168
- // -----------------------------------------------------------------------------
169
-
170
- export const teacher: Schemas<Teacher> = {
171
- ..._userTeacher,
172
- user: id.user.required(),
173
- }
174
-
175
- export const schoolTeacher: Schemas<SchoolTeacher> = {
176
- ..._userSchoolTeacher,
177
- user: id.user.required(),
178
- }
179
-
180
- export const adminSchoolTeacher: Schemas<AdminSchoolTeacher> = {
181
- ..._userAdminSchoolTeacher,
182
- user: id.user.required(),
183
- }
184
-
185
- export const nonAdminSchoolTeacher: Schemas<NonAdminSchoolTeacher> = {
186
- ..._userNonAdminSchoolTeacher,
187
- user: id.user.required(),
188
- }
189
-
190
- export const nonSchoolTeacher: Schemas<NonSchoolTeacher> = {
191
- ..._userNonSchoolTeacher,
192
- user: id.user.required(),
193
- }
194
-
195
- // -----------------------------------------------------------------------------
196
- // Other Schemas
197
- // -----------------------------------------------------------------------------
198
-
199
- export const student: Schemas<Student> = {
200
- ..._userStudent,
201
- user: id.user.required(),
202
- }
203
-
204
- export const school: Schemas<School> = {
205
- id: id.school.required(),
206
- name: unicodeAlphanumericString({
207
- spaces: true,
208
- specialChars: "'.",
209
- })
210
- .required()
211
- .max(200),
212
- country: yup.string().oneOf(COUNTRY_ISO_CODES),
213
- uk_county: yup.string().oneOf(UK_COUNTIES),
214
- }
215
-
216
- export const klass: Schemas<Class> = {
217
- id: id.klass.required(),
218
- teacher: id.teacher.required(),
219
- school: id.school.required(),
220
- name: unicodeAlphanumericString({
221
- spaces: true,
222
- specialChars: "-_",
223
- })
224
- .required()
225
- .max(200),
226
- read_classmates_data: yup.bool().required(),
227
- receive_requests_until: yup.date(),
228
- }
229
-
230
- export const authFactor: Schemas<AuthFactor> = {
231
- id: id.authFactor.required(),
232
- user: id.user.required(),
233
- type: yup
234
- .string()
235
- .oneOf(["otp"] as const)
236
- .required(),
237
- }
238
-
239
- export const otpBypassToken: Schemas<OtpBypassToken> = {
240
- id: id.otpBypassToken.required(),
241
- user: id.user.required(),
242
- token: lowercaseAsciiAlphanumericString().required().length(8),
243
- }
@@ -1,12 +0,0 @@
1
- const tagTypes = [
2
- // These are the tags for the common models used throughout our system.
3
- // https://github.com/ocadotechnology/codeforlife-package-python/tree/main/codeforlife/user/models
4
- // NOTE: Don't use the "Teacher" and "Student" tags. Use "User" instead.
5
- "User",
6
- "School",
7
- "Class",
8
- "AuthFactor",
9
- ] as const
10
-
11
- export default tagTypes
12
- export type TagTypes = (typeof tagTypes)[number]
package/src/api/urls.ts DELETED
@@ -1,13 +0,0 @@
1
- import { modelUrls } from "../utils/api"
2
-
3
- const urls = {
4
- user: modelUrls("users/", "users/<id>/"),
5
- teacher: modelUrls("users/teachers/", "users/teachers/<id>/"),
6
- student: modelUrls("users/students/", "users/students/<id>/"),
7
- school: modelUrls("schools/", "schools/<id>/"),
8
- class: modelUrls("classes/", "classes/<id>/"),
9
- otpBypassToken: modelUrls("otp-bypass-tokens/", "otp-bypass-tokens/<id>/"),
10
- authFactor: modelUrls("auth-factors/", "auth-factors/<id>/"),
11
- }
12
-
13
- export default urls
@@ -1,38 +0,0 @@
1
- @font-face {
2
- font-family: "SpaceGrotesk";
3
- src:
4
- local("SpaceGrotesk"),
5
- url("../fonts/ttf/SpaceGrotesk-VariableFont_wght.ttf") format("truetype");
6
- }
7
-
8
- @font-face {
9
- font-family: "Inter";
10
- src:
11
- local("Inter"),
12
- url("../fonts/ttf/Inter-VariableFont_slnt,wght.ttf") format("truetype");
13
- }
14
-
15
- html,
16
- body {
17
- box-sizing: border-box;
18
- height: 100%;
19
- padding: 0;
20
- margin: 0;
21
- }
22
-
23
- #root {
24
- box-sizing: border-box;
25
- min-height: 100%;
26
- display: flex;
27
- flex-direction: column;
28
- }
29
-
30
- #header,
31
- #footer {
32
- flex-grow: 0;
33
- flex-shrink: 0;
34
- }
35
-
36
- #body {
37
- flex-grow: 1;
38
- }
@@ -1,152 +0,0 @@
1
- import { BrowserRouter, Routes as RouterRoutes } from "react-router-dom"
2
- import { CssBaseline, ThemeProvider } from "@mui/material"
3
- import { type FC, type JSX, type ReactNode } from "react"
4
- import { Provider, type ProviderProps } from "react-redux"
5
- import { type Action } from "redux"
6
- import { StaticRouter } from "react-router-dom/server"
7
- import { type ThemeProviderProps } from "@mui/material/styles/ThemeProvider"
8
-
9
- import "./App.css"
10
- import { SSR } from "../settings"
11
- import { useLocation } from "../hooks"
12
- // import { InactiveDialog, ScreenTimeDialog } from "../features"
13
- // import { useCountdown, useEventListener } from "../hooks"
14
- // import "../scripts"
15
- // import {
16
- // configureFreshworksWidget,
17
- // toggleOneTrustInfoDisplay,
18
- // } from "../utils/window"
19
-
20
- export interface AppProps<A extends Action = Action, S = unknown> {
21
- path?: string
22
- theme: ThemeProviderProps["theme"]
23
- store: ProviderProps<A, S>["store"]
24
- routes: ReactNode
25
- header?: ReactNode
26
- footer?: ReactNode
27
- headerExcludePaths?: string[]
28
- footerExcludePaths?: string[]
29
- maxIdleSeconds?: number
30
- maxTotalSeconds?: number
31
- }
32
-
33
- type BaseRoutesProps = Pick<
34
- AppProps,
35
- "routes" | "header" | "footer" | "headerExcludePaths" | "footerExcludePaths"
36
- >
37
-
38
- const Routes: FC<BaseRoutesProps & { path: string }> = ({
39
- path,
40
- routes,
41
- header = <></>, // TODO: "header = <Header />"
42
- footer = <></>, // TODO: "footer = <Footer />"
43
- headerExcludePaths = [],
44
- footerExcludePaths = [],
45
- }) => (
46
- <>
47
- {!headerExcludePaths.includes(path) && header}
48
- <RouterRoutes>{routes}</RouterRoutes>
49
- {!footerExcludePaths.includes(path) && footer}
50
- </>
51
- )
52
-
53
- const BrowserRoutes: FC<BaseRoutesProps> = props => {
54
- const { pathname } = useLocation()
55
-
56
- return <Routes path={pathname} {...props} />
57
- }
58
-
59
- const App = <A extends Action = Action, S = unknown>({
60
- path,
61
- theme,
62
- store,
63
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
64
- maxIdleSeconds = 60 * 60,
65
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
66
- maxTotalSeconds = 60 * 60,
67
- ...routesProps
68
- }: AppProps<A, S>): JSX.Element => {
69
- // TODO: cannot use document during SSR
70
- // const root = document.getElementById("root") as HTMLElement
71
-
72
- // const [idleSeconds, setIdleSeconds] = useCountdown(maxIdleSeconds)
73
- // const [totalSeconds, setTotalSeconds] = useCountdown(maxTotalSeconds)
74
- // const resetIdleSeconds = useCallback(() => {
75
- // setIdleSeconds(maxIdleSeconds)
76
- // }, [setIdleSeconds, maxIdleSeconds])
77
-
78
- // const isIdle = idleSeconds === 0
79
- // const tooMuchScreenTime = totalSeconds === 0
80
-
81
- // useEventListener(root, "mousemove", resetIdleSeconds)
82
- // useEventListener(root, "keypress", resetIdleSeconds)
83
-
84
- // React.useEffect(() => {
85
- // configureFreshworksWidget("hide")
86
- // }, [])
87
-
88
- // if (import.meta.env.PROD) {
89
- // toggleOneTrustInfoDisplay()
90
- // }
91
-
92
- return (
93
- <ThemeProvider theme={theme}>
94
- <CssBaseline />
95
- <Provider store={store}>
96
- {/* <InactiveDialog open={isIdle} onClose={resetIdleSeconds} />
97
- <ScreenTimeDialog
98
- open={!isIdle && tooMuchScreenTime}
99
- onClose={() => {
100
- setTotalSeconds(maxTotalSeconds)
101
- }}
102
- /> */}
103
- {SSR ? (
104
- <StaticRouter location={path as string}>
105
- <Routes path={path as string} {...routesProps} />
106
- </StaticRouter>
107
- ) : (
108
- <BrowserRouter>
109
- <BrowserRoutes {...routesProps} />
110
- </BrowserRouter>
111
- )}
112
- </Provider>
113
- </ThemeProvider>
114
- )
115
- }
116
-
117
- export default App
118
-
119
- // TODO: figure out what to do with this
120
- // function useOneTrustScripts(): void {
121
- // const oneTrustEventTypes = [
122
- // useExternalScript({
123
- // props: {
124
- // src: "https://cdn-ukwest.onetrust.com/consent/5da42396-cb12-4493-8d04-5179033cfbad/OtAutoBlock.js",
125
- // type: "text/javascript",
126
- // },
127
- // eventTypes: ["load", "error"],
128
- // }),
129
- // useExternalScript({
130
- // props: {
131
- // src: "https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js",
132
- // type: "text/javascript",
133
- // charset: "UTF-8",
134
- // },
135
- // attrs: {
136
- // "data-domain-script": "5da42396-cb12-4493-8d04-5179033cfbad",
137
- // },
138
- // eventTypes: ["load", "error"],
139
- // }),
140
- // useExternalScript({
141
- // props: {
142
- // src: "https://cdn-ukwest.onetrust.com/scripttemplates/202302.1.0/otBannerSdk.js",
143
- // async: true,
144
- // type: "text/javascript",
145
- // },
146
- // eventTypes: ["load", "error"],
147
- // }),
148
- // ]
149
- // if (oneTrustEventTypes.some(t => t === "error")) {
150
- // alert("OneTrust failed to load!")
151
- // }
152
- // }
@@ -1,43 +0,0 @@
1
- import { Tooltip, type TooltipProps } from "@mui/material"
2
- import React from "react"
3
-
4
- import { wrap } from "../utils/general"
5
-
6
- export interface ClickableTooltipProps extends TooltipProps {}
7
-
8
- const ClickableTooltip: React.FC<ClickableTooltipProps> = ({
9
- open = false,
10
- onClick,
11
- ...otherTooltipProps
12
- }) => {
13
- const [_open, _setOpen] = React.useState(open)
14
-
15
- React.useEffect(() => {
16
- _setOpen(open)
17
- }, [open])
18
-
19
- return (
20
- <Tooltip
21
- open={_open}
22
- onMouseOver={() => {
23
- if (!_open) {
24
- _setOpen(true)
25
- }
26
- }}
27
- onMouseLeave={() => {
28
- _setOpen(false)
29
- }}
30
- onClick={wrap(
31
- {
32
- after: () => {
33
- _setOpen(!_open)
34
- },
35
- },
36
- onClick,
37
- )}
38
- {...otherTooltipProps}
39
- />
40
- )
41
- }
42
-
43
- export default ClickableTooltip
@@ -1,16 +0,0 @@
1
- import { screen } from "@testing-library/react"
2
-
3
- import CopyIconButton from "./CopyIconButton"
4
- import { renderWithUser } from "../utils/test"
5
-
6
- test("Clicking button should copy content", async () => {
7
- const content = "Example string to be copied."
8
-
9
- const { user } = renderWithUser(<CopyIconButton content={content} />)
10
-
11
- expect(await navigator.clipboard.readText()).toEqual("")
12
-
13
- await user.click(screen.getByTestId("copy-icon-button"))
14
-
15
- expect(await navigator.clipboard.readText()).toEqual(content)
16
- })
@@ -1,27 +0,0 @@
1
- import { IconButton, type IconButtonProps } from "@mui/material"
2
- import { ContentCopy as ContentCopyIcon } from "@mui/icons-material"
3
- import type { FC } from "react"
4
-
5
- export interface CopyIconButtonProps extends Omit<IconButtonProps, "onClick"> {
6
- content: string
7
- }
8
-
9
- const CopyIconButton: FC<CopyIconButtonProps> = ({
10
- content,
11
- children = <ContentCopyIcon />,
12
- ...otherIconButtonProps
13
- }) => {
14
- return (
15
- <IconButton
16
- data-testid="copy-icon-button"
17
- onClick={() => {
18
- void navigator.clipboard.writeText(content)
19
- }}
20
- {...otherIconButtonProps}
21
- >
22
- {children}
23
- </IconButton>
24
- )
25
- }
26
-
27
- export default CopyIconButton
@@ -1,42 +0,0 @@
1
- import { type FC, useState } from "react"
2
- import { Typography, type TypographyProps } from "@mui/material"
3
-
4
- import { useCountdown } from "../hooks"
5
-
6
- export interface CountdownProps extends Omit<TypographyProps, "children"> {
7
- seconds: number
8
- start?: boolean
9
- onEnd: () => void
10
- }
11
-
12
- const Countdown: FC<CountdownProps> = ({
13
- seconds,
14
- start = true,
15
- onEnd,
16
- ...typographyProps
17
- }) => {
18
- seconds = Math.floor(seconds)
19
- const _seconds = useCountdown(seconds)[0]
20
- const [end, setEnd] = useState(!start)
21
-
22
- if (_seconds === 0 && !end) {
23
- setEnd(true)
24
- onEnd()
25
- }
26
-
27
- seconds = Math.floor(_seconds % 60)
28
- const minutes = Math.floor(_seconds / 60)
29
-
30
- return (
31
- <>
32
- {_seconds > 0 && (
33
- <Typography {...typographyProps}>
34
- {minutes > 0 && `${minutes} ${minutes > 1 ? "mins" : "min"} `}
35
- {seconds > 0 && `${seconds} ${seconds > 1 ? "secs" : "sec"}`}
36
- </Typography>
37
- )}
38
- </>
39
- )
40
- }
41
-
42
- export default Countdown
@@ -1,55 +0,0 @@
1
- import { Button, type ButtonProps } from "@mui/material"
2
- import { type FC, useEffect } from "react"
3
- import { Download as DownloadIcon } from "@mui/icons-material"
4
-
5
- export type DownloadFileButtonProps = ButtonProps & {
6
- file:
7
- | Blob
8
- | MediaSource
9
- | {
10
- text: string
11
- mimeType: "plain" | "csv"
12
- name: string
13
- charset?: string
14
- extension?: string
15
- }
16
- }
17
-
18
- const DownloadFileButton: FC<DownloadFileButtonProps> = ({
19
- children = "Download",
20
- endIcon = <DownloadIcon />,
21
- file,
22
- ...otherButtonProps
23
- }) => {
24
- let url: undefined | string = undefined
25
- let anchorProps: undefined | { download?: string; href: string } = undefined
26
- if ("mimeType" in file) {
27
- const { text, mimeType, name, charset = "utf-8" } = file
28
- let { extension } = file
29
-
30
- if (!extension) extension = "." + { plain: "txt", csv: "csv" }[mimeType]
31
-
32
- anchorProps = {
33
- download: name + extension,
34
- href: `data:text/${mimeType};charset=${charset},${encodeURIComponent(text)}`,
35
- }
36
- } else {
37
- url = URL.createObjectURL(file)
38
-
39
- anchorProps = { href: url }
40
- }
41
-
42
- useEffect(() => {
43
- return () => {
44
- if (url) URL.revokeObjectURL(url)
45
- }
46
- }, [url])
47
-
48
- return (
49
- <Button endIcon={endIcon} {...otherButtonProps} {...anchorProps}>
50
- {children}
51
- </Button>
52
- )
53
- }
54
-
55
- export default DownloadFileButton
@@ -1,41 +0,0 @@
1
- import {
2
- AppBar,
3
- type AppBarProps,
4
- Container,
5
- type ContainerProps,
6
- Toolbar,
7
- type ToolbarProps,
8
- useScrollTrigger,
9
- } from "@mui/material"
10
- import { type FC, cloneElement } from "react"
11
-
12
- export interface ElevatedAppBarProps extends Omit<AppBarProps, "position"> {
13
- containerProps: ContainerProps
14
- toolbarProps?: ToolbarProps
15
- }
16
-
17
- const ElevatedAppBar: FC<ElevatedAppBarProps> = ({
18
- containerProps,
19
- toolbarProps,
20
- elevation = 4,
21
- children,
22
- ...otherProps
23
- }) => {
24
- const trigger = useScrollTrigger({
25
- disableHysteresis: true,
26
- threshold: 0,
27
- })
28
-
29
- return cloneElement(
30
- <AppBar elevation={elevation} {...otherProps}>
31
- <Container {...containerProps}>
32
- <Toolbar {...toolbarProps}>{children}</Toolbar>
33
- </Container>
34
- </AppBar>,
35
- {
36
- position: trigger ? "fixed" : "sticky",
37
- },
38
- )
39
- }
40
-
41
- export default ElevatedAppBar