add teamtask support

This commit is contained in:
Thomas Steen Rasmussen 2017-11-23 23:09:14 +01:00
parent d4265edaa0
commit 142afa5ead
20 changed files with 279 additions and 111 deletions

View file

@ -10,7 +10,7 @@
<div class="row"> <div class="row">
<h2>Infodesk Backoffice</h2> <h2>Infodesk Backoffice</h2>
<div class="lead"> <div class="lead">
Orders with one or more Products that are not handed out Paid (and not later refunded) orders with at least one product that is not yet handed out
</div> </div>
</div> </div>
<div class="row"> <div class="row">

View file

@ -297,6 +297,7 @@ urlpatterns = [
VillageUpdateView.as_view(), VillageUpdateView.as_view(),
name='village_update' name='village_update'
), ),
# this has to be the last url in the list
url( url(
r'(?P<slug>[-_\w+]+)/$', r'(?P<slug>[-_\w+]+)/$',
VillageDetailView.as_view(), VillageDetailView.as_view(),
@ -306,45 +307,11 @@ urlpatterns = [
), ),
url( url(
r'^teams/', include([ r'^teams/',
url( include('teams.urls', namespace='teams')
r'^$',
TeamListView.as_view(),
name='team_list'
),
url(
r'^members/(?P<pk>[0-9]+)/remove/$',
TeamMemberRemoveView.as_view(),
name='teammember_remove',
),
url(
r'^members/(?P<pk>[0-9]+)/approve/$',
TeamMemberApproveView.as_view(),
name='teammember_approve',
),
url(
r'(?P<slug>[-_\w+]+)/join/$',
TeamJoinView.as_view(),
name='team_join'
),
url(
r'(?P<slug>[-_\w+]+)/leave/$',
TeamLeaveView.as_view(),
name='team_leave'
),
url(
r'(?P<slug>[-_\w+]+)/manage/$',
TeamManageView.as_view(),
name='team_manage'
),
# this has to be the last url in the list
url(
r'(?P<slug>[-_\w+]+)/$',
TeamDetailView.as_view(),
name='team_detail'
),
])
), ),
]) ])
) )
] ]

View file

@ -37,7 +37,7 @@
<div class="row"> <div class="row">
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead"> <div class="lead">
The BornHack team looks forward to organising another great event for the hacker community. We <a href="{% url 'team_list' camp_slug=camp.slug %}">still need volunteers</a>, so please let us know if you want to help! The BornHack team looks forward to organising another great event for the hacker community. We <a href="{% url 'teams:list' camp_slug=camp.slug %}">still need volunteers</a>, so please let us know if you want to help!
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">

View file

@ -37,7 +37,7 @@
<div class="row"> <div class="row">
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead"> <div class="lead">
The BornHack team looks forward to organising another great event for the hacker community. We <a href="{% url 'team_list' camp_slug=camp.slug %}">still need volunteers</a>, so please let us know if you want to help! The BornHack team looks forward to organising another great event for the hacker community. We <a href="{% url 'teams:list' camp_slug=camp.slug %}">still need volunteers</a>, so please let us know if you want to help!
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">

View file

@ -37,7 +37,7 @@
<div class="row"> <div class="row">
<div class="col-md-9 col-sm-9 text-container"> <div class="col-md-9 col-sm-9 text-container">
<div class="lead"> <div class="lead">
The BornHack team looks forward to organising another great event for the hacker community. We <a href="{% url 'team_list' camp_slug=camp.slug %}">still need volunteers</a>, so please let us know if you want to help! The BornHack team looks forward to organising another great event for the hacker community. We <a href="{% url 'teams:list' camp_slug=camp.slug %}">still need volunteers</a>, so please let us know if you want to help!
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">

View file

