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:
Víðir Valberg Guðmundsson 2018-08-12 16:50:53 +02:00
parent a3bfd85604
commit da639ff4cd
5 changed files with 131 additions and 8 deletions

View file

@ -7,13 +7,47 @@ Teams | {{ block.super }}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h3>{{ camp.title }} Teams</h3> <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> <div class="row">
<p>Team memberships need to be approved by a team responsible. You will receive a message when your membership has been approved.</p> <div class="col-md-{% if user.is_authenticated %}6{% else %}12{% endif %}">
<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> <h4>About teams</h4>
<p>We currently have {{ teams.count }} teams for {{ camp.title }}:</p> <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 %} {% if teams %}
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>

View 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 %}

View file

@ -37,6 +37,7 @@ from teams.views.shifts import (
ShiftDeleteView, ShiftDeleteView,
MemberTakesShift, MemberTakesShift,
MemberDropsShift, MemberDropsShift,
UserShifts,
) )
app_name = 'teams' app_name = 'teams'
@ -47,6 +48,11 @@ urlpatterns = [
TeamListView.as_view(), TeamListView.as_view(),
name='list' name='list'
), ),
path(
'shifts',
UserShifts.as_view(),
name='user_shifts'
),
path( path(
'<slug:team_slug>/', include([ '<slug:team_slug>/', include([
path( path(

View file

@ -19,6 +19,12 @@ class TeamListView(CampViewMixin, ListView):
model = Team model = Team
context_object_name = 'teams' 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): class TeamGeneralView(CampViewMixin, DetailView):
template_name = "team_general.html" template_name = "team_general.html"

View file

@ -1,5 +1,7 @@
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.template import Template, Context
from django.views.generic import ( from django.views.generic import (
View, View,
CreateView, CreateView,
@ -7,9 +9,9 @@ from django.views.generic import (
ListView, ListView,
FormView, FormView,
DeleteView, DeleteView,
TemplateView
) )
from django import forms from django import forms
from django.contrib.postgres.forms.ranges import RangeWidget
from django.utils import timezone from django.utils import timezone
from django.urls import reverse from django.urls import reverse
@ -299,6 +301,24 @@ class MemberTakesShift(LoginRequiredMixin, CampViewMixin, View):
team_member = TeamMember.objects.get(team=team, user=request.user) team_member = TeamMember.objects.get(team=team, user=request.user)
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) shift.team_members.add(team_member)
kwargs.pop('pk') kwargs.pop('pk')
@ -334,3 +354,16 @@ class MemberDropsShift(LoginRequiredMixin, CampViewMixin, View):
kwargs=kwargs 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