codeforlife-portal 5.32.2__py2.py3-none-any.whl → 8.9.9__py2.py3-none-any.whl

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 (393) hide show
  1. cfl_common/common/__init__.py +1 -0
  2. cfl_common/common/app_settings.py +66 -0
  3. cfl_common/common/apps.py +6 -0
  4. cfl_common/common/context_processors.py +9 -0
  5. cfl_common/common/csp_config.py +85 -0
  6. cfl_common/common/helpers/__init__.py +0 -0
  7. cfl_common/common/helpers/data_migration_loader.py +42 -0
  8. cfl_common/common/helpers/emails.py +393 -0
  9. cfl_common/common/helpers/generators.py +52 -0
  10. cfl_common/common/helpers/organisation.py +10 -0
  11. cfl_common/common/mail.py +201 -0
  12. cfl_common/common/migrations/0001_initial.py +240 -0
  13. cfl_common/common/migrations/0002_emailverification.py +55 -0
  14. cfl_common/common/migrations/0003_aimmocharacter.py +31 -0
  15. cfl_common/common/migrations/0004_add_aimmocharacters.py +17 -0
  16. cfl_common/common/migrations/0005_add_worksheets.py +8 -0
  17. cfl_common/common/migrations/0006_update_aimmo_character_image_path.py +17 -0
  18. cfl_common/common/migrations/0007_add_pdf_names_to_first_two_worksheets.py +8 -0
  19. cfl_common/common/migrations/0008_unlock_worksheet_3.py +11 -0
  20. cfl_common/common/migrations/0009_add_blocked_time_to_teacher_and_student.py +24 -0
  21. cfl_common/common/migrations/0010_remove_teacher_title.py +18 -0
  22. cfl_common/common/migrations/0011_student_login_id.py +18 -0
  23. cfl_common/common/migrations/0012_usersession.py +39 -0
  24. cfl_common/common/migrations/0013_class_school.py +42 -0
  25. cfl_common/common/migrations/0014_login_type.py +29 -0
  26. cfl_common/common/migrations/0015_dailyactivity.py +31 -0
  27. cfl_common/common/migrations/0016_joinreleasestudent.py +42 -0
  28. cfl_common/common/migrations/0017_copy_email_to_username.py +18 -0
  29. cfl_common/common/migrations/0018_update_aimmo_character_image_path.py +15 -0
  30. cfl_common/common/migrations/0019_aimmocharacter_alt.py +16 -0
  31. cfl_common/common/migrations/0020_class_is_active_and_null_access_code.py +23 -0
  32. cfl_common/common/migrations/0021_school_is_active.py +28 -0
  33. cfl_common/common/migrations/0022_school_cleanup.py +29 -0
  34. cfl_common/common/migrations/0023_userprofile_aimmo_badges.py +22 -0
  35. cfl_common/common/migrations/0024_teacher_invited_by.py +25 -0
  36. cfl_common/common/migrations/0025_schoolteacherinvitation.py +47 -0
  37. cfl_common/common/migrations/0026_teacher_remove_join_request.py +22 -0
  38. cfl_common/common/migrations/0027_class_created_by.py +25 -0
  39. cfl_common/common/migrations/0028_coding_club_downloads.py +23 -0
  40. cfl_common/common/migrations/0029_dynamicelement.py +22 -0
  41. cfl_common/common/migrations/0030_add_maintenance_banner.py +25 -0
  42. cfl_common/common/migrations/0031_improve_admin_panel.py +56 -0
  43. cfl_common/common/migrations/0032_dailyactivity_level_control_submits.py +18 -0
  44. cfl_common/common/migrations/0033_password_reset_tracking_fields.py +23 -0
  45. cfl_common/common/migrations/0034_dailyactivity_daily_school_student_lockout_reset.py +18 -0
  46. cfl_common/common/migrations/0035_rename_lockout_fields.py +27 -0
  47. cfl_common/common/migrations/0036_rename_awaiting_email_verification_userprofile_is_verified.py +17 -0
  48. cfl_common/common/migrations/0037_migrate_email_verification.py +21 -0
  49. cfl_common/common/migrations/0038_delete_emailverification.py +16 -0
  50. cfl_common/common/migrations/0039_copy_email_to_username.py +18 -0
  51. cfl_common/common/migrations/0040_school_county.py +18 -0
  52. cfl_common/common/migrations/0041_populate_gb_counties.py +27 -0
  53. cfl_common/common/migrations/0042_totalactivity.py +25 -0
  54. cfl_common/common/migrations/0043_add_total_activity.py +30 -0
  55. cfl_common/common/migrations/0044_update_activity_models.py +33 -0
  56. cfl_common/common/migrations/0045_otp.py +23 -0
  57. cfl_common/common/migrations/0046_alter_school_country.py +19 -0
  58. cfl_common/common/migrations/0047_delete_school_postcode.py +16 -0
  59. cfl_common/common/migrations/0048_unique_school_names.py +42 -0
  60. cfl_common/common/migrations/0049_anonymise_orphan_users.py +29 -0
  61. cfl_common/common/migrations/0050_anonymise_orphan_schools.py +30 -0
  62. cfl_common/common/migrations/0051_verify_returning_users.py +26 -0
  63. cfl_common/common/migrations/0052_add_cse_fields.py +68 -0
  64. cfl_common/common/migrations/0053_clean_class_data.py +24 -0
  65. cfl_common/common/migrations/0054_delete_aimmo_models.py +20 -0
  66. cfl_common/common/migrations/0055_alter_schoolteacherinvitation_token.py +18 -0
  67. cfl_common/common/migrations/0056_set_non_school_teachers_as_non_admins.py +25 -0
  68. cfl_common/common/migrations/0057_teacher_teacher__is_admin.py +19 -0
  69. cfl_common/common/migrations/0058_userprofile_google_refresh_token_and_more.py +24 -0
  70. cfl_common/common/migrations/__init__.py +0 -0
  71. cfl_common/common/models.py +557 -0
  72. cfl_common/common/permissions.py +84 -0
  73. cfl_common/common/tests/__init__.py +0 -0
  74. cfl_common/common/tests/test_migration_anonymise_orphan_schools.py +30 -0
  75. cfl_common/common/tests/test_migration_anonymise_orphan_users.py +30 -0
  76. cfl_common/common/tests/test_migration_blocked_time.py +15 -0
  77. cfl_common/common/tests/test_migration_remove_teacher_title.py +13 -0
  78. cfl_common/common/tests/test_migration_unique_school_names.py +33 -0
  79. cfl_common/common/tests/test_migration_verify_returning_users.py +59 -0
  80. cfl_common/common/tests/test_models.py +87 -0
  81. cfl_common/common/tests/utils/__init__.py +0 -0
  82. cfl_common/common/tests/utils/classes.py +38 -0
  83. cfl_common/common/tests/utils/email.py +67 -0
  84. cfl_common/common/tests/utils/organisation.py +41 -0
  85. cfl_common/common/tests/utils/student.py +123 -0
  86. cfl_common/common/tests/utils/teacher.py +73 -0
  87. cfl_common/common/tests/utils/user.py +27 -0
  88. cfl_common/common/utils.py +56 -0
  89. cfl_common/setup.py +61 -0
  90. codeforlife_portal-8.9.9.dist-info/METADATA +226 -0
  91. {codeforlife_portal-5.32.2.dist-info → codeforlife_portal-8.9.9.dist-info}/RECORD +341 -238
  92. {codeforlife_portal-5.32.2.dist-info → codeforlife_portal-8.9.9.dist-info}/WHEEL +1 -1
  93. codeforlife_portal-8.9.9.dist-info/licenses/LICENSE.md +3 -0
  94. {codeforlife_portal-5.32.2.dist-info → codeforlife_portal-8.9.9.dist-info}/top_level.txt +1 -0
  95. deploy/middleware/maintenance.py +25 -0
  96. deploy/middleware/screentime_warning.py +29 -0
  97. deploy/middleware/security.py +5 -6
  98. deploy/middleware/session_timeout.py +31 -0
  99. deploy/middleware/tmp_basic_auth.py +41 -0
  100. example_project/portal_test_settings.py +239 -0
  101. example_project/settings.py +156 -17
  102. example_project/urls.py +5 -6
  103. portal/__init__.py +1 -1
  104. portal/admin.py +142 -29
  105. portal/app_settings.py +10 -7
  106. portal/forms/dotmailer.py +6 -4
  107. portal/forms/invite_teacher.py +19 -10
  108. portal/forms/organisation.py +137 -68
  109. portal/forms/play.py +53 -98
  110. portal/forms/registration.py +70 -164
  111. portal/forms/teach.py +147 -121
  112. portal/handlers.py +1 -2
  113. portal/helpers/decorators.py +30 -10
  114. portal/helpers/password.py +86 -47
  115. portal/helpers/ratelimit.py +32 -15
  116. portal/helpers/regexes.py +5 -0
  117. portal/helpers/request_handlers.py +10 -0
  118. portal/migrations/0044_auto_20150430_0959.py +6 -2
  119. portal/mixins/__init__.py +1 -0
  120. portal/mixins/cron_mixin.py +12 -0
  121. portal/permissions/__init__.py +1 -0
  122. portal/permissions/is_cron_request_from_google.py +14 -0
  123. portal/static/portal/img/10_years_anniversary.png +0 -0
  124. portal/static/portal/img/RR_logo_grass_background.png +0 -0
  125. portal/static/portal/img/coding_club_hero.jpg +0 -0
  126. portal/static/portal/img/coding_club_python_pack.png +0 -0
  127. portal/static/portal/img/facebook.png +0 -0
  128. portal/static/portal/img/gitbook.png +0 -0
  129. portal/static/portal/img/howe_dell_1.png +0 -0
  130. portal/static/portal/img/howe_dell_2.png +0 -0
  131. portal/static/portal/img/howe_dell_3.png +0 -0
  132. portal/static/portal/img/logo_cfl.png +0 -0
  133. portal/static/portal/img/logo_cfl_powered.svg +35 -0
  134. portal/static/portal/img/logo_cfl_reminder_cards.jpg +0 -0
  135. portal/static/portal/img/logo_ocado_group.png +0 -0
  136. portal/static/portal/img/logo_python_den.svg +21 -0
  137. portal/static/portal/img/long_europe_map.png +0 -0
  138. portal/static/portal/img/python_den.png +0 -0
  139. portal/static/portal/img/python_den_banner.svg +26 -0
  140. portal/static/portal/img/rapid_router_landing_hero.png +0 -0
  141. portal/static/portal/img/rr_advanced.png +0 -0
  142. portal/static/portal/img/ten_year_map_pin.svg +1 -0
  143. portal/static/portal/img/thumbnail_educate_rapid_router.png +0 -0
  144. portal/static/portal/img/thumbnail_educate_resources.png +0 -0
  145. portal/static/portal/img/thumbnail_play_rapid_router.png +0 -0
  146. portal/static/portal/img/thumbnail_python_den.png +0 -0
  147. portal/static/portal/img/twitter.png +0 -0
  148. portal/static/portal/js/carouselCards.js +25 -0
  149. portal/static/portal/js/common.js +96 -1
  150. portal/static/portal/js/independentLogin.js +16 -0
  151. portal/static/portal/js/independentRegistration.js +86 -0
  152. portal/static/portal/js/levelControl.js +77 -0
  153. portal/static/portal/js/lib/jquery.min.js +2 -0
  154. portal/static/portal/js/organisation_manage.js +142 -14
  155. portal/static/portal/js/passwordStrength.js +154 -64
  156. portal/static/portal/js/resetPassword.js +23 -0
  157. portal/static/portal/js/riveted.min.js +238 -239
  158. portal/static/portal/js/school.js +13 -0
  159. portal/static/portal/js/studentLogin.js +16 -0
  160. portal/static/portal/js/teacherEditStudent.js +23 -0
  161. portal/static/portal/js/teacherLogin.js +16 -0
  162. portal/static/portal/js/tenYearMap.js +14 -0
  163. portal/static/portal/sass/colorbox.scss +0 -1
  164. portal/static/portal/sass/modules/_colours.scss +1 -0
  165. portal/static/portal/sass/modules/_levels.scss +1 -1
  166. portal/static/portal/sass/modules/_mixins.scss +21 -0
  167. portal/static/portal/sass/partials/_banners.scss +4 -177
  168. portal/static/portal/sass/partials/_buttons.scss +12 -15
  169. portal/static/portal/sass/partials/_carousel.scss +129 -0
  170. portal/static/portal/sass/partials/_footer.scss +21 -22
  171. portal/static/portal/sass/partials/_forms.scss +60 -5
  172. portal/static/portal/sass/partials/_grids.scss +34 -61
  173. portal/static/portal/sass/partials/_header.scss +28 -20
  174. portal/static/portal/sass/partials/_images.scss +292 -39
  175. portal/static/portal/sass/partials/_popup.scss +18 -15
  176. portal/static/portal/sass/partials/_tables.scss +12 -20
  177. portal/static/portal/sass/partials/_text.scss +6 -10
  178. portal/static/portal/sass/styles.scss +0 -1
  179. portal/static/portal/video/code for life .pdf +0 -0
  180. portal/strings/about.py +5 -0
  181. portal/strings/coding_club.py +9 -0
  182. portal/strings/play.py +6 -5
  183. portal/strings/teach.py +1 -1
  184. portal/strings/teacher_resources.py +2 -8
  185. portal/strings/ten_year_map.py +13 -0
  186. portal/templates/403.html +2 -2
  187. portal/templates/404.html +1 -1
  188. portal/templates/500.html +2 -2
  189. portal/templates/{captcha → django_recaptcha}/includes/js_v2_invisible.html +3 -3
  190. portal/templates/{captcha → django_recaptcha}/widget_v2_invisible.html +2 -2
  191. portal/templates/email.html +4 -2
  192. portal/templates/maintenance.html +34 -0
  193. portal/templates/portal/about.html +94 -62
  194. portal/templates/portal/base.html +176 -152
  195. portal/templates/portal/coding_club.html +100 -0
  196. portal/templates/portal/contribute.html +56 -52
  197. portal/templates/portal/email_invitation_sent.html +1 -1
  198. portal/templates/portal/email_style_template.html +374 -0
  199. portal/templates/portal/email_verification_failed.html +1 -1
  200. portal/templates/portal/email_verification_needed.html +9 -9
  201. portal/templates/portal/form_shapes.html +20 -8
  202. portal/templates/portal/getinvolved.html +6 -6
  203. portal/templates/portal/home.html +35 -10
  204. portal/templates/portal/home_learning.html +19 -19
  205. portal/templates/portal/locked_out.html +0 -1
  206. portal/templates/portal/locked_out_school_student.html +16 -0
  207. portal/templates/portal/login/independent_student.html +31 -15
  208. portal/templates/portal/login/student.html +10 -7
  209. portal/templates/portal/login/student_class_code.html +7 -4
  210. portal/templates/portal/login/teacher.html +34 -17
  211. portal/templates/portal/partials/banner.html +18 -4
  212. portal/templates/portal/partials/benefits.html +1 -1
  213. portal/templates/portal/partials/card_list.html +34 -24
  214. portal/templates/portal/partials/character_list.html +5 -5
  215. portal/templates/portal/partials/cookie_list.html +161 -0
  216. portal/templates/portal/partials/delete_popup.html +18 -0
  217. portal/templates/portal/partials/footer.html +57 -26
  218. portal/templates/portal/partials/header.html +118 -117
  219. portal/templates/portal/partials/hero_card.html +4 -3
  220. portal/templates/portal/partials/info_popup.html +3 -3
  221. portal/templates/portal/partials/invite_admin_teacher.html +23 -0
  222. portal/templates/portal/partials/popup.html +7 -2
  223. portal/templates/portal/partials/register_newsletter_tickbox.html +2 -5
  224. portal/templates/portal/partials/screentime_popup.html +14 -0
  225. portal/templates/portal/partials/service_unavailable_popup.html +17 -0
  226. portal/templates/portal/partials/session_popup.html +19 -0
  227. portal/templates/portal/play/student_dashboard.html +42 -29
  228. portal/templates/portal/play/student_edit_account.html +64 -9
  229. portal/templates/portal/play.html +61 -41
  230. portal/templates/portal/privacy_notice.html +697 -0
  231. portal/templates/portal/register.html +122 -92
  232. portal/templates/portal/reset_password.html +20 -40
  233. portal/templates/portal/reset_password_confirm.html +9 -4
  234. portal/templates/portal/reset_password_email_sent.html +15 -13
  235. portal/templates/portal/teach/base_registering.html +1 -1
  236. portal/templates/portal/teach/class.html +4 -6
  237. portal/templates/portal/teach/dashboard.html +212 -117
  238. portal/templates/portal/teach/invited.html +90 -0
  239. portal/templates/portal/teach/onboarding_classes.html +5 -3
  240. portal/templates/portal/teach/onboarding_print.html +1 -1
  241. portal/templates/portal/teach/onboarding_school.html +26 -139
  242. portal/templates/portal/teach/onboarding_students.html +1 -1
  243. portal/templates/portal/teach/teacher_dismiss_students.html +73 -55
  244. portal/templates/portal/teach/teacher_edit_class.html +168 -11
  245. portal/templates/portal/teach/teacher_edit_student.html +12 -5
  246. portal/templates/portal/teach/teacher_move_all_classes.html +25 -38
  247. portal/templates/portal/teach/teacher_move_students_to_class.html +1 -1
  248. portal/templates/portal/teach.html +61 -42
  249. portal/templates/portal/ten_year_map.html +147 -0
  250. portal/templates/portal/terms.html +191 -42
  251. portal/templates/two_factor/core/login.html +71 -59
  252. portal/templates/two_factor/core/setup.html +58 -49
  253. portal/templates/two_factor/profile/disable.html +1 -1
  254. portal/templates/two_factor/profile/profile.html +35 -17
  255. portal/templatetags/app_tags.py +59 -84
  256. portal/templatetags/card_list_tags.py +0 -4
  257. portal/tests/base_test.py +14 -3
  258. portal/tests/conftest.py +0 -15
  259. portal/tests/migrations/test_migration_make_portaladmin_teacher.py +2 -6
  260. portal/tests/migrations/test_migration_preview_users.py +3 -9
  261. portal/tests/migrations/test_migration_remove_guardian.py +1 -3
  262. portal/tests/migrations/test_migration_use_common_models.py +2 -6
  263. portal/tests/migrations/test_migration_verify_portaladmin.py +1 -3
  264. portal/tests/pageObjects/portal/admin/admin_base_page.py +0 -21
  265. portal/tests/pageObjects/portal/base_page.py +16 -26
  266. portal/tests/pageObjects/portal/email_verification_needed_page.py +3 -2
  267. portal/tests/pageObjects/portal/game_page.py +12 -19
  268. portal/tests/pageObjects/portal/home_page.py +13 -15
  269. portal/tests/pageObjects/portal/independent_login_page.py +13 -17
  270. portal/tests/pageObjects/portal/password_reset_form_page.py +20 -4
  271. portal/tests/pageObjects/portal/password_reset_page.py +25 -0
  272. portal/tests/pageObjects/portal/play/account_page.py +18 -27
  273. portal/tests/pageObjects/portal/play/dashboard_page.py +4 -4
  274. portal/tests/pageObjects/portal/play/join_school_or_club_page.py +8 -10
  275. portal/tests/pageObjects/portal/play/play_base_page.py +5 -3
  276. portal/tests/pageObjects/portal/signup_page.py +28 -59
  277. portal/tests/pageObjects/portal/student_login_class_code.py +6 -9
  278. portal/tests/pageObjects/portal/student_login_page.py +6 -8
  279. portal/tests/pageObjects/portal/teach/add_independent_student_to_class_page.py +3 -3
  280. portal/tests/pageObjects/portal/teach/added_independent_student_to_class_page.py +3 -1
  281. portal/tests/pageObjects/portal/teach/class_page.py +36 -13
  282. portal/tests/pageObjects/portal/teach/dashboard_page.py +43 -84
  283. portal/tests/pageObjects/portal/teach/dismiss_students_page.py +7 -5
  284. portal/tests/pageObjects/portal/teach/edit_student_page.py +10 -8
  285. portal/tests/pageObjects/portal/teach/move_class_page.py +5 -10
  286. portal/tests/pageObjects/portal/teach/move_classes_page.py +4 -2
  287. portal/tests/pageObjects/portal/teach/move_students_disambiguate_page.py +4 -2
  288. portal/tests/pageObjects/portal/teach/move_students_page.py +6 -13
  289. portal/tests/pageObjects/portal/teach/onboarding_classes_page.py +5 -3
  290. portal/tests/pageObjects/portal/teach/onboarding_organisation_page.py +11 -49
  291. portal/tests/pageObjects/portal/teach/onboarding_student_list_page.py +7 -12
  292. portal/tests/pageObjects/portal/teach/onboarding_students_page.py +4 -27
  293. portal/tests/pageObjects/portal/teach/teach_base_page.py +6 -4
  294. portal/tests/pageObjects/portal/teacher_login_page.py +10 -16
  295. portal/tests/selenium_test_case.py +3 -43
  296. portal/tests/snapshots/snap_test_partials.py +11 -165
  297. portal/tests/test_2FA.py +15 -33
  298. portal/tests/test_admin.py +15 -97
  299. portal/tests/test_api.py +212 -73
  300. portal/tests/test_captcha_forms.py +2 -2
  301. portal/tests/test_class.py +374 -24
  302. portal/tests/test_emails.py +83 -20
  303. portal/tests/{test_newsletter_footer.py → test_global_forms.py} +5 -5
  304. portal/tests/test_helper_methods.py +30 -0
  305. portal/tests/test_independent_student.py +255 -144
  306. portal/tests/test_invite_teacher.py +318 -10
  307. portal/tests/test_middleware.py +138 -15
  308. portal/tests/test_organisation.py +78 -262
  309. portal/tests/test_partials.py +0 -88
  310. portal/tests/test_ratelimit.py +218 -36
  311. portal/tests/test_school_student.py +35 -40
  312. portal/tests/test_security.py +12 -31
  313. portal/tests/test_teacher.py +425 -325
  314. portal/tests/test_teacher_student.py +103 -91
  315. portal/tests/test_views.py +900 -76
  316. portal/tests/utils/classes.py +2 -2
  317. portal/tests/utils/messages.py +13 -28
  318. portal/urls.py +237 -164
  319. portal/views/admin.py +0 -332
  320. portal/views/api.py +82 -68
  321. portal/views/cron/__init__.py +1 -0
  322. portal/views/cron/user.py +322 -0
  323. portal/views/dotmailer.py +9 -1
  324. portal/views/email.py +33 -77
  325. portal/views/google_analytics.py +28 -0
  326. portal/views/home.py +126 -97
  327. portal/views/legal.py +13 -0
  328. portal/views/login/independent_student.py +5 -5
  329. portal/views/login/student.py +51 -14
  330. portal/views/login/teacher.py +2 -6
  331. portal/views/organisation.py +20 -189
  332. portal/views/registration.py +97 -17
  333. portal/views/student/edit_account_details.py +99 -72
  334. portal/views/student/play.py +81 -62
  335. portal/views/teacher/dashboard.py +421 -149
  336. portal/views/teacher/teach.py +226 -177
  337. portal/views/two_factor/__init__.py +0 -0
  338. portal/views/two_factor/core.py +28 -0
  339. portal/views/two_factor/form.py +7 -0
  340. portal/views/two_factor/profile.py +11 -0
  341. codeforlife_portal-5.32.2.dist-info/LICENSE.md +0 -577
  342. codeforlife_portal-5.32.2.dist-info/METADATA +0 -38
  343. deploy/permissions.py +0 -2
  344. example_project/manage.py +0 -10
  345. portal/autoconfig.py +0 -140
  346. portal/csp_config.py +0 -60
  347. portal/forms/add_game.py +0 -33
  348. portal/helpers/location.py +0 -121
  349. portal/static/portal/img/kurono_hero.jpg +0 -0
  350. portal/static/portal/img/kurono_landing_hero.png +0 -0
  351. portal/static/portal/img/kurono_logo.svg +0 -1
  352. portal/static/portal/img/kurono_logo_grey_background.svg +0 -1
  353. portal/static/portal/img/kurono_logo_mark.svg +0 -1
  354. portal/static/portal/img/kurono_resources_hero.jpg +0 -0
  355. portal/static/portal/img/kurono_story.png +0 -0
  356. portal/static/portal/img/ocado-swirl.svg +0 -22
  357. portal/static/portal/img/thumbnail_educate_kurono.png +0 -0
  358. portal/static/portal/img/thumbnail_educate_resources_and_progress_tracking.png +0 -0
  359. portal/static/portal/img/thumbnail_kurono_resources.png +0 -0
  360. portal/static/portal/img/thumbnail_play_kurono.png +0 -0
  361. portal/static/portal/img/x_close_video.png +0 -0
  362. portal/static/portal/js/aimmoGame.js +0 -106
  363. portal/static/portal/js/deleteWorkspaces.js +0 -14
  364. portal/static/portal/js/fuzzySchoolLookup.js +0 -46
  365. portal/static/portal/js/lib/jquery-3.5.1.min.js +0 -2
  366. portal/static/portal/js/lib/jquery-ui-1.12.1.min.js +0 -13
  367. portal/static/portal/sass/partials/_videos.scss +0 -10
  368. portal/static/portal/video/aimmo_play_now_background_video.mp4 +0 -0
  369. portal/strings/student_aimmo_dashboard.py +0 -6
  370. portal/templates/portal/admin/aggregated_data.html +0 -35
  371. portal/templates/portal/admin/map.html +0 -70
  372. portal/templates/portal/mouseflow.html +0 -9
  373. portal/templates/portal/partials/aimmo_games_table.html +0 -83
  374. portal/templates/portal/partials/register_over_required_age_tickbox.html +0 -9
  375. portal/templates/portal/play/independent_student_dashboard.html +0 -64
  376. portal/templates/portal/play/student_aimmo_dashboard.html +0 -63
  377. portal/templates/portal/privacy_policy.html +0 -483
  378. portal/templates/portal/reset_password_email.html +0 -9
  379. portal/templates/portal/teach/invite.html +0 -25
  380. portal/templates/portal/teach/teacher_aimmo_dashboard.html +0 -95
  381. portal/templates/portal/teach/teacher_resources.html +0 -68
  382. portal/templatetags/character_list_tags.py +0 -16
  383. portal/tests/pageObjects/portal/kurono_teacher_dashboard_page.py +0 -49
  384. portal/tests/pageObjects/portal/student_password_reset_form_page.py +0 -23
  385. portal/tests/pageObjects/portal/teach/onboarding_revoke_request_page.py +0 -20
  386. portal/tests/pageObjects/portal/teacher_password_reset_form_page.py +0 -23
  387. portal/tests/test_aimmo_dashboards.py +0 -172
  388. portal/tests/test_location.py +0 -217
  389. portal/tests/utils/aimmo_games.py +0 -30
  390. portal/views/aimmo/dashboard.py +0 -119
  391. portal/views/privacy_policy.py +0 -9
  392. portal/views/teacher/teacher_resources.py +0 -42
  393. {portal/views/aimmo → cfl_common}/__init__.py +0 -0