@ -1,8 +1,18 @@
from django.contrib import admin from django.contrib import admin
from .models import Team, TeamArea, TeamMember from .models import Team, TeamArea, TeamMember, TeamTask
from .email import add_added_membership_email, add_removed_membership_email from .email import add_added_membership_email, add_removed_membership_email
@admin.register(TeamTask)
class TeamTaskAdmin(admin.ModelAdmin):
list_display = [
'id',
'team',
'name',
'description',
]
@admin.register(Team) @admin.register(Team)
class TeamAdmin(admin.ModelAdmin): class TeamAdmin(admin.ModelAdmin):
def get_responsible(self, obj): def get_responsible(self, obj):

View file

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-11-22 18:28
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('teams', '0016_auto_20170711_2247'),
]
operations = [
migrations.CreateModel(
name='TeamTask',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('name', models.CharField(help_text='Short name of this task', max_length=100)),
('slug', models.SlugField(blank=True, help_text='url slug, leave blank to autogenerate', max_length=255)),
('description', models.TextField(help_text='Description of the task. Markdown is supported.')),
('team', models.ForeignKey(help_text='The team this task belongs to', on_delete=django.db.models.deletion.CASCADE, to='teams.Team')),
],
options={
'ordering': ['name'],
},
),
migrations.AlterUniqueTogether(
name='teamtask',
unique_together=set([('slug', 'team'), ('name', 'team')]),
),
]

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-11-22 21:04
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('teams', '0017_auto_20171122_1928'),
]
operations = [
migrations.AlterField(
model_name='teamtask',
name='team',
field=models.ForeignKey(help_text='The team this task belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to='teams.Team'),
),
]

View file

@ -115,3 +115,38 @@ def add_responsible_email(sender, instance, created, **kwargs):
if created: if created:
if not add_new_membership_email(instance): if not add_new_membership_email(instance):
logger.error('Error adding email to outgoing queue') logger.error('Error adding email to outgoing queue')
class TeamTask(CampRelatedModel):
team = models.ForeignKey(
'teams.Team',
related_name='tasks',
help_text='The team this task belongs to',
)
name = models.CharField(
max_length=100,
help_text='Short name of this task',
)
slug = models.SlugField(
max_length=255,
blank=True,
help_text='url slug, leave blank to autogenerate',
)
description = models.TextField(
help_text='Description of the task. Markdown is supported.'
)
class Meta:
ordering = ['name']
unique_together = (('name', 'team'), ('slug', 'team'))
@property
def camp(self):
return self.team.camp
def save(self, **kwargs):
if not self.slug:
slug = slugify(self.name)
self.slug = slug
super().save(**kwargs)

View file

@ -0,0 +1,17 @@
{% extends 'base.html' %}
{% load commonmark %}
{% block title %}
{{ task.name }}
{% endblock %}
{% block content %}
<div class="panel panel-default">
<div class="panel-heading"><h4>Task: {{ task.name }}</h4></div>
<div class="panel-body">{{ task.description|commonmark }}</div>
<div class="panel-footer"><i>This task belongs to the <a href="{% url 'teams:detail' slug=task.team.slug camp_slug=task.team.camp.slug %}">{{ task.team.name }} Team</a></i></div>
</div>
{% endblock %}

View file

@ -9,56 +9,81 @@ Team: {{ team.name }} | {{ block.super }}
{% block content %} {% block content %}
<h3>{{ team.name }} Team ({{ team.area.name }} area)</h3> <div class="panel panel-default">
<div class="panel-heading"><h4>{{ team.name }} Team</h4></div>
<div class="panel-body">
{{ team.description|unsafecommonmark }}
{% if request.user in team.responsible.all %}
<a href="{% url 'teams:manage' camp_slug=camp.slug slug=team.slug %}" class="btn btn-success">Manage Team</a>
{% endif %}
{{ team.description|unsafecommonmark }} <hr>
<p>Currently {{ team.approvedmembers.count }} people are members of this team{% if request.user in team.members.all %} (including you){% endif %}.</p>
{% if request.user in team.members.all %} <h3>Members</h3>
<p>Your team status: {% membershipstatus request.user team %}</p> <p>The following <b>{{ team.approvedmembers.count }}</b> people are members of the <b>{{ team.name }} team</b>:</p>
{% endif %} <table class="table">
<thead>
<tr>
<th>
Name
</th>
<th>
Status
</th>
</tr>
</thead>
<tbody>
{% for teammember in team.approvedmembers.all %}
<tr>
<td>
{% if teammember.user.profile.approved_public_credit_name %}
{{ teammember.user.profile.approved_public_credit_name }}
{% else %}
anonymous
{% endif %}
</td>
<td>
{% if teammember.responsible %}Team Responsible{% else %}Team Member{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if request.user in team.members.all %} {% if request.user in team.members.all %}
<a href="{% url 'team_leave' camp_slug=camp.slug slug=team.slug %}" class="btn btn-danger">Leave Team</a> <p>Your membership status: <b>{% membershipstatus request.user team %}</b></p>
{% else %} {% endif %}
{% if team.needs_members %}
<a href="{% url 'team_join' camp_slug=camp.slug slug=team.slug %}" class="btn btn-success">Join Team</a> {% if request.user in team.members.all %}
{% endif %} <a href="{% url 'teams:leave' camp_slug=camp.slug slug=team.slug %}" class="btn btn-danger">Leave Team</a>
{% endif %} {% else %}
{% if team.needs_members %}
<b>This team is looking for members!</b> <a href="{% url 'teams:join' camp_slug=camp.slug slug=team.slug %}" class="btn btn-xs btn-success">Join Team</a>
{% endif %}
{% endif %}
<hr>
<h3>Tasks</h3>
<p>This team is responsible for the following tasks</p>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for task in team.tasks.all %}
<tr>
<td><a href="{% url 'teams:task_detail' slug=task.slug camp_slug=camp.slug team_slug=team.slug %}">{{ task.name }}</a></td>
<td>{{ task.description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% if request.user in team.responsible.all %}
<a href="{% url 'team_manage' camp_slug=camp.slug slug=team.slug %}" class="btn btn-success">Manage Team</a>
{% endif %}
<hr />
<h3>Team Members</h3>
<p>The following people are members of the <b>{{ team.name }} team</b>:</p>
<table class="table">
<thead>
<tr>
<th>
Name
</th>
<th>
Status
</th>
</tr>
</thead>
<tbody>
{% for teammember in team.approvedmembers.all %}
{% if teammember.user.profile.approved_public_credit_name and teammember.approved or teammember.responsible %}
<tr>
<td>
{{ teammember.user.profile.approved_public_credit_name }}
</td>
<td>
{% if teammember.responsible %}Team Responsible{% else %}Team Member{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% if team.anoncount %}
<p>Plus <b>{{ team.anoncount }}</b> member(s) who prefer to remain anonymous.</p>
{% endif %}
{% endblock %} {% endblock %}

View file

@ -13,6 +13,6 @@ Join Team: {{ team.name }} | {{ block.super }}
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Join {{ team.name }} Team</button> <button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Join {{ team.name }} Team</button>
<a href="{% url 'team_list' camp_slug=camp.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a> <a href="{% url 'teams:list' camp_slug=camp.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a>
</form> </form>
{% endblock %} {% endblock %}

View file

@ -13,6 +13,6 @@ Leave Team: {{ team.name }} | {{ block.super }}
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Leave {{ team.name }} Team</button> <button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Leave {{ team.name }} Team</button>
<a href="{% url 'team_list' camp_slug=camp.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a> <a href="{% url 'teams:list' camp_slug=camp.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a>
</form> </form>
{% endblock %} {% endblock %}

View file

@ -22,6 +22,7 @@ Teams | {{ block.super }}
<th>Description</th> <th>Description</th>
<th>Responsible</th> <th>Responsible</th>
<th class="text-center">Members</th> <th class="text-center">Members</th>
<th class="text-center">Tasks</th>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<th>Member?</th> <th>Member?</th>
<th>Actions</th> <th>Actions</th>
@ -32,7 +33,7 @@ Teams | {{ block.super }}
{% for team in teams %} {% for team in teams %}
<tr> <tr>
<td> <td>
<a href="{% url 'team_detail' camp_slug=camp.slug slug=team.slug %}"> <a href="{% url 'teams:detail' camp_slug=camp.slug slug=team.slug %}">
{{ team.name }} Team {{ team.name }} Team
</a> </a>
</td> </td>
@ -51,6 +52,10 @@ Teams | {{ block.super }}
{% if team.needs_members %}(more needed){% endif %} {% if team.needs_members %}(more needed){% endif %}
</td> </td>
<td class="text-center">
<span class="badge">{{ team.tasks.count }}</span><br>
</td>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<td class="text-center"> <td class="text-center">
{% membershipstatus request.user team as membership_status %} {% membershipstatus request.user team as membership_status %}
@ -67,15 +72,15 @@ Teams | {{ block.super }}
<td> <td>
{% if request.user in team.members.all %} {% if request.user in team.members.all %}
<a href="{% url 'team_leave' camp_slug=camp.slug slug=team.slug %}" class="btn btn-danger"><i class="fa fa-minus"></i> Leave</a> <a href="{% url 'teams:leave' camp_slug=camp.slug slug=team.slug %}" class="btn btn-danger"><i class="fa fa-minus"></i> Leave</a>
{% else %} {% else %}
{% if team.needs_members %} {% if team.needs_members %}
<a href="{% url 'team_join' camp_slug=camp.slug slug=team.slug %}" class="btn btn-success"><i class="fa fa-plus"></i> Join</a> <a href="{% url 'teams:join' camp_slug=camp.slug slug=team.slug %}" class="btn btn-success"><i class="fa fa-plus"></i> Join</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if request.user in team.responsible.all %} {% if request.user in team.responsible.all %}
<a href="{% url 'team_manage' camp_slug=camp.slug slug=team.slug %}" class="btn btn-primary"><i class="fa fa-cog"></i> Manage</a> <a href="{% url 'teams:manage' camp_slug=camp.slug slug=team.slug %}" class="btn btn-primary"><i class="fa fa-cog"></i> Manage</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
</td> </td>

View file

@ -71,10 +71,10 @@ Manage Team: {{ team.name }} | {{ block.super }}
</td> </td>
<td> <td>
{% if membership.approved %} {% if membership.approved %}
<a class="btn btn-danger" href="{% url 'teammember_remove' camp_slug=camp.slug pk=membership.id %}"><i class="fa fa-trash-o"></i> Remove</a> <a class="btn btn-danger" href="{% url 'teams:teammember_remove' camp_slug=camp.slug pk=membership.id %}"><i class="fa fa-trash-o"></i> Remove</a>
{% else %} {% else %}
<a class="btn btn-danger" href="{% url 'teammember_remove' camp_slug=camp.slug pk=membership.id %}"><i class="fa fa-trash-o"></i> Remove</a> <a class="btn btn-danger" href="{% url 'teams:teammember_remove' camp_slug=camp.slug pk=membership.id %}"><i class="fa fa-trash-o"></i> Remove</a>
<a class="btn btn-success" href="{% url 'teammember_approve' camp_slug=camp.slug pk=membership.id %}"><i class="fa fa-check"></i> Approve</a> <a class="btn btn-success" href="{% url 'teams:teammember_approve' camp_slug=camp.slug pk=membership.id %}"><i class="fa fa-check"></i> Approve</a>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>

View file

@ -13,6 +13,6 @@ Approve team member {{ teammember.user.profile.name }} for the {{ teammember.tea
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Add teammember</button> <button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Add teammember</button>
<a href="{% url 'team_detail' camp_slug=teammember.team.camp.slug slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a> <a href="{% url 'teams:detail' camp_slug=teammember.team.camp.slug slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a>
</form> </form>
{% endblock %} {% endblock %}

View file

@ -13,6 +13,6 @@ Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.nam
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<button class="btn btn-danger" type="submit"><i class="fa fa-trash-o"></i> Remove teammember</button> <button class="btn btn-danger" type="submit"><i class="fa fa-trash-o"></i> Remove teammember</button>
<a href="{% url 'team_detail' camp_slug=teammember.team.camp.slug slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a> <a href="{% url 'teams:detail' camp_slug=teammember.team.camp.slug slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a>
</form> </form>
{% endblock %} {% endblock %}

47
src/teams/urls.py Normal file
View file

@ -0,0 +1,47 @@
from django.conf.urls import url
from .views import *
urlpatterns = [
url(
r'^$',
TeamListView.as_view(),
name='list'
),
url(
r'^members/(?P<pk>[0-9]+)/remove/$',
TeamMemberRemoveView.as_view(),
name='teammember_remove',
),
url(
r'^members/(?P<pk>[0-9]+)/approve/$',
TeamMemberApproveView.as_view(),
name='teammember_approve',
),
url(
r'(?P<team_slug>[-_\w+]+)/tasks/(?P<slug>[-_\w+]+)/$',
TaskDetailView.as_view(),
name='task_detail',
),
url(
r'(?P<slug>[-_\w+]+)/join/$',
TeamJoinView.as_view(),
name='join'
),
url(
r'(?P<slug>[-_\w+]+)/leave/$',
TeamLeaveView.as_view(),
name='leave'
),
url(
r'(?P<slug>[-_\w+]+)/manage/$',
TeamManageView.as_view(),
name='manage'
),
# this has to be the last url in the list
url(
r'(?P<slug>[-_\w+]+)/$',
TeamDetailView.as_view(),
name='detail'
),
]

View file

@ -1,7 +1,7 @@
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, FormView from django.views.generic.edit import UpdateView, FormView
from camps.mixins import CampViewMixin from camps.mixins import CampViewMixin
from .models import Team, TeamMember from .models import Team, TeamMember, TeamTask
from .forms import ManageTeamForm from .forms import ManageTeamForm
from .email import add_added_membership_email, add_removed_membership_email from .email import add_added_membership_email, add_removed_membership_email
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
@ -62,22 +62,22 @@ class TeamJoinView(LoginRequiredMixin, CampViewMixin, UpdateView):
request, request,
"Please fill the description in your profile before joining a team" "Please fill the description in your profile before joining a team"
) )
return redirect('team_list', camp_slug=self.camp.slug) return redirect('teams:list', camp_slug=self.camp.slug)
if request.user in self.get_object().members.all(): if request.user in self.get_object().members.all():
messages.warning(request, "You are already a member of this team") messages.warning(request, "You are already a member of this team")
return redirect('team_list', camp_slug=self.camp.slug) return redirect('teams:list', camp_slug=self.camp.slug)
if not self.get_object().needs_members: if not self.get_object().needs_members:
messages.warning(request, "This team does not need members right now") messages.warning(request, "This team does not need members right now")
return redirect('team_list', camp_slug=self.get_object().camp.slug) return redirect('teams:list', camp_slug=self.get_object().camp.slug)
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def form_valid(self, form): def form_valid(self, form):
TeamMember.objects.create(team=self.get_object(), user=self.request.user) TeamMember.objects.create(team=self.get_object(), user=self.request.user)
messages.success(self.request, "You request to join the team %s has been registered, thank you." % self.get_object().name) messages.success(self.request, "You request to join the team %s has been registered, thank you." % self.get_object().name)
return redirect('team_list', camp_slug=self.get_object().camp.slug) return redirect('teams:list', camp_slug=self.get_object().camp.slug)
class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView): class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView):
@ -88,14 +88,14 @@ class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if request.user not in self.get_object().members.all(): if request.user not in self.get_object().members.all():
messages.warning(request, "You are not a member of this team") messages.warning(request, "You are not a member of this team")
return redirect('team_list', camp_slug=self.get_object().camp.slug) return redirect('teams:list', camp_slug=self.get_object().camp.slug)
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def form_valid(self, form): def form_valid(self, form):
TeamMember.objects.filter(team=self.get_object(), user=self.request.user).delete() TeamMember.objects.filter(team=self.get_object(), user=self.request.user).delete()
messages.success(self.request, "You are no longer a member of the team %s" % self.get_object().name) messages.success(self.request, "You are no longer a member of the team %s" % self.get_object().name)
return redirect('team_list', camp_slug=self.get_object().camp.slug) return redirect('teams:list', camp_slug=self.get_object().camp.slug)
class EnsureTeamMemberResponsibleMixin(SingleObjectMixin): class EnsureTeamMemberResponsibleMixin(SingleObjectMixin):
@ -145,3 +145,9 @@ class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberR
) )
return redirect('team_detail', camp_slug=self.camp.slug, slug=form.instance.team.slug) return redirect('team_detail', camp_slug=self.camp.slug, slug=form.instance.team.slug)
class TaskDetailView(CampViewMixin, DetailView):
template_name = "task_detail.html"
context_object_name = "task"
model = TeamTask

