Skip to content
Merged
5 changes: 5 additions & 0 deletions docs/usage/account_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ Upon activating your account or subsequently logging into the site, you should b
>
> In order for your course instructor(s) to receive a record of your contest participation, you are required to complete the FSU ID section of your account profile, as well as select your enrolled coure(s) from the Courses list in your Account Dashboard.

{: .highlight-title }
> Changing your password
>
> To update your account password, use the *Lost password* link on the log-in page.

## Account Dashboard

A link to your Account Dashboard is assessible from the user dropdown menu located in the site's navbar when you view the site while logged in. The dashboard may be accessed directly by navigating to `<site_url>/manage/`.
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/contest_administration/announcements.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ parent: Contest Administration

---

The PCS supports the dissemination of simple text announcements to multiple distribution endpoints. Announcements are managed through the Django Administration interface.
The PCS supports the dissemination of simple text announcements to multiple distribution endpoints. Announcements are managed through the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) interface.

## Distribution Endpoints

Expand Down
2 changes: 1 addition & 1 deletion docs/usage/contest_administration/contest_checkin.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ On or after Contest Day, the Contest Organizers will provide each volunteer who
title: Volunteer Check-in Flow
---
graph TD
A[<small>Check-in Form</small><br>Enter username and passphrase]--> B((Submission<br>Accepted?))
A[<small>Check-in Form</small><br>Enter Username and Volunteer PIN]--> B((Submission<br>Accepted?))
B-->|Yes| C[/Participation recorded\]
B-->|No| D{<small>Correct entry</small><br>}
D-->|Retry| A
Expand Down
6 changes: 3 additions & 3 deletions docs/usage/contest_administration/contest_creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ parent: Contest Administration

---

The *Contest* database table stores details about a contest and should be populated after the PCS is deployed, initialized and secured. Create a contest by adding a new entry to the *Contest* table using the Django Administration interface.
The *Contest* database table stores details about a contest and should be populated after the PCS is deployed, initialized and secured. Create a contest by adding a new entry to the *Contest* table using the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) interface.

{: .warning-title }
> Multiple contests
Expand All @@ -30,14 +30,14 @@ The *Contest* database table stores details about a contest and should be popula
>
> A contest is easy to intialize requiring only the *Contest date* attribute.

From the Django Administration homepage, click the *Add* button located in the *Contests* row of the *CONTESTADMIN* section.
From the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) homepage, click the *Add* button located in the *Contests* row of the *CONTESTADMIN* section.

<figure>
<img src="{{site.url}}/assets/images/contest_administration/add_contest.png?raw=true" alt="Add contest"/>
<figcaption><small>Figure 1. Adding a Contest Model.</small></figcaption>
</figure>

Besides the *Contest date* attribute, which is required at creation, a contest's other attributes may be set during initialization or later via the Django Administration interface. Once done editig a contest, click the *Save* button at the bottom of the page.
Besides the *Contest date* attribute, which is required at creation, a contest's other attributes may be set during initialization or later via the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) interface. Once done editig a contest, click the *Save* button at the bottom of the page.

<figure>
<img src="{{site.url}}/assets/images/contest_administration/manage_contest.png?raw=true" alt="Edit contest"/>
Expand Down
14 changes: 9 additions & 5 deletions docs/usage/contest_administration/django_administration.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@ parent: Contest Administration

---

The Django Administration provides an interface for managing objects such as Sponsors and Contests. This centralized control panel is essential for tasks that cannot be handled within a Contest Dashboard. The interface may be accessed directly by navigating to `<site_url>/admin/`.
Django Administration provides an interface for managing the PCS database. This centralized control panel is essential for tasks that cannot be handled within the Contest Dashboard. The interface may be accessed directly by navigating to `<site_url>/admin/`.

## Administration access