@@ -1,90 +1,70 @@
1
- {% load staticfiles %}
1
+ {% load static %}
2
2
  {% load app_tags %}
3
-
4
3
  {% load sekizai_tags %}
5
-
6
4
  <!DOCTYPE html>
7
5
  <html>
8
- <head>
9
- {% render_block "css" %}
10
-
11
- <title>{% block title %}Code for Life{% endblock %}</title>
12
- <meta name="msapplication-config" content="none"/>
13
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
14
-
15
- {% include "common/onetrust_cookies_consent_notice.html" %}
16
-
17
- {% block head %}
18
- {% endblock head %}
19
-
20
- {% block css %}
21
- <link href="{% static 'portal.css' %}" type="text/css" rel="stylesheet">
22
- <link rel="preconnect" href="https://fonts.googleapis.com">
23
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
24
- <link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet">
25
- <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500&display=swap" rel="stylesheet">
26
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
27
- <link rel="shortcut icon" href="{% static 'portal/img/favicon.ico' %}" type="image/x-icon">
28
- <link rel="icon" href="{% static 'portal/img/favicon.ico' %}" type="image/x-icon">
29
- {% endblock css %}
30
-
31
- {% include "portal/tag_manager/tag_manager_head.html" %}
32
-
33
- <script
34
- src="https://code.jquery.com/jquery-3.5.1.min.js"
35
- integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
36
- crossorigin="anonymous"></script>
37
- <script>window.jQuery || document.write('<script type="text/javascript" src="/static/portal/js/lib/jquery-3.5.1.min.js">\x3C/script>')</script>
38
- <script
39
- src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
40
- integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
41
- crossorigin="anonymous"></script>
42
- <script>window.jQuery.ui || document.write('<script type="text/javascript" src="/static/portal/js/lib/jquery-ui-1.12.1.min.js">\x3C/script>')</script>
43
- <script type="text/javascript" src="{% static 'portal/js/bootstrap.min.js' %}"></script>
44
- <script type="text/javascript" src="{% static 'portal/js/lib/modernizr-build.js' %}"></script>
45
- <script type="text/javascript" src="{% static 'portal/js/common.js' %}"></script>
46
- <script type="text/javascript" src="{% static 'portal/js/deleteWorkspaces.js' %}"></script>
47
- <script type="text/javascript" src="{% static 'portal/js/jquery.placeholder.js' %}"></script>
48
- <script type="text/javascript" src="{% static 'portal/js/lib/jquery.colorbox.js' %}"></script>
49
- <script type="text/javascript" src="{% static 'portal/js/lib/papaparse.min.js' %}"></script>
50
- <script type="text/javascript" src="{% static 'portal/js/sticky_subnav.js' %}"></script>
51
- <script src="https://code.iconify.design/2/2.0.3/iconify.min.js"
52
- integrity="sha256-pRhh6noOilGT8GyGitRuoRwdp5k1p8QJW2lvyGz4B9M="
53
- crossorigin="anonymous"></script>
54
- {% block check_user_status %}
55
- <script>
6
+ <head>
7
+ {% render_block "css" %}
8
+ <title>
9
+ {% block title %}Code for Life{% endblock %}
10
+ </title>
11
+ <meta name="msapplication-config" content="none"/>
12
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
13
+ <script type="text/javascript" src="{% static 'portal/js/lib/jquery.min.js' %}"></script>
14
+ {% include "common/onetrust_cookies_consent_notice.html" %}
15
+ {% block head %}
16
+ {% endblock head %}
17
+ {% block css %}
18
+ <link href="{% static 'portal/css/portal.css' %}" type="text/css" rel="stylesheet">
19
+ <link rel="preconnect" href="https://fonts.googleapis.com">
20
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
21
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined"
22
+ rel="stylesheet">
23
+ <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500&display=swap"
24
+ rel="stylesheet">
25
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
26
+ rel="stylesheet">
27
+ <link rel="shortcut icon"
28
+ href="{% static 'portal/img/favicon.ico' %}"
29
+ type="image/x-icon">
30
+ <link rel="icon"
31
+ href="{% static 'portal/img/favicon.ico' %}"
32
+ type="image/x-icon">
33
+ {% endblock css %}
34
+ {% include "portal/tag_manager/tag_manager_head.html" %}
35
+ <script type="text/javascript" src="{% static 'portal/js/lib/modernizr-build.js' %}"></script>
36
+ <script type="text/javascript" src="{% static 'portal/js/common.js' %}"></script>
37
+ <script type="text/javascript" src="{% static 'portal/js/jquery.placeholder.js' %}"></script>
38
+ <script type="text/javascript" src="{% static 'portal/js/lib/jquery.colorbox.js' %}"></script>
39
+ <script type="text/javascript" src="{% static 'portal/js/lib/papaparse.min.js' %}"></script>
40
+ <script type="text/javascript" src="{% static 'portal/js/sticky_subnav.js' %}"></script>
41
+ <script type="text/javascript" src="{% static 'portal/js/bootstrap.min.js' %}"></script>
42
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
43
+ <script src="https://code.iconify.design/2/2.0.3/iconify.min.js"
44
+ integrity="sha256-pRhh6noOilGT8GyGitRuoRwdp5k1p8QJW2lvyGz4B9M="
45
+ crossorigin="anonymous"></script>
46
+ {% block check_user_status %}
47
+ <script>
56
48
  // Set to 'TEACHER', 'SCHOOL_STUDENT', 'INDEPENDENT_STUDENT', or 'UNTRACKED'
