We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[UI idea] Improve pre-join class UI
**Idea incl level**
Currently the pre-join page of a class is nothing more than plain-text with a link. It would be nice to improve the UI a bit to better align with the rest of the Hedy website. See the screenshot below for the current situation:

![Schermafbeelding 2022-01-24 om 13 22 28](https://user-images.githubusercontent.com/38155424/150782347-2c230948-6284-4396-bf97-a9d9b5ebc32b.png)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `website/teacher.py`
Content:
```
1 import json
2 
3 from website.auth import requires_login, is_teacher, current_user
4 import utils
5 import uuid
6 from flask import g, request, jsonify, redirect
7 from flask_helpers import render_template
8 import os
9 import hedyweb
10 import hedy_content
11 TRANSLATIONS = hedyweb.Translations ()
12 from config import config
13 cookie_name     = config ['session'] ['cookie_name']
14 
15 
16 def routes (app, database, achievements):
17     global DATABASE
18     global ACHIEVEMENTS
19     DATABASE = database
20     ACHIEVEMENTS = achievements
21 
22     @app.route('/classes', methods=['GET'])
23     @requires_login
24     def get_classes (user):
25         if not is_teacher(user):
26             return utils.error_page_403(error=403, ui_message='retrieve_class')
27         return jsonify (DATABASE.get_teacher_classes (user ['username'], True))
28 
29     @app.route('/for-teachers/class/<class_id>', methods=['GET'])
30     @requires_login
31     def get_class (user, class_id):
32         app.logger.info('This is info output')
33         if not is_teacher(user):
34             return utils.error_page_403(error=403, ui_message='retrieve_class')
35         Class = DATABASE.get_class (class_id)
36         if not Class or Class ['teacher'] != user ['username']:
37             return utils.error_page(error=404,  ui_message='no_such_class')
38         students = []
39         for student_username in Class.get ('students', []):
40             student = DATABASE.user_by_username (student_username)
41             programs = DATABASE.programs_for_user(student_username)
42             highest_level = max(program['level'] for program in programs) if len(programs) else 0
43             sorted_public_programs = list(sorted([program for program in programs if program.get ('public')], key=lambda p: p['date']))
44             if sorted_public_programs:
45                 latest_shared = sorted_public_programs[-1]
46                 latest_shared['link'] = f"/hedy/{latest_shared['id']}/view"
47             else:
48                 latest_shared = None
49             students.append ({'username': student_username, 'last_login': utils.datetotimeordate (utils.mstoisostring (student ['last_login'])), 'programs': len (programs), 'highest_level': highest_level, 'latest_shared': latest_shared})
50 
51         if utils.is_testing_request (request):
52             return jsonify ({'students': students, 'link': Class ['link'], 'name': Class ['name'], 'id': Class ['id']})
53 
54         achievement = None
55         if len(students) > 20:
56             achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "full_house")
57         if achievement:
58             achievement = json.dumps(achievement)
59 
60         teachers = os.getenv('BETA_TEACHERS', '').split(',')
61         is_beta_teacher = user['username'] in teachers
62 
63         return render_template ('class-overview.html', current_page='my-profile',
64                                 page_title=hedyweb.get_page_title('class overview'),
65                                 achievement=achievement,
66                                 is_beta_teacher=is_beta_teacher,
67                                 class_info={'students': students, 'link': os.getenv('BASE_URL') + '/hedy/l/' + Class ['link'],
68                                             'name': Class ['name'], 'id': Class ['id']})
69 
70     @app.route('/class', methods=['POST'])
71     @requires_login
72     def create_class (user):
73         if not is_teacher(user):
74             return 'Only teachers can create classes', 403
75 
76         body = request.json
77         # Validations
78         if not isinstance(body, dict):
79             return 'body must be an object', 400
80         if not isinstance(body.get('name'), str):
81             return 'name must be a string', 400
82 
83         # We use this extra call to verify if the class name doesn't already exist, if so it's a duplicate
84         Classes = DATABASE.get_teacher_classes(user['username'], True)
85         for Class in Classes:
86             if Class['name'] == body['name']:
87                 return "duplicate", 200
88 
89         Class = {
90             'id': uuid.uuid4().hex,
91             'date': utils.timems (),
92             'teacher': user ['username'],
93             'link': utils.random_id_generator (7),
94             'name': body ['name']
95         }
96 
97         DATABASE.store_class (Class)
98         achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "ready_set_education")
99         if achievement:
100             return {'id': Class['id'], 'achievement': achievement}, 200
101         return {'id': Class['id']}, 200
102 
103     @app.route('/class/<class_id>', methods=['PUT'])
104     @requires_login
105     def update_class (user, class_id):
106         if not is_teacher(user):
107             return 'Only teachers can update classes', 403
108 
109         body = request.json
110         # Validations
111         if not isinstance(body, dict):
112             return 'body must be an object', 400
113         if not isinstance(body.get('name'), str):
114             return 'name must be a string', 400
115 
116         Class = DATABASE.get_class (class_id)
117         if not Class or Class ['teacher'] != user ['username']:
118             return 'No such class', 404
119 
120         # We use this extra call to verify if the class name doesn't already exist, if so it's a duplicate
121         Classes = DATABASE.get_teacher_classes(user ['username'], True)
122         for Class in Classes:
123             if Class['name'] == body['name']:
124                 return "duplicate", 200
125 
126         Class = DATABASE.update_class (class_id, body ['name'])
127         achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "on_second_thoughts")
128         if achievement:
129             return {'achievement': achievement}, 200
130         return {}, 200
131 
132     @app.route('/class/<class_id>', methods=['DELETE'])
133     @requires_login
134     def delete_class (user, class_id):
135         Class = DATABASE.get_class (class_id)
136         if not Class or Class ['teacher'] != user ['username']:
137             return 'No such class', 404
138 
139         DATABASE.delete_class (Class)
140         achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "end_of_semester")
141         if achievement:
142             return {'achievement': achievement}, 200
143         return {}, 200
144 
145     @app.route('/class/<class_id>/prejoin/<link>', methods=['GET'])
146     def prejoin_class (class_id, link):
147         Class = DATABASE.get_class (class_id)
148         if not Class or Class ['link'] != link:
149             return utils.error_page(error=404,  ui_message='invalid_class_link')
150         user = {}
151         if request.cookies.get (cookie_name):
152             token = DATABASE.get_token(request.cookies.get (cookie_name))
153             if token:
154                 if token ['username'] in Class.get ('students', []):
155                     return render_template ('class-already-joined.html', page_title=hedyweb.get_page_title('join class'),
156                                             current_page='my-profile', class_info={'name': Class ['name']})
157                 user = DATABASE.user_by_username(token ['username'])
158 
159         return render_template ('class-prejoin.html', page_title=hedyweb.get_page_title('join class'),
160             current_page='my-profile',
161             class_info={
162                 'id': Class ['id'],
163                 'name': Class ['name'],
164             })
165 
166     @app.route('/class/join', methods=['POST'])
167     @requires_login
168     def join_class(user):
169         body = request.json
170         if 'id' in body:
171             Class = DATABASE.get_class(body['id'])
172         if not Class or Class ['id'] != body['id']:
173             return utils.error_page(error=404,  ui_message='invalid_class_link')
174 
175         DATABASE.add_student_to_class(Class['id'], user['username'])
176         achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "epic_education")
177         if achievement:
178             return {'achievement': achievement}, 200
179         return {}, 200
180 
181     @app.route('/class/<class_id>/student/<student_id>', methods=['DELETE'])
182     @requires_login
183     def leave_class (user, class_id, student_id):
184         Class = DATABASE.get_class (class_id)
185         if not Class or Class ['teacher'] != user ['username'] or student_id != user ['username']:
186             return 'No such class', 404
187 
188         DATABASE.remove_student_from_class (Class ['id'], student_id)
189         if Class['teacher'] == user['username']:
190             achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "detention")
191         if achievement:
192             return {'achievement': achievement}, 200
193         return {}, 200
194 
195     @app.route('/for-teachers/customize-class/<class_id>', methods=['GET'])
196     @requires_login
197     def get_class_info(user, class_id):
198         if not is_teacher(user):
199             return utils.error_page_403(error=403, ui_message='retrieve_class')
200         Class = DATABASE.get_class(class_id)
201         if not Class or Class['teacher'] != user['username']:
202             return utils.error_page(error=404,  ui_message='no_such_class')
203 
204         if hedy_content.Adventures(g.lang).has_adventures():
205             adventures = hedy_content.Adventures(g.lang).get_adventure_keyname_name_levels()
206         else:
207             adventures = hedy_content.Adventures("en").get_adventure_keyname_name_levels()
208         levels = hedy_content.LevelDefaults(g.lang).levels
209         preferences = DATABASE.get_customizations_class(class_id)
210 
211         return render_template('customize-class.html', page_title=hedyweb.get_page_title('customize class'),
212                                class_info={'name': Class['name'], 'id': Class['id']}, levels=levels,
213                                adventures=adventures, preferences=preferences, current_page='my-profile')
214 
215     @app.route('/customize-class/<class_id>', methods=['PUT'])
216     @requires_login
217     def update_level_preferences(user, class_id):
218         if not is_teacher(user):
219             return 'Only teachers can update class preferences', 403
220 
221         body = request.json
222         print(body)
223         # Validations
224         if not isinstance(body, dict):
225             return 'body must be an object', 400
226         if not isinstance(body.get('example_programs'), bool):
227             return 'amount of example programs must be an integer', 400
228         if not isinstance(body.get('hide_level'), bool):
229             return 'level switch must be a boolean', 400
230         if not isinstance(body.get('hide_prev_level'), bool):
231             return 'level switch must be a boolean', 400
232         if not isinstance(body.get('hide_next_level'), bool):
233             return 'level switch must be a boolean', 400
234         if not isinstance(int(body.get('level')), int):
235             return 'level must ben an integer', 400
236 
237         Class = DATABASE.get_class(class_id)
238         if not Class or Class['teacher'] != user['username']:
239             return 'No such class', 404
240 
241         customizations = {}
242         customizations['id'] = class_id
243         customizations['level'] = int(body.get('level'))
244         customizations['adventures'] = body.get('adventures')
245         customizations['example_programs'] = body.get('example_programs')
246         customizations['hide'] = body.get('hide_level')
247         customizations['hide_prev_level'] = body.get('hide_prev_level')
248         customizations['hide_next_level'] = body.get('hide_next_level')
249 
250         DATABASE.update_customizations_class(customizations)
251         achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "my_class_my_rules")
252         if achievement:
253             return {'achievement': achievement}, 200
254         return {}, 200
255 
256     @app.route('/hedy/l/<link_id>', methods=['GET'])
257     def resolve_class_link (link_id):
258         Class = DATABASE.resolve_class_link (link_id)
259         if not Class:
260             return utils.error_page(error=404,  ui_message='invalid_class_link')
261         return redirect(request.url.replace('/hedy/l/' + link_id, '/class/' + Class ['id'] + '/prejoin/' + link_id), code=302)
262
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/website/teacher.py b/website/teacher.py
--- a/website/teacher.py
+++ b/website/teacher.py
@@ -152,16 +152,18 @@
             token = DATABASE.get_token(request.cookies.get (cookie_name))
             if token:
                 if token ['username'] in Class.get ('students', []):
-                    return render_template ('class-already-joined.html', page_title=hedyweb.get_page_title('join class'),
+                    return render_template ('class-prejoin.html', joined=True,
+                                            page_title=hedyweb.get_page_title('join class'),
                                             current_page='my-profile', class_info={'name': Class ['name']})
                 user = DATABASE.user_by_username(token ['username'])
 
-        return render_template ('class-prejoin.html', page_title=hedyweb.get_page_title('join class'),
-            current_page='my-profile',
-            class_info={
-                'id': Class ['id'],
-                'name': Class ['name'],
-            })
+        return render_template ('class-prejoin.html', joined=False,
+                                page_title=hedyweb.get_page_title('join class'),
+                                current_page='my-profile',
+                                class_info={
+                                    'id': Class ['id'],
+                                    'name': Class ['name'],
+                                })
 
     @app.route('/class/join', methods=['POST'])
     @requires_login

{"golden_diff": "diff --git a/website/teacher.py b/website/teacher.py\n--- a/website/teacher.py\n+++ b/website/teacher.py\n@@ -152,16 +152,18 @@\n             token = DATABASE.get_token(request.cookies.get (cookie_name))\n             if token:\n                 if token ['username'] in Class.get ('students', []):\n-                    return render_template ('class-already-joined.html', page_title=hedyweb.get_page_title('join class'),\n+                    return render_template ('class-prejoin.html', joined=True,\n+                                            page_title=hedyweb.get_page_title('join class'),\n                                             current_page='my-profile', class_info={'name': Class ['name']})\n                 user = DATABASE.user_by_username(token ['username'])\n \n-        return render_template ('class-prejoin.html', page_title=hedyweb.get_page_title('join class'),\n-            current_page='my-profile',\n-            class_info={\n-                'id': Class ['id'],\n-                'name': Class ['name'],\n-            })\n+        return render_template ('class-prejoin.html', joined=False,\n+                                page_title=hedyweb.get_page_title('join class'),\n+                                current_page='my-profile',\n+                                class_info={\n+                                    'id': Class ['id'],\n+                                    'name': Class ['name'],\n+                                })\n \n     @app.route('/class/join', methods=['POST'])\n     @requires_login\n", "issue": "[UI idea] Improve pre-join class UI\n**Idea incl level**\r\nCurrently the pre-join page of a class is nothing more than plain-text with a link. It would be nice to improve the UI a bit to better align with the rest of the Hedy website. See the screenshot below for the current situation:\r\n\r\n![Schermafbeelding 2022-01-24 om 13 22 28](https://user-images.githubusercontent.com/38155424/150782347-2c230948-6284-4396-bf97-a9d9b5ebc32b.png)\n", "before_files": [{"content": "import json\n\nfrom website.auth import requires_login, is_teacher, current_user\nimport utils\nimport uuid\nfrom flask import g, request, jsonify, redirect\nfrom flask_helpers import render_template\nimport os\nimport hedyweb\nimport hedy_content\nTRANSLATIONS = hedyweb.Translations ()\nfrom config import config\ncookie_name     = config ['session'] ['cookie_name']\n\n\ndef routes (app, database, achievements):\n    global DATABASE\n    global ACHIEVEMENTS\n    DATABASE = database\n    ACHIEVEMENTS = achievements\n\n    @app.route('/classes', methods=['GET'])\n    @requires_login\n    def get_classes (user):\n        if not is_teacher(user):\n            return utils.error_page_403(error=403, ui_message='retrieve_class')\n        return jsonify (DATABASE.get_teacher_classes (user ['username'], True))\n\n    @app.route('/for-teachers/class/<class_id>', methods=['GET'])\n    @requires_login\n    def get_class (user, class_id):\n        app.logger.info('This is info output')\n        if not is_teacher(user):\n            return utils.error_page_403(error=403, ui_message='retrieve_class')\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['teacher'] != user ['username']:\n            return utils.error_page(error=404,  ui_message='no_such_class')\n        students = []\n        for student_username in Class.get ('students', []):\n            student = DATABASE.user_by_username (student_username)\n            programs = DATABASE.programs_for_user(student_username)\n            highest_level = max(program['level'] for program in programs) if len(programs) else 0\n            sorted_public_programs = list(sorted([program for program in programs if program.get ('public')], key=lambda p: p['date']))\n            if sorted_public_programs:\n                latest_shared = sorted_public_programs[-1]\n                latest_shared['link'] = f\"/hedy/{latest_shared['id']}/view\"\n            else:\n                latest_shared = None\n            students.append ({'username': student_username, 'last_login': utils.datetotimeordate (utils.mstoisostring (student ['last_login'])), 'programs': len (programs), 'highest_level': highest_level, 'latest_shared': latest_shared})\n\n        if utils.is_testing_request (request):\n            return jsonify ({'students': students, 'link': Class ['link'], 'name': Class ['name'], 'id': Class ['id']})\n\n        achievement = None\n        if len(students) > 20:\n            achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"full_house\")\n        if achievement:\n            achievement = json.dumps(achievement)\n\n        teachers = os.getenv('BETA_TEACHERS', '').split(',')\n        is_beta_teacher = user['username'] in teachers\n\n        return render_template ('class-overview.html', current_page='my-profile',\n                                page_title=hedyweb.get_page_title('class overview'),\n                                achievement=achievement,\n                                is_beta_teacher=is_beta_teacher,\n                                class_info={'students': students, 'link': os.getenv('BASE_URL') + '/hedy/l/' + Class ['link'],\n                                            'name': Class ['name'], 'id': Class ['id']})\n\n    @app.route('/class', methods=['POST'])\n    @requires_login\n    def create_class (user):\n        if not is_teacher(user):\n            return 'Only teachers can create classes', 403\n\n        body = request.json\n        # Validations\n        if not isinstance(body, dict):\n            return 'body must be an object', 400\n        if not isinstance(body.get('name'), str):\n            return 'name must be a string', 400\n\n        # We use this extra call to verify if the class name doesn't already exist, if so it's a duplicate\n        Classes = DATABASE.get_teacher_classes(user['username'], True)\n        for Class in Classes:\n            if Class['name'] == body['name']:\n                return \"duplicate\", 200\n\n        Class = {\n            'id': uuid.uuid4().hex,\n            'date': utils.timems (),\n            'teacher': user ['username'],\n            'link': utils.random_id_generator (7),\n            'name': body ['name']\n        }\n\n        DATABASE.store_class (Class)\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"ready_set_education\")\n        if achievement:\n            return {'id': Class['id'], 'achievement': achievement}, 200\n        return {'id': Class['id']}, 200\n\n    @app.route('/class/<class_id>', methods=['PUT'])\n    @requires_login\n    def update_class (user, class_id):\n        if not is_teacher(user):\n            return 'Only teachers can update classes', 403\n\n        body = request.json\n        # Validations\n        if not isinstance(body, dict):\n            return 'body must be an object', 400\n        if not isinstance(body.get('name'), str):\n            return 'name must be a string', 400\n\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['teacher'] != user ['username']:\n            return 'No such class', 404\n\n        # We use this extra call to verify if the class name doesn't already exist, if so it's a duplicate\n        Classes = DATABASE.get_teacher_classes(user ['username'], True)\n        for Class in Classes:\n            if Class['name'] == body['name']:\n                return \"duplicate\", 200\n\n        Class = DATABASE.update_class (class_id, body ['name'])\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"on_second_thoughts\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/class/<class_id>', methods=['DELETE'])\n    @requires_login\n    def delete_class (user, class_id):\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['teacher'] != user ['username']:\n            return 'No such class', 404\n\n        DATABASE.delete_class (Class)\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"end_of_semester\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/class/<class_id>/prejoin/<link>', methods=['GET'])\n    def prejoin_class (class_id, link):\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['link'] != link:\n            return utils.error_page(error=404,  ui_message='invalid_class_link')\n        user = {}\n        if request.cookies.get (cookie_name):\n            token = DATABASE.get_token(request.cookies.get (cookie_name))\n            if token:\n                if token ['username'] in Class.get ('students', []):\n                    return render_template ('class-already-joined.html', page_title=hedyweb.get_page_title('join class'),\n                                            current_page='my-profile', class_info={'name': Class ['name']})\n                user = DATABASE.user_by_username(token ['username'])\n\n        return render_template ('class-prejoin.html', page_title=hedyweb.get_page_title('join class'),\n            current_page='my-profile',\n            class_info={\n                'id': Class ['id'],\n                'name': Class ['name'],\n            })\n\n    @app.route('/class/join', methods=['POST'])\n    @requires_login\n    def join_class(user):\n        body = request.json\n        if 'id' in body:\n            Class = DATABASE.get_class(body['id'])\n        if not Class or Class ['id'] != body['id']:\n            return utils.error_page(error=404,  ui_message='invalid_class_link')\n\n        DATABASE.add_student_to_class(Class['id'], user['username'])\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"epic_education\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/class/<class_id>/student/<student_id>', methods=['DELETE'])\n    @requires_login\n    def leave_class (user, class_id, student_id):\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['teacher'] != user ['username'] or student_id != user ['username']:\n            return 'No such class', 404\n\n        DATABASE.remove_student_from_class (Class ['id'], student_id)\n        if Class['teacher'] == user['username']:\n            achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"detention\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/for-teachers/customize-class/<class_id>', methods=['GET'])\n    @requires_login\n    def get_class_info(user, class_id):\n        if not is_teacher(user):\n            return utils.error_page_403(error=403, ui_message='retrieve_class')\n        Class = DATABASE.get_class(class_id)\n        if not Class or Class['teacher'] != user['username']:\n            return utils.error_page(error=404,  ui_message='no_such_class')\n\n        if hedy_content.Adventures(g.lang).has_adventures():\n            adventures = hedy_content.Adventures(g.lang).get_adventure_keyname_name_levels()\n        else:\n            adventures = hedy_content.Adventures(\"en\").get_adventure_keyname_name_levels()\n        levels = hedy_content.LevelDefaults(g.lang).levels\n        preferences = DATABASE.get_customizations_class(class_id)\n\n        return render_template('customize-class.html', page_title=hedyweb.get_page_title('customize class'),\n                               class_info={'name': Class['name'], 'id': Class['id']}, levels=levels,\n                               adventures=adventures, preferences=preferences, current_page='my-profile')\n\n    @app.route('/customize-class/<class_id>', methods=['PUT'])\n    @requires_login\n    def update_level_preferences(user, class_id):\n        if not is_teacher(user):\n            return 'Only teachers can update class preferences', 403\n\n        body = request.json\n        print(body)\n        # Validations\n        if not isinstance(body, dict):\n            return 'body must be an object', 400\n        if not isinstance(body.get('example_programs'), bool):\n            return 'amount of example programs must be an integer', 400\n        if not isinstance(body.get('hide_level'), bool):\n            return 'level switch must be a boolean', 400\n        if not isinstance(body.get('hide_prev_level'), bool):\n            return 'level switch must be a boolean', 400\n        if not isinstance(body.get('hide_next_level'), bool):\n            return 'level switch must be a boolean', 400\n        if not isinstance(int(body.get('level')), int):\n            return 'level must ben an integer', 400\n\n        Class = DATABASE.get_class(class_id)\n        if not Class or Class['teacher'] != user['username']:\n            return 'No such class', 404\n\n        customizations = {}\n        customizations['id'] = class_id\n        customizations['level'] = int(body.get('level'))\n        customizations['adventures'] = body.get('adventures')\n        customizations['example_programs'] = body.get('example_programs')\n        customizations['hide'] = body.get('hide_level')\n        customizations['hide_prev_level'] = body.get('hide_prev_level')\n        customizations['hide_next_level'] = body.get('hide_next_level')\n\n        DATABASE.update_customizations_class(customizations)\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"my_class_my_rules\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/hedy/l/<link_id>', methods=['GET'])\n    def resolve_class_link (link_id):\n        Class = DATABASE.resolve_class_link (link_id)\n        if not Class:\n            return utils.error_page(error=404,  ui_message='invalid_class_link')\n        return redirect(request.url.replace('/hedy/l/' + link_id, '/class/' + Class ['id'] + '/prejoin/' + link_id), code=302)\n", "path": "website/teacher.py"}], "after_files": [{"content": "import json\n\nfrom website.auth import requires_login, is_teacher, current_user\nimport utils\nimport uuid\nfrom flask import g, request, jsonify, redirect\nfrom flask_helpers import render_template\nimport os\nimport hedyweb\nimport hedy_content\nTRANSLATIONS = hedyweb.Translations ()\nfrom config import config\ncookie_name     = config ['session'] ['cookie_name']\n\n\ndef routes (app, database, achievements):\n    global DATABASE\n    global ACHIEVEMENTS\n    DATABASE = database\n    ACHIEVEMENTS = achievements\n\n    @app.route('/classes', methods=['GET'])\n    @requires_login\n    def get_classes (user):\n        if not is_teacher(user):\n            return utils.error_page_403(error=403, ui_message='retrieve_class')\n        return jsonify (DATABASE.get_teacher_classes (user ['username'], True))\n\n    @app.route('/for-teachers/class/<class_id>', methods=['GET'])\n    @requires_login\n    def get_class (user, class_id):\n        app.logger.info('This is info output')\n        if not is_teacher(user):\n            return utils.error_page_403(error=403, ui_message='retrieve_class')\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['teacher'] != user ['username']:\n            return utils.error_page(error=404,  ui_message='no_such_class')\n        students = []\n        for student_username in Class.get ('students', []):\n            student = DATABASE.user_by_username (student_username)\n            programs = DATABASE.programs_for_user(student_username)\n            highest_level = max(program['level'] for program in programs) if len(programs) else 0\n            sorted_public_programs = list(sorted([program for program in programs if program.get ('public')], key=lambda p: p['date']))\n            if sorted_public_programs:\n                latest_shared = sorted_public_programs[-1]\n                latest_shared['link'] = f\"/hedy/{latest_shared['id']}/view\"\n            else:\n                latest_shared = None\n            students.append ({'username': student_username, 'last_login': utils.datetotimeordate (utils.mstoisostring (student ['last_login'])), 'programs': len (programs), 'highest_level': highest_level, 'latest_shared': latest_shared})\n\n        if utils.is_testing_request (request):\n            return jsonify ({'students': students, 'link': Class ['link'], 'name': Class ['name'], 'id': Class ['id']})\n\n        achievement = None\n        if len(students) > 20:\n            achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"full_house\")\n        if achievement:\n            achievement = json.dumps(achievement)\n\n        teachers = os.getenv('BETA_TEACHERS', '').split(',')\n        is_beta_teacher = user['username'] in teachers\n\n        return render_template ('class-overview.html', current_page='my-profile',\n                                page_title=hedyweb.get_page_title('class overview'),\n                                achievement=achievement,\n                                is_beta_teacher=is_beta_teacher,\n                                class_info={'students': students, 'link': os.getenv('BASE_URL') + '/hedy/l/' + Class ['link'],\n                                            'name': Class ['name'], 'id': Class ['id']})\n\n    @app.route('/class', methods=['POST'])\n    @requires_login\n    def create_class (user):\n        if not is_teacher(user):\n            return 'Only teachers can create classes', 403\n\n        body = request.json\n        # Validations\n        if not isinstance(body, dict):\n            return 'body must be an object', 400\n        if not isinstance(body.get('name'), str):\n            return 'name must be a string', 400\n\n        # We use this extra call to verify if the class name doesn't already exist, if so it's a duplicate\n        Classes = DATABASE.get_teacher_classes(user['username'], True)\n        for Class in Classes:\n            if Class['name'] == body['name']:\n                return \"duplicate\", 200\n\n        Class = {\n            'id': uuid.uuid4().hex,\n            'date': utils.timems (),\n            'teacher': user ['username'],\n            'link': utils.random_id_generator (7),\n            'name': body ['name']\n        }\n\n        DATABASE.store_class (Class)\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"ready_set_education\")\n        if achievement:\n            return {'id': Class['id'], 'achievement': achievement}, 200\n        return {'id': Class['id']}, 200\n\n    @app.route('/class/<class_id>', methods=['PUT'])\n    @requires_login\n    def update_class (user, class_id):\n        if not is_teacher(user):\n            return 'Only teachers can update classes', 403\n\n        body = request.json\n        # Validations\n        if not isinstance(body, dict):\n            return 'body must be an object', 400\n        if not isinstance(body.get('name'), str):\n            return 'name must be a string', 400\n\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['teacher'] != user ['username']:\n            return 'No such class', 404\n\n        # We use this extra call to verify if the class name doesn't already exist, if so it's a duplicate\n        Classes = DATABASE.get_teacher_classes(user ['username'], True)\n        for Class in Classes:\n            if Class['name'] == body['name']:\n                return \"duplicate\", 200\n\n        Class = DATABASE.update_class (class_id, body ['name'])\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"on_second_thoughts\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/class/<class_id>', methods=['DELETE'])\n    @requires_login\n    def delete_class (user, class_id):\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['teacher'] != user ['username']:\n            return 'No such class', 404\n\n        DATABASE.delete_class (Class)\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"end_of_semester\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/class/<class_id>/prejoin/<link>', methods=['GET'])\n    def prejoin_class (class_id, link):\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['link'] != link:\n            return utils.error_page(error=404,  ui_message='invalid_class_link')\n        user = {}\n        if request.cookies.get (cookie_name):\n            token = DATABASE.get_token(request.cookies.get (cookie_name))\n            if token:\n                if token ['username'] in Class.get ('students', []):\n                    return render_template ('class-prejoin.html', joined=True,\n                                            page_title=hedyweb.get_page_title('join class'),\n                                            current_page='my-profile', class_info={'name': Class ['name']})\n                user = DATABASE.user_by_username(token ['username'])\n\n        return render_template ('class-prejoin.html', joined=False,\n                                page_title=hedyweb.get_page_title('join class'),\n                                current_page='my-profile',\n                                class_info={\n                                    'id': Class ['id'],\n                                    'name': Class ['name'],\n                                })\n\n    @app.route('/class/join', methods=['POST'])\n    @requires_login\n    def join_class(user):\n        body = request.json\n        if 'id' in body:\n            Class = DATABASE.get_class(body['id'])\n        if not Class or Class ['id'] != body['id']:\n            return utils.error_page(error=404,  ui_message='invalid_class_link')\n\n        DATABASE.add_student_to_class(Class['id'], user['username'])\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"epic_education\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/class/<class_id>/student/<student_id>', methods=['DELETE'])\n    @requires_login\n    def leave_class (user, class_id, student_id):\n        Class = DATABASE.get_class (class_id)\n        if not Class or Class ['teacher'] != user ['username'] or student_id != user ['username']:\n            return 'No such class', 404\n\n        DATABASE.remove_student_from_class (Class ['id'], student_id)\n        if Class['teacher'] == user['username']:\n            achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"detention\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/for-teachers/customize-class/<class_id>', methods=['GET'])\n    @requires_login\n    def get_class_info(user, class_id):\n        if not is_teacher(user):\n            return utils.error_page_403(error=403, ui_message='retrieve_class')\n        Class = DATABASE.get_class(class_id)\n        if not Class or Class['teacher'] != user['username']:\n            return utils.error_page(error=404,  ui_message='no_such_class')\n\n        if hedy_content.Adventures(g.lang).has_adventures():\n            adventures = hedy_content.Adventures(g.lang).get_adventure_keyname_name_levels()\n        else:\n            adventures = hedy_content.Adventures(\"en\").get_adventure_keyname_name_levels()\n        levels = hedy_content.LevelDefaults(g.lang).levels\n        preferences = DATABASE.get_customizations_class(class_id)\n\n        return render_template('customize-class.html', page_title=hedyweb.get_page_title('customize class'),\n                               class_info={'name': Class['name'], 'id': Class['id']}, levels=levels,\n                               adventures=adventures, preferences=preferences, current_page='my-profile')\n\n    @app.route('/customize-class/<class_id>', methods=['PUT'])\n    @requires_login\n    def update_level_preferences(user, class_id):\n        if not is_teacher(user):\n            return 'Only teachers can update class preferences', 403\n\n        body = request.json\n        print(body)\n        # Validations\n        if not isinstance(body, dict):\n            return 'body must be an object', 400\n        if not isinstance(body.get('example_programs'), bool):\n            return 'amount of example programs must be an integer', 400\n        if not isinstance(body.get('hide_level'), bool):\n            return 'level switch must be a boolean', 400\n        if not isinstance(body.get('hide_prev_level'), bool):\n            return 'level switch must be a boolean', 400\n        if not isinstance(body.get('hide_next_level'), bool):\n            return 'level switch must be a boolean', 400\n        if not isinstance(int(body.get('level')), int):\n            return 'level must ben an integer', 400\n\n        Class = DATABASE.get_class(class_id)\n        if not Class or Class['teacher'] != user['username']:\n            return 'No such class', 404\n\n        customizations = {}\n        customizations['id'] = class_id\n        customizations['level'] = int(body.get('level'))\n        customizations['adventures'] = body.get('adventures')\n        customizations['example_programs'] = body.get('example_programs')\n        customizations['hide'] = body.get('hide_level')\n        customizations['hide_prev_level'] = body.get('hide_prev_level')\n        customizations['hide_next_level'] = body.get('hide_next_level')\n\n        DATABASE.update_customizations_class(customizations)\n        achievement = ACHIEVEMENTS.add_single_achievement(user['username'], \"my_class_my_rules\")\n        if achievement:\n            return {'achievement': achievement}, 200\n        return {}, 200\n\n    @app.route('/hedy/l/<link_id>', methods=['GET'])\n    def resolve_class_link (link_id):\n        Class = DATABASE.resolve_class_link (link_id)\n        if not Class:\n            return utils.error_page(error=404,  ui_message='invalid_class_link')\n        return redirect(request.url.replace('/hedy/l/' + link_id, '/class/' + Class ['id'] + '/prejoin/' + link_id), code=302)\n", "path": "website/teacher.py"}]}