Skip to content

Commit

Permalink
feat(enrichment): add restricted activity functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
alanzhu0 committed Mar 8, 2024
1 parent d80c923 commit 81edff8
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Ion.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Intranet 3
*Version 3.0.0*

Intranet3 (Ion) is the next-generation Intranet platform for `TJHSST
<https://www.tjhsst.edu/>`_. Using Python, Django, Redis, Postgres, and many other technologies, Ion was developed from the ground up to be simple, well-documented, and extensible.
<https://tjhsst.fcps.edu/>`_. Using Python, Django, Redis, Postgres, and many other technologies, Ion was developed from the ground up to be simple, well-documented, and extensible.

Documentation (in RestructuredText format) is available inside the "docs" folder or at https://tjcsl.github.io/ion publicly on the web.

Expand Down
1 change: 1 addition & 0 deletions Ion.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ intranet/apps/enrichment/urls.py
intranet/apps/enrichment/views.py
intranet/apps/enrichment/migrations/0001_initial.py
intranet/apps/enrichment/migrations/0002_alter_enrichmentactivity_options.py
intranet/apps/enrichment/migrations/0003_auto_20240307_2313.py
intranet/apps/enrichment/migrations/__init__.py
intranet/apps/error/__init__.py
intranet/apps/error/tests.py
Expand Down
9 changes: 1 addition & 8 deletions intranet/apps/enrichment/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,4 @@ def __init__(self, *args, **kwargs):
class Meta:
model = EnrichmentActivity

fields = [
"title",
"description",
"time",
"location",
"capacity",
"presign",
]
fields = ["title", "description", "time", "location", "capacity", "presign", "groups_allowed", "groups_blacklisted"]
24 changes: 24 additions & 0 deletions intranet/apps/enrichment/migrations/0003_auto_20240307_2313.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.2.20 on 2024-03-08 04:13

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('enrichment', '0002_alter_enrichmentactivity_options'),
]

operations = [
migrations.AddField(
model_name='enrichmentactivity',
name='groups_allowed',
field=models.ManyToManyField(blank=True, related_name='allowed_enrichments_set', to='auth.Group'),
),
migrations.AddField(
model_name='enrichmentactivity',
name='groups_blacklisted',
field=models.ManyToManyField(blank=True, related_name='blacklisted_enrichments_set', to='auth.Group'),
),
]
24 changes: 24 additions & 0 deletions intranet/apps/enrichment/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime

from django.conf import settings
from django.contrib.auth.models import Group as DjangoGroup
from django.db import models
from django.db.models import Manager
from django.utils import timezone
Expand Down Expand Up @@ -51,6 +52,25 @@ class EnrichmentActivity(models.Model):

presign = models.BooleanField(default=False)

groups_allowed = models.ManyToManyField(DjangoGroup, related_name="allowed_enrichments_set", blank=True)
groups_blacklisted = models.ManyToManyField(DjangoGroup, related_name="blacklisted_enrichments_set", blank=True)

def user_can_signup(self, user):
"""Return whether a user can sign up for an enrichment activity.
Args:
user: The user to check.
Returns:
Whether the user can sign up for the enrichment activity.
"""
return (not self.groups_allowed.exists() or any(group in user.groups.all() for group in self.groups_allowed.all())) and not any(
group in user.groups.all() for group in self.groups_blacklisted.all()
)

def user_is_blacklisted(self, user):
return any(group in user.groups.all() for group in self.groups_blacklisted.all())

@property
def is_this_year(self):
"""Return whether the enrichment activity was created after the start of the school year."""
Expand All @@ -61,6 +81,10 @@ def happened(self):
"""Return whether an enrichment activity has happened."""
return self.time < timezone.now()

@property
def restricted(self):
return self.groups_allowed.exists()

