Add shortcut to users teams. Add a overview of users shifts, and prevent user from taking a shift which overlaps with one already assigned to the user.
This commit is contained in:
parent
a3bfd85604
commit
da639ff4cd
|
@ -7,13 +7,47 @@ Teams | {{ block.super }}
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h3>{{ camp.title }} Teams</h3>
|
||||
<p>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 <a href="{% url 'profiles:detail' %}">profile</a> first, so the team responsible has some idea who you are.</p>
|
||||
<p>You can also leave a team of course, but please let the team responsible know why :)</p>
|
||||
<p>Team memberships need to be approved by a team responsible. You will receive a message when your membership has been approved.</p>
|
||||
<p>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.</p>
|
||||
<p>We currently have {{ teams.count }} teams for {{ camp.title }}:</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-{% if user.is_authenticated %}6{% else %}12{% endif %}">
|
||||
<h4>About teams</h4>
|
||||
<p>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 <a href="{% url 'profiles:detail' %}">profile</a> first, so the team responsible has some idea who you are.</p>
|
||||
<p>You can also leave a team of course, but please let the team responsible know why :)</p>
|
||||
<p>Team memberships neesdf be approved by a team responsible. You will receive a message when your membership has been approved.</p>
|
||||
<p>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.</p>
|
||||
<p>We currently have {{ teams.count }} teams for {{ camp.title }}.</p>
|
||||
</div>
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<div class="col-md-6">
|
||||
<div>
|
||||
<h4>Your teams</h4>
|
||||
</div>
|
||||
{% if user_teams %}
|
||||
<ul>
|
||||
{% for team_member in user_teams %}
|
||||
<li>
|
||||
<a href="{% url 'teams:general' camp_slug=camp.slug team_slug=team_member.team.slug %}">
|
||||
{{ team_member.team.name }}
|
||||
{% if team_member.responsible %}
|
||||
(Responsible)
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="{% url 'teams:user_shifts' camp_slug=camp.slug %}" class="btn btn-primary">
|
||||
Manage shifts
|
||||
</a>
|
||||
{% else %}
|
||||
You are not on any teams.
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
{% if teams %}
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
|
|
44
src/teams/templates/team_user_shifts.html
Normal file
44
src/teams/templates/team_user_shifts.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h3>Your shifts</h3>
|
||||
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
{% for shift in user_shifts %}
|
||||
{% ifchanged shift.shift_range.lower|date:'d' %}
|
||||
<tr>
|
||||
<td colspan=4>
|
||||
<h4>
|
||||
{{ shift.shift_range.lower|date:'Y-m-d l' }}
|
||||
</h4>
|
||||
<tr>
|
||||
<th>Team</th>
|
||||
<th>Start</th>
|
||||
<th>End</th>
|
||||
<th>Actions</th>
|
||||
{% endifchanged %}
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
{{ shift.team.name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ shift.shift_range.lower|date:'H:i' }}
|
||||
</td>
|
||||
<td>
|
||||
{{ shift.shift_range.upper|date:'H:i' }}
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn btn-danger"
|
||||
href="{% url 'teams:shift_member_drop' camp_slug=camp.slug team_slug=shift.team.slug pk=shift.pk %}">
|
||||
<i class="fas fa-thumbs-down"></i> Unassign me
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
|
@ -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(
|
||||
'<slug:team_slug>/', include([
|
||||
path(
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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:<br/> <ul>
|
||||
{% for shift in shifts %}
|
||||
<li>{{ shift }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
""")
|
||||
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
|
Loading…
Reference in a new issue