diff --git a/src/teams/templates/team_list.html b/src/teams/templates/team_list.html
index c0a314da..9a74a534 100644
--- a/src/teams/templates/team_list.html
+++ b/src/teams/templates/team_list.html
@@ -7,13 +7,47 @@ Teams | {{ block.super }}
{% endblock %}
{% block content %}
-
{{ camp.title }} Teams
-This is a list of the teams for {{ camp.title }}. To join a team just press the Join button, but please put some info in your profile first, so the team responsible has some idea who you are.
-You can also leave a team of course, but please let the team responsible know why :)
-Team memberships need to be approved by a team responsible. You will receive a message when your membership has been approved.
-At {{ camp.title }} all organisers and volunteers buy full tickets like everyone else. At future events our budget may allow for discounts or free tickets for volunteers, but currently it does not.
-We currently have {{ teams.count }} teams for {{ camp.title }}:
+
+
+
+
About teams
+
This is a list of the teams for {{ camp.title }}. To join a team just press the Join button, but please put some info in your profile first, so the team responsible has some idea who you are.
+
You can also leave a team of course, but please let the team responsible know why :)
+
Team memberships neesdf be approved by a team responsible. You will receive a message when your membership has been approved.
+
At {{ camp.title }} all organisers and volunteers buy full tickets like everyone else. At future events our budget may allow for discounts or free tickets for volunteers, but currently it does not.
+
We currently have {{ teams.count }} teams for {{ camp.title }}.
+
+
+ {% if user.is_authenticated %}
+
+
+
Your teams
+
+ {% if user_teams %}
+
+
+ Manage shifts
+
+ {% else %}
+ You are not on any teams.
+ {% endif %}
+
+ {% endif %}
+
+
+
{% if teams %}
diff --git a/src/teams/templates/team_user_shifts.html b/src/teams/templates/team_user_shifts.html
new file mode 100644
index 00000000..fe370b1d
--- /dev/null
+++ b/src/teams/templates/team_user_shifts.html
@@ -0,0 +1,44 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
+Your shifts
+
+
+
+ {% for shift in user_shifts %}
+ {% ifchanged shift.shift_range.lower|date:'d' %}
+
+
+
+ {{ shift.shift_range.lower|date:'Y-m-d l' }}
+
+ |
+ Team |
+ Start |
+ End |
+ Actions |
+ {% endifchanged %}
+
+
+
+ {{ shift.team.name }}
+ |
+
+ {{ shift.shift_range.lower|date:'H:i' }}
+ |
+
+ {{ shift.shift_range.upper|date:'H:i' }}
+ |
+
+
+ Unassign me
+
+ |
+
+ {% endfor %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/teams/urls.py b/src/teams/urls.py
index 37100380..9e84f0f0 100644
--- a/src/teams/urls.py
+++ b/src/teams/urls.py
@@ -37,6 +37,7 @@ from teams.views.shifts import (
ShiftDeleteView,
MemberTakesShift,
MemberDropsShift,
+ UserShifts,
)
app_name = 'teams'
@@ -47,6 +48,11 @@ urlpatterns = [
TeamListView.as_view(),
name='list'
),
+ path(
+ 'shifts',
+ UserShifts.as_view(),
+ name='user_shifts'
+ ),
path(
'/', include([
path(
diff --git a/src/teams/views/base.py b/src/teams/views/base.py
index cce95e70..ee5c7c77 100644
--- a/src/teams/views/base.py
+++ b/src/teams/views/base.py
@@ -19,6 +19,12 @@ class TeamListView(CampViewMixin, ListView):
model = Team
context_object_name = 'teams'
+ def get_context_data(self, *, object_list=None, **kwargs):
+ context = super().get_context_data(object_list=object_list, **kwargs)
+ if self.request.user.is_authenticated:
+ context['user_teams'] = self.request.user.teammember_set.filter(team__camp=self.camp)
+ return context
+
class TeamGeneralView(CampViewMixin, DetailView):
template_name = "team_general.html"
diff --git a/src/teams/views/shifts.py b/src/teams/views/shifts.py
index 7a436462..9b218dc7 100644
--- a/src/teams/views/shifts.py
+++ b/src/teams/views/shifts.py
@@ -1,5 +1,7 @@
+from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
+from django.template import Template, Context
from django.views.generic import (
View,
CreateView,
@@ -7,9 +9,9 @@ from django.views.generic import (
ListView,
FormView,
DeleteView,
+ TemplateView
)
from django import forms
-from django.contrib.postgres.forms.ranges import RangeWidget
from django.utils import timezone
from django.urls import reverse
@@ -299,7 +301,25 @@ class MemberTakesShift(LoginRequiredMixin, CampViewMixin, View):
team_member = TeamMember.objects.get(team=team, user=request.user)
- shift.team_members.add(team_member)
+ overlapping_shifts = TeamShift.objects.filter(
+ team__camp=self.camp,
+ team_members__user=request.user,
+ shift_range__overlap=shift.shift_range
+ )
+
+ if overlapping_shifts.exists():
+ template = Template("""You have shifts overlapping with the one you are trying to assign:
+ {% for shift in shifts %}
+ - {{ shift }}
+ {% endfor %}
+
+ """)
+ messages.error(
+ request,
+ template.render(Context({"shifts": overlapping_shifts}))
+ )
+ else:
+ shift.team_members.add(team_member)
kwargs.pop('pk')
@@ -334,3 +354,16 @@ class MemberDropsShift(LoginRequiredMixin, CampViewMixin, View):
kwargs=kwargs
)
)
+
+
+class UserShifts(CampViewMixin, TemplateView):
+ template_name = 'team_user_shifts.html'
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['user_teams'] = self.request.user.teammember_set.filter(team__camp=self.camp)
+ context['user_shifts'] = TeamShift.objects.filter(
+ team__camp=self.camp,
+ team_members__user=self.request.user
+ )
+ return context
\ No newline at end of file