@property
def is_too_early_to_signup(self):
"""Returns whether it is too early to sign up for the activity
Expand Down
11 changes: 10 additions & 1 deletion intranet/apps/enrichment/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,12 @@ def enrichment_view(request):
{"title": "This month", "enrichments": viewable_enrichments.filter(time__gte=this_month[0], time__lt=this_month[1])},
]

week_and_month = viewable_enrichments.filter(time__gte=this_week[0], time__lt=this_month[1])
if not show_all and not classic:
enrichments_categories.append(
{
"title": "Week and month",
"enrichments": viewable_enrichments.filter(time__gte=this_week[0], time__lt=this_month[1]),
"enrichments": week_and_month,
}
)

Expand All @@ -180,6 +181,8 @@ def enrichment_view(request):

context = {
"enrichments": enrichments_categories,
"authorized_enrichments": {e.id for e in week_and_month if e.user_can_signup(request.user)},
"blacklisted_enrichments": {e.id for e in week_and_month if e.user_is_blacklisted(request.user)},
"num_enrichments": num_enrichments,
"is_enrichment_admin": is_enrichment_admin,
"show_attend": True,
Expand Down Expand Up @@ -209,6 +212,10 @@ def enrichment_signup_view(request, enrichment_id):
messages.error(request, "Signups are locked for this enrichment activity.")
return redirect("enrichment")

if not enrichment.user_can_signup(request.user):
messages.error(request, "You do not have permission to sign up for this enrichment activity.")
return redirect("enrichment")

if enrichment.presign:
too_early_to_signup = enrichment.is_too_early_to_signup
if too_early_to_signup[0]:
Expand Down Expand Up @@ -249,6 +256,8 @@ def enrichment_roster_view(request, enrichment_id):

context = {
"enrichment": enrichment,
"authorized_enrichments": {enrichment.id if enrichment.user_can_signup(request.user) else None},
"blacklisted_enrichments": {enrichment.id if enrichment.user_is_blacklisted(request.user) else None},
"enrichment_time": enrichment.time.astimezone(timezone.get_default_timezone()),
"enrichment_is_today": enrichment_is_today,
"roster": enrichment.attending.all().order_by("first_name", "last_name"),
Expand Down
16 changes: 16 additions & 0 deletions intranet/static/css/enrichment.scss
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@
display: none;
}

.selectize-control {
margin-top: 4px;
}

.schedule {
min-height: 65vh;
}


@keyframes gradient {
0% {
Expand All @@ -71,6 +79,14 @@
}
}

@media(min-width: 768px) {
.signup-notice {
width: 40vw;
position: relative;
left: 15px;
}
}

@media(max-width: 550px) {
.attending-badge {
display: block;
Expand Down
9 changes: 9 additions & 0 deletions intranet/templates/enrichment/add_modify.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
create: true
})

$("#id_groups_allowed").selectize({
create: false
})

$("#id_groups_blacklisted").selectize({
create: false
});

// name of <textarea> is description
var editor = CKEDITOR.replace("id_description", {
width: "600px"
Expand All @@ -46,6 +54,7 @@
<link rel="stylesheet" href="{% static 'vendor/datetimepicker-2.4.5/jquery.datetimepicker.css' %}">
<link rel="stylesheet" href="{% static 'vendor/selectize.js-0.12.4/dist/css/selectize.default.css' %}">
{% stylesheet 'announcements.form' %}
{% stylesheet 'enrichment' %}
{% endblock %}

{% block head %}
Expand Down
115 changes: 73 additions & 42 deletions intranet/templates/enrichment/enrichment.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,67 +43,98 @@ <h3 style="font-size: 15px; margin-top: auto;">
</div>
<div class="enrichment-metadata event-metadata">
{{ enrichment.attending.all|length }}/{{ enrichment.capacity }} signups

{% if enrichment.presign %}
{% if enrichment.presign or enrichment.restricted %}
&bull;
{% endif %}
{% if enrichment.presign %}
<span
class="badge yellow clickable"
data-append-search="is:p"
title="Signups for this enrichment activity open on {{ enrichment.is_too_early_to_signup.1|date:'l, F j' }} at {{ enrichment.is_too_early_to_signup.1|date:'P' }}">
2 day
</span>
{% endif %}
{% if enrichment.restricted %}
{% if enrichment.id in authorized_enrichments %}
<span class="badge green clickable" title="You are authorized to sign up for this restricted activity.">
Authorized
</span>
{% else %}
<span class="badge purple clickable" title="This activity is restricted to those on the authorized list.">
Restricted
</span>
{% endif %}
{% endif %}
</div>
<div class="enrichment-content" style="font-size:14px;">
{{ enrichment.description|safe }}
</div>
</div>
<div class="enrichment enrichment-bottom event {% if request.user in enrichment.attending.all %}signed-up{% endif %}">
{% if not enrichment.happened %}
<form data-form-attend="{{ enrichment.id }}" action="{% url 'enrichment_signup' enrichment.id %}" method="post" style="font-size: 12px">
{% csrf_token %}
{% if request.user in enrichment.attending.all %}
<span {% if enrichment_is_today %} style="color: green" {% endif %}>
<i class="fas fa-check"></i> You are signed up for this activity.
</span>
<br>
<a data-form-attend="{{ enrichment.id }}" class="button small-button no-attend-button attend-button">
<i class="fas fa-times"></i>
Remove Signup
</a>
{% else %}
<input type="hidden" name="attending" value="true">
<a data-form-attend="{{ enrichment.id }}" class="button attend-button">
Sign Up
</a>
{% endif %}
</form>
{% if enrichment.id in blacklisted_enrichments %}
<div class="enrichment-content" style="font-size:12px;">
<i class="fas fa-times" style="color: red"></i>
You have been blocked from signing up for this activity.
Contact the activity sponsor for more information.
</div>
{% elif enrichment.restricted and enrichment.id not in authorized_enrichments %}
<div class="enrichment-content" style="font-size:12px;">
<i class="fas fa-times"></i>
Signups for this activity are restricted to those on the authorized list.
</div>
{% else %}
<form data-form-attend="{{ enrichment.id }}" action="{% url 'enrichment_signup' enrichment.id %}" method="post" style="font-size: 12px">
{% csrf_token %}
{% if request.user in enrichment.attending.all %}
<span {% if enrichment_is_today %} style="color: green" {% endif %}>
<i class="fas fa-check"></i> You are signed up for this activity.
</span>
<br>
<a data-form-attend="{{ enrichment.id }}" class="button small-button no-attend-button attend-button">
<i class="fas fa-times"></i>
Remove Signup
</a>
{% else %}
<input type="hidden" name="attending" value="true">
<a data-form-attend="{{ enrichment.id }}" class="button attend-button">
Sign Up
</a>
{% endif %}
</form>
{% endif %}
{% else %}
<div class="enrichment-content" style="font-size:12px;">
{% if request.user in enrichment.attending.all %}
{% if not enrichment_is_today %}
<i class="fas fa-check"></i>
You signed up for this activity.

{% if enrichment.id in blacklisted_enrichments %}
<div class="enrichment-content" style="font-size:12px;">
<i class="fas fa-times" style="color: red"></i>
You have been blocked from signing up for this activity.
Contact the activity sponsor for more information.
</div>
{% else %}
<span style="color: green">
<i class="fas fa-check"></i>
You are signed up for this activity.
</span>
{% comment %} <br>
<hr>
<span class="remove-signup-text">
You can still remove your signup, but you will not be able to sign up again.
</span>
<br>
{% if not enrichment_is_today %} {# This shouldn't happen, but just in case #}
<i class="fas fa-check"></i>
You signed up for this activity.
{% else %}
<span style="color: green">
<i class="fas fa-check"></i>
You are signed up for this activity.
</span>
{% comment %} <br>
<hr>
<span class="remove-signup-text">
You can still remove your signup, but you will not be able to sign up again.
</span>
<br>

<form data-form-attend="{{ enrichment.id }}" action="{% url 'enrichment_signup' enrichment.id %}" method="post">
{% csrf_token %}
<a data-form-attend="{{ enrichment.id }}" style="margin-top: 3px" class="button small-button no-attend-button attend-button">
<i class="fas fa-times"></i>
Remove Signup
</a>
</form> {% endcomment %}
<form data-form-attend="{{ enrichment.id }}" action="{% url 'enrichment_signup' enrichment.id %}" method="post">
{% csrf_token %}
<a data-form-attend="{{ enrichment.id }}" style="margin-top: 3px" class="button small-button no-attend-button attend-button">
<i class="fas fa-times"></i>
Remove Signup
</a>
</form> {% endcomment %}
{% endif %}
{% endif %}
{% else %}
<i class="fas fa-times"></i>
Expand Down
8 changes: 8 additions & 0 deletions intranet/templates/enrichment/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ <h2 class="category">{{ category.title }}:</h2>
<div class="enrichment-container" id="view-div"></div>
{% endif %}

<div class="signup-notice">
<hr>
<i class="fas fa-info-circle"></i> Students should not repeatedly signup for enrichment activities and not
attend, as this takes away spots from other students. Please remove your signup if
you do not plan to attend. Repeat offenders may lose enrichment activity signup
privileges.
<hr>
</div>
</div>
{# This needs to be at the bottom for the content to properly load #}
<script src="{% static 'js/events.js' %}"></script>
Expand Down

0 comments on commit 81edff8

Please sign in to comment.