57
49
  USER_STATUS = '{{ user|get_user_status }}';
58
50
  DEVELOPER = '{{ user|is_developer }}' === 'True';
59
51
  BETA = '{{ request|has_beta_access }}' === 'True';
60
- </script>
61
- {% endblock check_user_status %}
62
-
63
- {% block google_analytics %}
64
- {% if request|is_production %}
65
- <script>
66
- (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function() {
67
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
68
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
69
- })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
70
-
71
-
72
- ga('create', 'UA-49883146-1', 'auto');
73
- ga('send', 'pageview');
74
-
75
- function send_event(category_name, action, label_name) {
76
- ga('send', {
77
- hitType: 'event',
78
- eventCategory: category_name,
79
- eventAction: action,
80
- eventLabel: label_name
81
- });
82
- }
83
- </script>
84
-
85
- <script src="/static/portal/js/riveted.min.js"></script>
86
- <script>riveted.init();</script>
87
- <script>
52
+ </script>
53
+ {% endblock check_user_status %}
54
+ {% block google_analytics %}
55
+ {% if request|is_production %}
56
+ <!-- Google tag (gtag.js) -->
57
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-R81N6YZYT7"></script>
58
+ <script>
59
+ window.dataLayer = window.dataLayer || [];
60
+ function gtag(){dataLayer.push(arguments);}
61
+ gtag('js', new Date());
62
+
63
+ gtag('config', 'G-R81N6YZYT7');
64
+ </script>
65
+ <script src="/static/portal/js/riveted.min.js"></script>
66
+ <script>riveted.init();</script>
67
+ <script>
88
68
  function send_event(name_of_file, action){
89
69
  ga('send', {
90
70
  hitType: 'event',
@@ -93,81 +73,89 @@
93
73
  eventLabel: name_of_file
94
74
  });
95
75
  }
