Skip to content

Commit a2b7a7e

Browse files
Merge pull request #63 from FSU-ACM/dev
ui updates + contest dash additions + faculty dash overhaul
2 parents a1184f5 + 21a58af commit a2b7a7e

File tree

12 files changed

+334
-54
lines changed

12 files changed

+334
-54
lines changed

src/contestadmin/tasks.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,13 @@ def generate_ec_reports():
193193
else:
194194
team_division = 'Lower'
195195

196+
if student.profile.fsu_id is None:
197+
fsu_id = 'none'
198+
else:
199+
fsu_id = student.profile.fsu_id
200+
196201
writer.writerow([
197-
student.profile.fsu_id,
202+
fsu_id,
198203
student.last_name,
199204
student.first_name,
200205
questions_answered,
@@ -214,9 +219,13 @@ def email_faculty(domain):
214219
fpath = MEDIA_ROOT + '/ec_files/'
215220

216221
for faculty in faculty_members:
222+
found_files = False
223+
217224
for fname in os.listdir(fpath):
218225
uid=((faculty.email).split('@'))[0]
219226
if uid in fname: #not faculty_nanmer
227+
found_files = True
228+
220229
message = render_to_string('contestadmin/ec_available_email.html', {
221230
'faculty': faculty,
222231
'domain': domain,
@@ -232,7 +241,21 @@ def email_faculty(domain):
232241
)
233242

234243
break
235-
244+
245+
if not found_files:
246+
message = render_to_string('contestadmin/no_ec_available_email.html', {
247+
'faculty': faculty,
248+
'domain': domain,
249+
'uid': urlsafe_base64_encode(force_bytes(uid)),
250+
})
251+
252+
send_mail(
253+
'Programming Contest EC files',
254+
message,
255+
DEFAULT_FROM_EMAIL,
256+
[faculty.email],
257+
fail_silently=False,
258+
)
236259

237260

238261
@shared_task

src/contestadmin/templates/contestadmin/dashboard.html

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,59 @@ <h1 class="text-center">Contest Dashboard</h1>
189189
</div>
190190
<!-- Division Stats Card deck end -->
191191

192-
192+
<!-- Volunteer Summary card -->
193+
<div class="card mt-4 mb-3">
194+
<div class="card-header font-weight-bold">
195+
Volunteers
196+
</div>
197+
<div class="card-body overflow-auto">
198+
<div class="row justify-content-center">
199+
<div class="col-10">
200+
<div class="table-responsive">
201+
<table class="table table-sm">
202+
<thead class="thead-light">
203+
<tr>
204+
<th scope="col">Role</th>
205+
<th scope="col">Name</th>
206+
<th scope="col" class="text-center">Checked-in</th>
207+
<th scope="col" class="text-center">Added Courses</th>
208+
209+
</tr>
210+
</thead>
211+
<tbody>
212+
{% for volunteer in volunteers %}
213+
<tr>
214+
{% if volunteer.role == 2 %}
215+
<td>Proctor</td>
216+
{% elif volunteer.role == 3 %}
217+
<td>Question Writer</td>
218+
{% else %}
219+
<td>Organizer</td>
220+
{% endif %}
221+
222+
<td>{{ volunteer.user.get_full_name }}</td>
223+
224+
{% if volunteer.checked_in %}
225+
<td class="text-center">Yes</td>
226+
{% else %}
227+
<td class="text-center">No</td>
228+
{% endif %}
229+
230+
{% if volunteer.has_courses %}
231+
<td class="text-center">Yes</td>
232+
{% else %}
233+
<td class="text-center">No</td>
234+
{% endif %}
235+
</tr>
236+
{% endfor %}
237+
</tbody>
238+
</table>
239+
</div>
240+
</div>
241+
</div>
242+
</div>
243+
</div>
244+
<!-- Volunteer Summary card end -->
193245

194246
<!-- Course Summary card -->
195247
<div class="card mt-4 mb-3">
@@ -199,32 +251,35 @@ <h1 class="text-center">Contest Dashboard</h1>
199251
<div class="card-body overflow-auto">
200252
<div class="row justify-content-center">
201253
<div class="col-10">
202-
<table class="table table-sm">
203-
<thead class="thead-light">
204-
<tr>
205-
<th scope="col">Code</th>
206-
<th scope="col">Name</th>
207-
<th scope="col">Instructor</th>
208-
<th scope="col">Students</th>
209-
</tr>
210-
</thead>
211-
<tbody>
212-
{% for course in courses %}
213-
<tr>
214-
<td>{{ course.code }}</td>
215-
<td>{{ course.name }}</td>
216-
<td>{{ course.instructor.last_name }}</td>
217-
<td>{{ course.num_registered }}</td>
218-
</tr>
219-
{% endfor %}
220-
</tbody>
221-
</table>
254+
<div class="table-responsive">
255+
<table class="table table-sm">
256+
<thead class="thead-light">
257+
<tr>
258+
<th scope="col">Code</th>
259+
<th scope="col">Name</th>
260+
<th scope="col">Instructor</th>
261+
<th scope="col" class="text-center">Students</th>
262+
</tr>
263+
</thead>
264+
<tbody>
265+
{% for course in courses %}
266+
<tr>
267+
<td>{{ course.code }}</td>
268+
<td>{{ course.name }}</td>
269+
<td>{{ course.instructor.last_name }}</td>
270+
<td class="text-center">{{ course.num_registered }}</td>
271+
</tr>
272+
{% endfor %}
273+
</tbody>
274+
</table>
275+
</div>
222276
</div>
223277
</div>
224278
</div>
225279
</div>
226280
<!-- Course Summary card end -->
227281

282+
228283
<!-- Create Walk-in Teams Modal -->
229284
<div class="modal fade" id="walkinModal" tabindex="-1" role="dialog"
230285
aria-labelledby="confirmClearModalCenterTitle" aria-hidden="true">

src/contestadmin/templates/contestadmin/faculty_dashboard.html

Lines changed: 167 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,175 @@
55

66
{% block content %}
77
<h1 class="text-center">Faculty Dashboard</h1>
8-
<div class="row justify-content-center mt-4">
9-
<div class="col-8">
10-
<div class="card">
11-
<div class="card-header lead">
12-
Hello {{ first_name }} {{ last_name }}
13-
</div>
14-
<div class="card-body">
15-
<p class="card-text">The zip file linked below contains CSVs with participant information for each of the courses you registered with the contest. Each row in a CSV file contains the following fields: fsu_id, last_name, first_name, questions_answered, team_division, role. Each field is separated by a single comma without whitespace, and each row is delimited by a newline. The role field will have one of the following values: contestant, proctor, question writer, organizer. If a student checked into the contest but subsequently removed themself from the team used at check-in before we processed the results, then the team_division and questions_answered fields will contain the value 'none'. You will only receive reports for classes where at least one student checked-in to the contest. </p>
16-
<a href="{% url 'fac_ec_files_dl' uidb64=uid %}" class="btn btn-primary"><i class="fa fa-download mx-1" aria-hidden="true"></i>Download</a>
8+
<!-- File Download and Description Card deck -->
9+
<div class="card-deck">
10+
<!-- File Download card -->
11+
<div class="card mt-4">
12+
<div class="card-header lead">
13+
{{ first_name }} {{ last_name }}
14+
</div>
15+
<div class="card-body overflow-auto">
16+
<p class="card-text">
17+
The zip file linked below contains CSVs with participant information for each of the courses you confirmed with the contest. You will only receive reports for classes where at least one student checked in to the contest either as a contestant or volunteer. Additionally, only individuals who checked in to the contest will appear in a file.
18+
</p>
19+
<p class="card-text">
20+
For in-person contests, we strive to ensure that individuals who are marked as checked-in actually attended the contest by requiring that check-in is performed in-person. We do not verify the identity of the individuals who check-in, so if Student A possesses Student B's credentials, then Student A could hypothetically check in on behalf of student B.
21+
</p>
22+
</div>
23+
<div class="card-footer">
24+
{% if ec_files_available %}
25+
<a href="{% url 'fac_ec_files_dl' uidb64=uid %}" class="btn btn-primary"><i class="fa fa-download mx-1" aria-hidden="true"></i>Download</a>
26+
{% else %}
27+
<a href="" class="btn btn-primary disabled"><i class="fa fa-download mx-1" aria-hidden="true"></i>Download</a>
28+
{% endif %}
29+
</div>
30+
</div>
31+
<!-- File Download card end -->
32+
<!-- File Description card -->
33+
<div class="card mt-4">
34+
<div class="card-header font-weight-bold">
35+
File Format
36+
</div>
37+
<div class="card-body overflow-auto">
38+
<p class="card-text">
39+
Each row in a CSV file contains the following fields in the order listed:
40+
</p>
41+
<ul class="card-text">
42+
<li>fsu_id</li>
43+
<li>last_name</li>
44+
<li>first_name</li>
45+
<li>questions_answered</li>
46+
<li>team_division</li>
47+
<li>role</li>
48+
</ul>
49+
<p class="card-text">
50+
Each field is separated by a single comma without whitespace, and each row is delimited by a newline.
51+
</p>
52+
<p class="card-text">
53+
The fsu_id field will have a value of "none" if the student did not add the ID to their profile.
54+
</p>
55+
</div>
56+
</div>
57+
<!-- File Description card end -->
58+
</div>
59+
<!-- File Download and Description Card deck end -->
60+
61+
<!-- Role, Division, and QA Card deck -->
62+
<div class="card-deck">
63+
<!-- Roles card -->
64+
<div class="card mt-4">
65+
<div class="card-header font-weight-bold">
66+
Role Descriptions
67+
</div>
68+
<div class="card-body overflow-auto">
69+
<ul class="card-text" style="list-style-type: none; margin: 0; padding: 0;">
70+
<li>
71+
<div class="font-weight-bold">Contestant</div> A student who competed in the contest either alone or with teammates.
72+
</li>
73+
<li>
74+
<div class="font-weight-bold">Proctor</div> A contest volunteer who assisted with room monitoring, check-in, preparing/serving food, or any other activity required to host the event.
75+
</li>
76+
<li>
77+
<div class="font-weight-bold">Question Writer</div> A contest volunteer who wrote one or more questions used in the contest packets, and offered question clarifications to contestants for the duration of the contest.
78+
</li>
79+
<li>
80+
<div class="font-weight-bold">Organizer</div> A contest volunteer who helped plan, coordinate, and host the contest. Typically involves managing question writers, proctors, and high level contest details.
81+
</li>
82+
</ul>
83+
</div>
84+
</div>
85+
<!-- Roles card end -->
86+
<!-- Division and QA card -->
87+
<div class="card mt-4">
88+
<div class="card-header font-weight-bold">
89+
Division &amp; Questions Answered
90+
</div>
91+
<div class="card-body overflow-auto">
92+
<h5>Division<span class="text-danger">&dagger;</span></h5>
93+
<ul class="card-text">
94+
<li><span class="font-weight-bold">Upper:</span> competed in the Upper Division
95+
</li>
96+
<li><span class="font-weight-bold">Lower:</span> competed in the Lower Division
97+
</li>
98+
<li><span class="font-weight-bold">none:</span> reserved for contest volunteers </li>
99+
</ul>
100+
101+
<p>The Lower Division is intended for students in CDA3100, COP3014, COP3363, or COP3330 who are typically first or second year undergrads. All other students are expected to participate in the Upper Division.</p>
102+
103+
<h5>Questions Answered<span class="text-danger">&dagger;</h5>
104+
<p class="card-text">
105+
<ul>
106+
<li>
107+
<span class="font-weight-bold">[0, total_questions]:</span> a value of 0 represents a contestant who checked in, but did not correctly solve any of the questions in the packet.
108+
</li>
109+
<li>
110+
<span class="font-weight-bold">none:</span> reserved for contest volunteers
111+
</li>
112+
</ul>
113+
</p>
114+
</div>
115+
</div>
116+
<!-- Division and QA card end -->
117+
</div>
118+
<!-- Role, Division, and QA Card deck end -->
119+
120+
<!-- Volunteer Summary Card note-->
121+
<div class="row justify-content-center mt-2">
122+
<div class="col-10">
123+
<small>
124+
<span class="text-danger">&dagger;</span>
125+
NOTE: An individual who has a role other than Contestant may still be attached to a contest team in our registration system. In this instance, values for questions_answered and team_division will not be "none". This does NOT necessarily mean that the individual took part in solving any of the questions.
126+
</small>
127+
</div>
128+
</div>
129+
130+
<!-- Course Summary card -->
131+
<div class="card mt-3 mb-3">
132+
<div class="card-header font-weight-bold">
133+
Course Overview
134+
</div>
135+
<div class="card-body overflow-auto">
136+
<div class="row justify-content-center">
137+
<div class="col-10">
138+
<div class="table-responsive">
139+
<table class="table table-sm">
140+
<thead class="thead-light">
141+
<tr>
142+
<th scope="col">Code</th>
143+
<th scope="col">Name</th>
144+
<th scope="col" class="text-center">
145+
Checked-in<span class="text-danger">&Dagger;</span>
146+
</th>
147+
<th scope="col" class="text-center">
148+
Registered<span class="text-danger">&Dagger;</span>
149+
</th>
150+
</tr>
151+
</thead>
152+
<tbody>
153+
{% for course in courses %}
154+
<tr>
155+
<td>{{ course.code }}</td>
156+
<td>{{ course.name }}</td>
157+
<td class="text-center">{{ course.num_checkedin }}</td>
158+
<td class="text-center">{{ course.num_registered }}</td>
159+
</tr>
160+
{% endfor %}
161+
</tbody>
162+
</table>
163+
</div>
17164
</div>
18165
</div>
19166
</div>
20167
</div>
168+
<!-- Course Summary card end -->
169+
170+
<!-- Course Summary Card note-->
171+
<div class="row justify-content-center mt-2">
172+
<div class="col-10">
173+
<small>
174+
<span class="text-danger">&Dagger;</span>
175+
NOTE: The Registered value represents the number of individuals who signed up in for the contest and added the given course to their profile. The Checked-in value repsresents the number of individuals who signed up, added the given course, and checked in to the contest.
176+
</small>
177+
</div>
178+
</div>
21179
{% endblock %}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{% autoescape off %}
2+
Hello {{ faculty.first_name }},
3+
4+
Thank you for offering extra credit in your course(s) for Programming Contest participation. After processing the contest results, we determined that either no students added your course(s) to their profile, or no students who did add the course(s) checked in to the contest. Therefore, no documents containing participation information are available for you to access. An overview of your courses is still available via the link below.
5+
6+
https://{{ domain }}{% url 'fac_ec_dashboard' uidb64=uid %}
7+
8+
Cheers,
9+
The Programming Contest Team
10+
contest@fsu.acm.org
11+
{% endautoescape %}

0 commit comments

Comments
 (0)