A user profile must be assigned privileges to access Django Administration that are separate from the [Volunteer Roles]({{ site.url }}/usage/volunteers.html#volunteer-roles) assigned through the [Contest Dashboard]({{ site.url }}/usage/contest_administration/contest_dashboard.html). These privileges may be assigned in Django Administration by a user with appropriate access, such as a superuser.

{: .important-title }
> Administration access
> Docker deployment
>
> A user profile must be assigned the *Contest Organizer* role to access the Django Administration.

![Django Administration]({{ site.url }}/assets/images/contest_administration/django_administration.png?raw=true)
> When using a [Docker deployment]({{ site.url }}/deployment/docker/docker_image.html) of the PCS, a superuser account is created automatically during system initialization.

## Action Overview

![Django Administration]({{ site.url }}/assets/images/contest_administration/django_administration.png?raw=true)

- **Create Contests**
- Create a contest for the semester.
- **Add Sponsors**
Expand Down
29 changes: 29 additions & 0 deletions docs/usage/contest_administration/export_pcs_data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
layout: default
title: Export PCS Data
grand_parent: User Manuals
parent: Contest Administration
---

# Export PCS Data

The PCS can generate CSV files with merged user, team and contest results data, useful for archiving results post-contest. Generate the data files using the *Generate Team CSVs* utility in the *Tools* section on the [Contest Dashboard]({{ site.url }}/usage/contest_administration/contest_dashboard.html). A download button is enabled in the same section after file generation completes.

For each division, a file is generated where each row has the following CSV format:

```
team_division,team_name,questions_answered,domjudge_id,team_active,team_members
```

- **team_division**
The division code of the team: faculty (`F`), upper (`U`) or lower (`L`).
- **team_name**
The team's name registered in the PCS.
- **questions_answered**
The number of correct submissions by the team in DOMjudge.
- **domjudge_id**
The team's ID (ex. `acm-xxx`) in DOMjudge.
- **team_active**
If `T` then at least one team member checked into the contest, otherwise `F`.
- **team_members**
The full name of each team member.
12 changes: 6 additions & 6 deletions docs/usage/contest_administration/extra_credit.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The extra credit system allows users to attach one or more registered courses to

## Pre-contest

The PCS database must be populated with course and faculty data before users can attach courses to their profile. *Course* and *Faculty* database entries are managed through the Django Administration interface.
The PCS database must be populated with course and faculty data before users can attach courses to their profile. *Course* and *Faculty* database entries are managed through the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) interface.

{: .important-title }
> Initialization order
Expand All @@ -29,7 +29,7 @@ The PCS database must be populated with course and faculty data before users can

### Adding Faculty

The *Faculty* database table stores the course instructors who register one or more courses with a semester's contest. From the Django Administration homepage, click the *Add* button located in the *Facultys* row of the *MANAGER* section.
The *Faculty* database table stores the course instructors who register one or more courses with a semester's contest. From the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) homepage, click the *Add* button located in the *Facultys* row of the *MANAGER* section.

{: .warning-title }
> Email addresses
Expand All @@ -50,7 +50,7 @@ Each Faculty entry contains the following fields.

### Adding Courses

The *Course* database table stores the courses that instructors register with a semester's contest. From the Django Administration homepage, click the *Add* button located in the *Courses* row of the *MANAGER* section.
The *Course* database table stores the courses that instructors register with a semester's contest. From the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) homepage, click the *Add* button located in the *Courses* row of the *MANAGER* section.

### Course Attributes

Expand All @@ -64,7 +64,7 @@ The *Course* database table stores the courses that instructors register with a

### Adding data in bulk

*Course* and *Faculty* data may be added in bulk through the Django Administration interface.
*Course* and *Faculty* data may be added in bulk through the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) interface.

{: .important-title }
> Import order
Expand All @@ -73,7 +73,7 @@ The *Course* database table stores the courses that instructors register with a

#### Faculty file

From the Django Administration homepage, navigate to the *Faculty* table by clicking the *Facultys* button in the *MANAGER* section. On the *Faculty* table page, click the *IMPORT* button in the upper right hand corner of the interface.
From the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) homepage, navigate to the *Faculty* table by clicking the *Facultys* button in the *MANAGER* section. On the *Faculty* table page, click the *IMPORT* button in the upper right hand corner of the interface.