96
- </script>
97
- {% endif %}
98
- {% endblock google_analytics %}
99
- </head>
100
-
101
- <body id="top">
102
- {% include "portal/tag_manager/tag_manager_body.html" %}
103
- {% render_block "js" %}
104
- {% include 'portal/mouseflow.html' %}
105
-
106
- <div class="content-footer-wrapper">
107
- {% block contentWrapper %}
108
- <div {% block pageID %}id="contentWrapper"{% endblock %}>
109
- {% block topBar %}
110
- {% include 'portal/partials/header.html' %}
111
- {% endblock topBar %}
112
-
113
- {% block subNav %}
114
- {% endblock subNav %}
115
- <div id="messages">
116
- {% if messages %}
117
- <div class="sub-nav--message">
118
- {% for message in messages %}
119
- <div class="sub-nav {{ message.tags }}">
120
- <div class="container">
121
- <div class="row">
122
- <div class="d-flex col-sm-12 align-items-center">
123
- {% if 'error' in message.tags or 'warning' in message.tags %}
124
- <span class="material-icons-outlined md-32">error</span>
125
- {% else %}
126
- <span class="material-icons-outlined md-32">info</span>
127
- {% endif %}
128
- <p class="flex-grow-1">
129
- {% if 'safe' in message.tags %}{{ message|safe }}{% else %}{{ message }}{% endif %}
130
- </p>
131
- <a class="x-icon"><span class="sr-only">Close</span> <span class="iconify" data-icon="mdi:close"></span></a>
76
+ </script>
77
+ {% endif %}
78
+ {% endblock google_analytics %}
79
+ </head>
80
+ <body id="top">
81
+ {% include "portal/tag_manager/tag_manager_body.html" %}
82
+ {% render_block "js" %}
83
+ <div class="content-footer-wrapper">
84
+ {% block contentWrapper %}
85
+ <div {% block pageID %}id="contentWrapper"{% endblock %}>
86
+ {% block topBar %}
87
+ {% include 'portal/partials/header.html' %}
88
+ {% endblock topBar %}
89
+ {% block subNav %}
90
+ {% endblock subNav %}
91
+ <div id="messages">
92
+ {% if messages %}
93
+ <div class="sub-nav--message">
94
+ {% for message in messages %}
95
+ <div class="sub-nav {{ message.tags }}">
96
+ <div class="container">
97
+ <div class="row">
98
+ <div class="d-flex col-sm-12 align-items-center">
99
+ {% if 'error' in message.tags or 'warning' in message.tags %}
100
+ <span class="material-icons-outlined md-32">error</span>
101
+ {% else %}
102
+ <span class="material-icons-outlined md-32">info</span>
103
+ {% endif %}
104
+ <p class="flex-grow-1">
105
+ {% if 'safe' in message.tags %}
106
+ {{ message|safe }}
107
+ {% else %}
108
+ {{ message }}
109
+ {% endif %}
110
+ </p>
111
+ <a class="x-icon"><span class="sr-only">Close</span> <span class="iconify" data-icon="mdi:close"></span></a>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ {% endfor %}
132
117
  </div>
