diff --git a/cfp/templates/cfp/staff/base.html b/cfp/templates/cfp/staff/base.html
index 37986c0..cd38fa9 100644
--- a/cfp/templates/cfp/staff/base.html
+++ b/cfp/templates/cfp/staff/base.html
@@ -7,8 +7,8 @@
{{ block.super }}
-{% empty %}{% trans "No talks" %}
+{% empty %}
+
{% trans "No talks" %}
{% endfor %}
+
+ {% trans "Add a talk" %}
+
{% trans "Messaging" %}
diff --git a/cfp/templates/cfp/staff/participant_form.html b/cfp/templates/cfp/staff/participant_form.html
index 997444b..fcdfb3e 100644
--- a/cfp/templates/cfp/staff/participant_form.html
+++ b/cfp/templates/cfp/staff/participant_form.html
@@ -5,7 +5,13 @@
{% block content %}
-
{% trans "Edit a speaker" %}
+
+ {% if participant %}
+ {% trans "Edit a speaker" %}
+ {% else %}
+ {% trans "Add a speaker" %}
+ {% endif %}
+
{% url 'participant-details' participant.token as cancel_url %}
{% include '_form.html' %}
diff --git a/cfp/templates/cfp/staff/participant_list.html b/cfp/templates/cfp/staff/participant_list.html
index 6edde20..3d3abd7 100644
--- a/cfp/templates/cfp/staff/participant_list.html
+++ b/cfp/templates/cfp/staff/participant_list.html
@@ -7,7 +7,14 @@
{% trans "Speakers" %}
-
{% trans "Show filtering options…" %}
+
+
+ {% bootstrap_icon "filter" %} {% trans "Show filtering options…" %}
+
+
+ {% bootstrap_icon "plus" %} {% trans "Add a speaker" %}
+
+
diff --git a/cfp/templates/cfp/staff/talk_form.html b/cfp/templates/cfp/staff/talk_form.html
index 74f02da..384f377 100644
--- a/cfp/templates/cfp/staff/talk_form.html
+++ b/cfp/templates/cfp/staff/talk_form.html
@@ -5,9 +5,16 @@
{% block content %}
-
{% trans "Edit a talk" %}
+
+ {% if talk %}
+ {% trans "Edit a talk" %}
+ {% url 'talk-details' talk.token as cancel_url %}
+ {% else %}
+ {% trans "Add a talk" %}
+ {% url 'participant-details' participant.token as cancel_url %}
+ {% endif %}
+
-{% url 'talk-details' talk.token as cancel_url %}
{% include '_form.html' with multipart=True %}
{% endblock %}
diff --git a/cfp/urls.py b/cfp/urls.py
index 1750474..f2b9c79 100644
--- a/cfp/urls.py
+++ b/cfp/urls.py
@@ -43,7 +43,9 @@ urlpatterns = [
url(r'^staff/talks/(?P
[\w\-]+)/desist/$', views.talk_acknowledgment, {'confirm': False}, name='talk-desist-by-staff'),
url(r'^staff/talks/(?P[\w\-]+)/edit/$', views.TalkUpdate.as_view(), name='talk-edit'),
url(r'^staff/speakers/$', views.participant_list, name='participant-list'),
+ url(r'^staff/speakers/add/$', views.ParticipantCreate.as_view(), name='participant-add'),
url(r'^staff/speakers/(?P[\w\-]+)/$', views.participant_details, name='participant-details'),
+ url(r'^staff/speakers/(?P[\w\-]+)/add-talk/$', views.participant_add_talk, name='participant-add-talk'),
url(r'^staff/speakers/(?P[\w\-]+)/edit/$', views.ParticipantUpdate.as_view(), name='participant-edit'),
url(r'^staff/tracks/$', views.TrackList.as_view(), name='track-list'),
url(r'^staff/tracks/add/$', views.TrackCreate.as_view(), name='track-add'),
diff --git a/cfp/views.py b/cfp/views.py
index 26d6109..c4156cc 100644
--- a/cfp/views.py
+++ b/cfp/views.py
@@ -755,6 +755,21 @@ def participant_details(request, participant_id):
})
+class ParticipantCreate(StaffRequiredMixin, OnSiteFormMixin, CreateView):
+ model = Participant
+ slug_field = 'token'
+ slug_url_kwarg = 'participant_id'
+ #form_class = ParticipantStaffForm
+ template_name = 'cfp/staff/participant_form.html'
+
+ def get_form_class(self):
+ return modelform_factory(
+ self.model,
+ form=ParticipantForm,
+ fields=['name', 'vip', 'email', 'phone_number', 'notes'] + ParticipantForm.SOCIAL_FIELDS,
+ )
+
+
class ParticipantUpdate(StaffRequiredMixin, OnSiteFormMixin, UpdateView):
model = Participant
slug_field = 'token'
@@ -770,6 +785,20 @@ class ParticipantUpdate(StaffRequiredMixin, OnSiteFormMixin, UpdateView):
)
+@staff_required
+def participant_add_talk(request, participant_id):
+ participant = get_object_or_404(Participant, site=request.conference.site, pk=participant_id)
+ form = TalkForm(request.POST or None, categories=TalkCategory.objects.filter(site=request.conference.site))
+ if request.method == 'POST' and form.is_valid():
+ talk = form.save()
+ talk.speakers.add(participant)
+ return redirect(reverse('talk-details', kwargs=dict(talk_id=talk.token)))
+ return render(request, 'cfp/staff/talk_form.html', {
+ 'form': form,
+ 'participant': participant,
+ })
+
+
@staff_required
def conference_edit(request):
form = ConferenceForm(request.POST or None, instance=request.conference)