The PCS supports faculty bulk uploads in the following CSV format:

Expand All @@ -94,7 +94,7 @@ A simple Python script to generate a faculty data CSV is located in the [PCS cod

#### Course file

From the Django Administration homepage, navigate to the *Course* table by clicking the *Courses* button in the *MANAGER* section. On the *Course* table page, click the *IMPORT* button in the upper right hand corner of the interface. The faculty member references in the course data file must already exist in the database.
From the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) homepage, navigate to the *Course* table by clicking the *Courses* button in the *MANAGER* section. On the *Course* table page, click the *IMPORT* button in the upper right hand corner of the interface. The faculty member references in the course data file must already exist in the database.

The PCS supports course bulk uploads in the following CSV format:

Expand Down
13 changes: 13 additions & 0 deletions docs/usage/contest_administration/faculty_teams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
layout: default
title: Faculty Teams
grand_parent: User Manuals
parent: Contest Administration
---

# Faculty Teams

The PCS supports designating a registered team as a *Faculty Team*, which are teams comprised of one or more faculty members. Use the *Designate Faculty Team* utility in the *Tools* section on the [Contest Dashboard]({{ site.url }}/usage/contest_administration/contest_dashboard.html) to change a team's status.

Once a team is assigned faculty status, it is displayed in the Faculty Teams table on the *Teams* page. A team from either division may be assigned faculty status, and the team will participate in it's registered division.

2 changes: 1 addition & 1 deletion docs/usage/contest_administration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The Programming Contest Suite (PCS) is designed to ease the administration of a
{: .important-title }
> Management Interfaces
>
> A contest is managed through the [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) and the [Contest Dashboard]({{ site.url }}/usage/contest_administration/contest_dashboard.html).
> A contest is managed through [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) and the [Contest Dashboard]({{ site.url }}/usage/contest_administration/contest_dashboard.html).

## Administration Flowchart

Expand Down
20 changes: 20 additions & 0 deletions docs/usage/contest_administration/user_passwords.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
layout: default
title: User Passwords
grand_parent: User Manuals
parent: Contest Administration
---

# User Password Management

The PCS **does not** yet allow users to change their account password when logged into the system. Instead, users should use the *Lost password* link on the log-in page to perform password updates.

## Change Password Utility

In instances when a user cannot reset their password using the aforementioned method, use the form in the *Change User Password* section on the [Contest Dashboard]({{ site.url }}/usage/contest_administration/contest_dashboard.html).

{: .warning-title }
> Django administration
>
> User passwords should **not** be changed in the *Users* section of [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html), as this field represents a password's *hashed* value, not the raw value.

13 changes: 9 additions & 4 deletions docs/usage/contest_administration/volunteer_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,29 @@ The PCS volunteer integration grants contest volunteers edditional permissions i

After registering a PCS account, a contest volunteer is assigned one of the PCS user profile roles that most closely corresponds to their duties.