133
- </div>
118
+ {% endif %}
134
119
  </div>
135
- </div>
136
- {% endfor %}
137
- </div>
138
- {% endif %}
139
- </div>
140
- <!--[if lt IE 10]>
120
+ <!--[if lt IE 10]>
141
121
  <ul class="messages">
142
122
  <li class="error">You appear to be using an old version of Internet Explorer. You will be unable to play Rapid Router, unless you upgrade to Internet Explorer 10, or consider using another browser.</li>
143
123
  </ul>
144
- <![endif]-->
145
-
146
- {% block contentDiv %}
147
- <div class="content">
148
-
149
- {% block content %}
150
- {% block base_new_content %}{% endblock %}
151
- {% endblock content %}
152
-
124
+ <![endif]-->
125
+ {% block contentDiv %}
126
+ <div class="content">
127
+ {% block content %}
128
+ {% block base_new_content %}{% endblock %}
129
+ {% endblock content %}
130
+ </div>
131
+ {% endblock contentDiv %}
132
+ <div class="push"></div>
133
+ </div>
134
+ {% endblock contentWrapper %}
135
+ {% if request.session.screentime_warning_timeout %}
136
+ {% include "portal/partials/screentime_popup.html" %}
137
+ <script>setTimeout(showScreentimePopup, {{ request.session.screentime_warning_timeout }});</script>
138
+ {% endif %}
139
+ {% if request.session.last_request %}
140
+ {% include "portal/partials/session_popup.html" %}
141
+ <script>
142
+ // showing the popup after 28 minutes so it adds up to 30 minutes with the 2 minute countdown
143
+ setTimeout(showSessionPopup, 1680000);
144
+ </script>
145
+ {% endif %}
146
+ {% block footer %}
147
+ {% include 'portal/partials/footer.html' %}
148
+ {% endblock footer %}
153
149
  </div>