View file

@ -91,7 +91,7 @@
<a class="btn {% menubuttonclass 'program' %}" href="{% url 'schedule_index' camp_slug=camp.slug %}">Program</a> <a class="btn {% menubuttonclass 'program' %}" href="{% url 'schedule_index' camp_slug=camp.slug %}">Program</a>
<a class="btn {% menubuttonclass 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</a> <a class="btn {% menubuttonclass 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</a>
<a class="btn {% menubuttonclass 'sponsors' %}" href="{% url 'sponsors' camp_slug=camp.slug %}">Sponsors</a> <a class="btn {% menubuttonclass 'sponsors' %}" href="{% url 'sponsors' camp_slug=camp.slug %}">Sponsors</a>
<a class="btn {% menubuttonclass 'teams' %}" href="{% url 'team_list' camp_slug=camp.slug %}">Teams</a> <a class="btn {% menubuttonclass 'teams' %}" href="{% url 'teams:list' camp_slug=camp.slug %}">Teams</a>
</div> </div>
<div class="btn-group-vertical visible-xs"> <div class="btn-group-vertical visible-xs">
<a class="btn {% menubuttonclass 'camps' %}" href="{% url 'camp_detail' camp_slug=camp.slug %}">{{ camp.title }}</a> <a class="btn {% menubuttonclass 'camps' %}" href="{% url 'camp_detail' camp_slug=camp.slug %}">{{ camp.title }}</a>
@ -99,7 +99,7 @@
<a class="btn {% menubuttonclass 'program' %}" href="{% url 'schedule_index' camp_slug=camp.slug %}">Program</a> <a class="btn {% menubuttonclass 'program' %}" href="{% url 'schedule_index' camp_slug=camp.slug %}">Program</a>
<a class="btn {% menubuttonclass 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</a> <a class="btn {% menubuttonclass 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</a>
<a class="btn {% menubuttonclass 'sponsors' %}" href="{% url 'sponsors' camp_slug=camp.slug %}">Sponsors</a> <a class="btn {% menubuttonclass 'sponsors' %}" href="{% url 'sponsors' camp_slug=camp.slug %}">Sponsors</a>
<a class="btn {% menubuttonclass 'teams' %}" href="{% url 'team_list' camp_slug=camp.slug %}">Teams</a> <a class="btn {% menubuttonclass 'teams' %}" href="{% url 'teams:list' camp_slug=camp.slug %}">Teams</a>
</div> </div>
<p> <p>
</div> </div>