{: .important-title }
> Contestant check-in interface
>
> All volunteers gain access to the [Contestant Check-in]({{ site.url }}/usage/contest_administration/contest_checkin.html#contestant-check-in) interface, allowing any volunteer to manage a check-in station.

- **Docent**
Assists with check-in, preparing/serving food, or any other activity required to host a contest.
- **Proctor**
Responsible for monitoring contestants and answering basic questions while the contest is active.
- **Question Writer**
Writes one or more questions used in the contest packets, and offers question clarifications to contestants for the duration of the contest.
- **Contest Organizer**
Helps plan, coordinate, and host the contest. Typically involves managing question writers, proctors, docents, and important contest details.
Helps plan, coordinate, and host the contest. Typically involves managing question writers, proctors, docents, and important contest details. Users with this role can access and use the [Contest Dashboard]({{ site.url }}/usage/contest_administration/contest_dashboard.html) and [Contest Statistics]({{ site.url }}/usage/contest_administration/contest_dashboard.html#contest-statistics) pages.

## Managing roles

User roles are managed with the utility in the *Update User Role* section on the [Contest Dashboard]({{ site.url }}/usage/contest_administration/contest_dashboard.html).

{: .note-title }
{: .highlight-title }
> Role limitation
>
> The User Role system does not grant a user Django Administration privileges. These privileges must be assigned separately through Django Administration.
> The User Role system does not grant a user [Django Administration]({{ site.url }}/usage/contest_administration/django_administration.html) privileges. These privileges must be assigned separately through Django Administration.

## Voluteer check-in

The [Volunteer Check-in]({{ site.url }}/usage/volunteers.html#volunteer-check-in) interface is a dedicated portal for contest volunteers to check in. The *Volunteer pin* attribute of a contest specifies the passcode volunteers use to complete volunteer check-in. The interface may be accessed by any user with a volunteer role, allowing a contest volunteer to complete check-in whenever they are provided the passcode.
The [Volunteer Check-in]({{ site.url }}/usage/contest_administration/contest_checkin.html#volunteer-check-in) interface is a dedicated portal for contest volunteers to check in. The *Volunteer pin* attribute of a contest specifies the passcode volunteers use to complete volunteer check-in. The interface may be accessed by any user with a volunteer role, allowing a contest volunteer to complete check-in whenever they are provided the passcode.
12 changes: 9 additions & 3 deletions src/checkin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def checkin(request):

is_walkin = True

# Process email form entry, if it has been made.
# Process swipe form entry, if it has been made.
if swipe_form.cleaned_data['fsu_num']:
if swipe_form.valid_read():
fsu_number = Hashid(swipe_form.parse())
Expand All @@ -60,8 +60,11 @@ def checkin(request):
request, 'Check in failed. FSU number not found. ', fail_silently=True)
messages.info(request, 'Retry using email check in.', fail_silently=True)
else:
# User has a volunteer role
if user.profile.is_volunteer():
messages.warning(request, f"{user.first_name}, you are a contest volunteer. Please use the Volunteer Check-in interface.", fail_silently=True)
# User already checked in
if user.profile.checked_in and not checkin_auth(user):
elif user.profile.checked_in and not checkin_auth(user):
messages.info(request, 'You are already checked in.',
fail_silently=True)
# User exists but no team selection (walk-in/registered) provided
Expand Down Expand Up @@ -104,8 +107,11 @@ def checkin(request):
messages.error(
request, 'Check in failed. Email address not found.', fail_silently=True)
else:
# User has a volunteer role
if user.profile.is_volunteer():
messages.warning(request, f"{user.first_name}, you are a contest volunteer. Please use the Volunteer Check-in interface.", fail_silently=True)
# User already checked in
if user.profile.checked_in and not checkin_auth(user):
elif user.profile.checked_in and not checkin_auth(user):
messages.info(request, 'You are already checked in.', fail_silently=True)
# User exists but no team selection (walk-in/registered) provided
elif user.profile.team is None and not is_walkin:
Expand Down
2 changes: 1 addition & 1 deletion src/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ <h5 class="dropdown-header">Misc</h5>
<a class="dropdown-item" href="https://contest.cs.fsu.edu/flower/" target="_blank"><i class="fa-solid fa-diagram-project fa-fw"></i> Flower Dashboard</a>
<hr>
{% endif %}
<a class="dropdown-item" href="{% url 'checkin' %}"><i class="fa-solid fa-door-open fa-fw"></i> Contest Check-in</a>
<a class="dropdown-item" href="{% url 'checkin' %}"><i class="fa-solid fa-door-open fa-fw"></i> Contestant Check-in</a>
<a class="dropdown-item" href="{% url 'volunteer_checkin' %}"><i class="fa-solid fa-handshake-simple fa-fw"></i> Volunteer Check-in</a>
<hr>
{% endif %}
Expand Down
Loading