154
- {% endblock contentDiv %}
155
-
156
- <div class="push"></div>
157
- </div>
158
- {% endblock contentWrapper %}
159
-
160
- {% block footer %}
161
- {% include 'portal/partials/footer.html' %}
162
- {% endblock footer %}
163
- </div>
164
-
165
- <div id="confirmation-dialog" title=""></div>
166
-
167
- {% block scripts %}
168
- <script>
150
+ <div id="confirmation-dialog" title=""></div>
151
+ {% block scripts %}
152
+ <script>
169
153
  let bannerHeight;
170
154
 
155
+ // store current hash, then remove it so the page doesn't jump to the section
156
+ const currentHash = window.location.hash
157
+ window.location.hash = ''
158
+
171
159
  $(function() {
172
160
  $('input, textarea').placeholder();
173
161
  });
@@ -210,21 +198,57 @@
210
198
  });
211
199
  }
212
200
 
201
+ function updateLocationHash(hash) {
202
+ // using replaceState as changing hash directly will scroll to element
203
+ history.replaceState({}, '', hash)
204
+ }
205
+
213
206
  $(document).ready(function() {
214
207
  bannerHeight = $('.sticky-subnav').height();
215
208
  if(!bannerHeight) {
216
209
  bannerHeight = $('.menu').height() * 1.25
217
210
  }
218
211
  animateScroll(bannerHeight);
212
+
213
+ // select the tab based on the current location hash
214
+ const tabs = $('.sub-nav [data-toggle="tab"]')
215
+ const tabNames = tabs.map((index, element) => $(element).attr('href')).toArray()
216
+ const currentTabIndex = tabNames.indexOf(currentHash)
217
+ if (currentTabIndex < 0) {
218
+ updateLocationHash(tabNames[0])
219
+ }
220
+ else {
221
+ updateLocationHash(tabNames[currentTabIndex])
222
+ tabs[currentTabIndex].click()
223
+ animate($(tabNames[currentTabIndex]).offset().top - bannerHeight)
224
+ }
225
+
226
+ // make each tab update the current location hash on click
227
+ tabs.on('shown.bs.tab', (event) => {
228
+ updateLocationHash(event.target.hash)
229
+ window.scrollTo(0, 0)
230
+ })
219
231
  });
220
- </script>
221
- {% include "common/freshdesk_widget.html" %}
222
- <script>
232
+ </script>
233
+ {% include "common/freshdesk_widget.html" %}
234
+ <script>
223
235
  FreshworksWidget('hide');
224
236
  $('.freshdesk__contact-us').on('click', function() {
225
237
  FreshworksWidget('open');
226
238
  });
227
- </script>
228
- {% endblock scripts %}
229
- </body>
239
+ </script>
240
+ <script>
241
+ // disable newsletter signup button by default
242
+ const newsletterSubmitButton = $('#submit_newsletter');
243
+ newsletterSubmitButton.addClass("disabled");
244
+ newsletterSubmitButton.prop("disabled", true);
245
+
246
+ // enable them or disable it depending on age verification checkbox
247
+ $('#id_age_verification').on("click", function() {
248
+ newsletterSubmitButton.prop("disabled", !this.checked);
249
+ newsletterSubmitButton.toggleClass("disabled", !this.checked);
250
+ });
251
+ </script>
252
+ {% endblock scripts %}
253
+ </body>
230
254
  </html>
@@ -0,0 +1,100 @@
1
+ {% extends 'portal/base.html' %}
2
+ {% load static %}
3
+ {% load app_tags %}
4
+ {% load banner_tags %}
5
+
6
+ {% block content %}
7
+
8
+
9
+ {% banner banner_name="BANNER" %}
10
+
11
+
12
+ <div class="background container">
13
+ <section>
14
+ <h4>Who are the club packs aimed at?</h4>
15
+ </section>
16
+ <div class="row">
17
+ <div class="col-sm-12">
18
+ <p>
19
+ The FREE resource packs are aimed at two different groups, the first is aimed at students ages
20
+ between 7-11yrs with an interest in learning Python. The second pack is aimed at students 12yrs
21
+ and up, including adults. This moves at a much faster pace and also introduces students to
22
+ setting up an environment on their own computer.
23
+ </p>
24
+ <p>
25
+ Both packs are a condensed learning pathway using our game Rapid Router alongside suggested
26
+ session plan and slides.
27
+ </p>
28
+ </div>
29
+ </div>
30
+ </div>
31
+
32
+ <div class="background background--primary">
33
+ <div class="container">
34
+ <div class="row d-flex">
35
+ <div class="col-sm-6 d-flex flex-column">
36
+ <div class="flex-grow-1">
37
+ <h4 class="mt-0">Primary coding club</h4>
38
+ <p>
39
+ Download your FREE coding club pack for students aged 7-11. This pack introduces
40
+ students to the first principles of Python at a faster pace than the regular lesson
41
+ plans. It is aimed at students already interested in learning coding and can be used in clubs,
42
+ at home or in school, on or offline.
43
+ </div>
44
+ <div>
45
+ {% if user|is_logged_in_as_teacher %}
46
+ <a id="primary_pack" target="_blank" type="submit" class="button button--primary button--icon" href="https://code-for-life.gitbook.io/teaching-resources/code-club-resources-primary/">
47
+ Get started with our Primary coding club pack<span class="iconify" data-icon="mdi:open-in-new"></span>
48
+ </a>
49
+ {% else %}
50
+ <a id="primary_pack" target="_blank" type="submit" class="button button--primary button--icon" href="https://code-for-life.gitbook.io/code-for-life-primary-club-resources">
51
+ View Primary coding club pack<span class="iconify" data-icon="mdi:open-in-new"></span>
52
+ </a>
53
+ {% endif %}
54
+ </div>
55
+ </div>
56
+ <div class="col-sm-6 d-flex flex-column">
57
+ <div class="flex-grow-1">
58
+ <img title="Primary coding club" alt="Primary coding club" src="{% static 'portal/img/about_us_cfl.jpg' %}">
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+
66
+ <div class="background">
67
+ <div class="container">
68
+ <div class="row d-flex">
69
+ <div class="col-sm-6 d-flex flex-column">
70
+ <div class="flex-grow-1">
71
+ <img title="Python coding club" alt="Python coding club" src="{% static 'portal/img/coding_club_python_pack.png' %}">
72
+ </div>
73
+ </div>
74
+ <div class="col-sm-6 d-flex flex-column">
75
+ <div class="flex-grow-1">
76
+ <h4 class="mt-0">Python coding club</h4>
77
+ <p>
78
+ Download your FREE coding club pack for students aged 12 and above.
79
+ This pack is a fast-paced introduction to Python. It is aimed at students already interested
80
+ in learning coding, individuals looking to learn and run their own club, or adults wanting to
81
+ try coding out. It is designed to be used in face-to-face or online clubs.
82
+ </p>
83
+ </div>
84
+ <div>
85
+ {% if user|is_logged_in_as_teacher %}
86
+ <a id="python_pack" target="_blank" type="submit" class="button button--primary button--icon" href="https://code-for-life.gitbook.io/teaching-resources/rapid-introduction-to-python-code-club">
87
+ Get started with our Python coding club packs<span class="iconify" data-icon="mdi:open-in-new"></span>
88
+ </a>
89
+ {% else %}
90
+ <a id="python_pack" target="_blank" type="submit" class="button button--primary button--icon" href="https://code-for-life.gitbook.io/code-for-life-python-club-resources">
91
+ View Python coding club packs<span class="iconify" data-icon="mdi:open-in-new"></span>
92
+ </a>
93
+ {% endif %}
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </div>
99
+
100
+ {% endblock content %}
@@ -1,5 +1,5 @@
1
1
  {% extends 'portal/base.html' %}
2
- {% load staticfiles %}
2
+ {% load static %}
3
3
  {% load app_tags %}
4
4
  {% load banner_tags %}
5
5
 
@@ -10,60 +10,60 @@
10
10
  {% block content %}
11
11
  <div class="background container">
12
12
  <section>
13
- <h4>How to get involved and gain experience</h4>
13
+ <h3>How to get involved and gain experience</h3>
14
14
  </section>
15
- <div class="row">
16
- <div class="col-sm-6">
17
- <p>Code for Life would not have been possible without the dedication of our volunteers.
18
- </p>
19
- <p>In 2014, computing was added to the UK curriculum, requiring schools to teach coding
20
- principles and programming foundations.
21
- </p>
22
- </div>
23
- <div class="col-sm-6">
24
- <p>Recognising a need to support teachers and students in navigating the uncharted territory,
25
- Ocado Technology deployed an army of internal volunteers who worked after hours, fuelled by
26
- free pizzas and fizzy drinks.
27
- </p>
28
- <p>What came out of this, is what you see today, used by educators and learners from over 150
29
- countries. Our products are open-source and free forever.
30
- </p>
31
- </div>
15
+ <div class="row">
16
+ <div class="col-sm-6">
17
+ <p>Code for Life would not have been possible without the dedication
18
+ of our volunteers.</p>
19
+ <p>In 2014, computing was added to the UK curriculum, requiring
20
+ schools to teach coding principles and programming foundations.</p>
32
21
  </div>
33
- <div class="text-right">
34
- <a href="https://docs.codeforlife.education/" target="_blank" class="button button--primary button-right-arrow">
35
- Read our developer guide
36
- </a>
22
+ <div class="col-sm-6">
23
+ <p>Recognising a need to support teachers and students in navigating
24
+ the uncharted territory, Ocado Technology deployed an army of
25
+ internal volunteers who worked after hours, fuelled by free
26
+ pizzas and fizzy drinks.</p>
27
+ <p>What came out of this, is what you see today, used by educators
28
+ and learners from over 180 countries. Our products are
29
+ open-source and free forever.</p>
37
30
  </div>
38
31
  </div>
32
+ <div class="text-right">
33
+ <a href="https://docs.codeforlife.education/" target="_blank"
34
+ class="button button--primary button-right-arrow">
35
+ Read our developer guide
36
+ </a>
37
+ </div>
39
38
  </div>
40
39
 
41
40
  <div class="background background--primary">
42
- <div class="row">
43
- <div class="container d-flex flex-row">
44
- <div class="col-sm-6">
41
+ <div class="container">
42
+ <div class="row d-flex flex-column-reverse flex-md-row">
43
+ <div class="col-12 col-md-6 order-1 order-md-0">
45
44
  <h4>Our products</h4>
46
45
 
47
- <p><b>The portal or website</b></p>
48
- <p>This is the gateway for users to get to know who we are and what we do.
49
- It hosts our web-based games and plenty of teaching resources.
50
- </p>
46
+ <p><b>The website</b></p>
47
+ <p>This is the gateway for users to get to know who we are and
48
+ what we do. It hosts our web-based games and plenty of
49
+ teaching resources, and the teacher dashboard for class
50
+ management.</p>
51
51
 
52
52
  <p><b>Rapid Router</b></p>
53
- <p>An introduction to coding that is aimed at Key Stages 1-3 (age 5 to 14).
54
- Built on Blockly, it's a visual programming language similar to Scratch.
55
- The levels start off with Blockly and gradually progress to Python. With 109 levels,
56
- Rapid Router is our flagship game with the biggest user base.
57
- </p>
53
+ <p>An introduction to coding that is aimed at ages 5 to 14.
54
+ Built on Blockly, it's a visual programming language similar
55
+ to Scratch. Rapid Router is our flagship game with the
56
+ biggest user base.</p>
58
57
 
59
- <p><b>Kurono</b></p>
60
- <p>A multiplayer game that is aimed at older students of Key Stages 3 and up,
61
- it is primarily for use in a class or a club setting. Students code in Python to
62
- move their avatar around in order to complete tasks. Parts of Kurono are still in development.
63
- </p>
58
+ <p><b>Python Den</b></p>
59
+ <p>Our new Python Den uses Blockly, Blockly/Python split
60
+ screen, and an IDE. It takes students from no previous
61
+ Python experience to a foundation in Python, helping
62
+ prepare them for GCSE and beyond.</p>
64
63
  </div>
65
- <div class="col-sm-6">
66
- <img title="Rapid Router" alt="Rapid Router" src="{% static 'portal/img/rapidrouter.png' %}">
64
+ <div class="col-12 col-md-6 order-0 order-md-1">
65
+ <img title="Rapid Router" alt="Rapid Router"
66
+ src="{% static 'portal/img/rapidrouter.png' %}" class="img-fluid">
67
67
  </div>
68
68
  </div>
69
69
  </div>
@@ -72,20 +72,24 @@
72
72
  <div class="background container">
73
73
  <div class="row">
74
74
  <div class="col-sm-6 bg-image">
75
- <img title="Gitbook" alt="Gitbook" src="{% static 'portal/img/gitbook.png' %}" class="img-border">
75
+ <img title="Gitbook" alt="Gitbook"
76
+ src="{% static 'portal/img/gitbook.png' %}" class="img-border">
76
77
  </div>
77
78
  <div class="col-sm-6">
78
79
  <h4>How you can contribute</h4>
79
- <p>Today, there is a small dedicated team working full time on Code for Life.
80
- In 2021, we're expecting to reach over 100,000 newly registered teachers and students.
81
- We need your help to do even more.
82
- </p>
83
- <p>
84
- If contributing to open-source projects to support education in coding and technology
85
- sounds exciting for you, we'd love to have you on board!
86
- </p>
80
+ <p>Today, there is a small dedicated team working full-time on Code
81
+ for Life. Our community, made up of dedicated teachers, tutors,
82
+ students, and volunteers, has played a vital part in Code For
83
+ Life's growth. The resources and games are aligned to the UK
84
+ National Curriculum and have reached over 260,000 active users
85
+ across 180 countries, and over 660,000 users since the launch in
86
+ 2014. We need your help to grow even more.</p>
87
+ <p>If contributing to open-source projects to support education in
88
+ coding and technology sounds exciting for you, we'd love to have
89
+ you on board!</p>
87
90
  <div class="text-right">
88
- <a href="https://docs.codeforlife.education/" target="_blank" class="button button--primary button-right-arrow">
91
+ <a href="https://docs.codeforlife.education/" target="_blank"
92
+ class="button button--primary button-right-arrow">
89
93
  Read our developer guide
90
94
  </a>
91
95
  </div>
@@ -1,5 +1,5 @@
1
1
  {% extends 'portal/base.html' %}
2
- {% load staticfiles %}
2
+ {% load static %}
3
3
  {% load app_tags %}
4
4
 
5
5
  {% block content %}