From 3cf81a211026622eb74f0fecd4be9278a663a536 Mon Sep 17 00:00:00 2001
From: Tom Teichler <tom.teichler@teckids.org>
Date: Tue, 27 Oct 2020 17:47:37 +0100
Subject: [PATCH] Add form to edit persons photo. Closes #269

---
 aleksis/core/forms.py                         | 11 +++++++++
 .../templates/core/person/edit_photo.html     | 23 +++++++++++++++++++
 aleksis/core/templates/core/person/full.html  |  4 ++++
 aleksis/core/urls.py                          |  1 +
 aleksis/core/views.py                         | 22 ++++++++++++++++++
 5 files changed, 61 insertions(+)
 create mode 100644 aleksis/core/templates/core/person/edit_photo.html

diff --git a/aleksis/core/forms.py b/aleksis/core/forms.py
index e1c0be7ef..969cb4b22 100644
--- a/aleksis/core/forms.py
+++ b/aleksis/core/forms.py
@@ -7,6 +7,7 @@ from django.utils.translation import gettext_lazy as _
 
 from django_select2.forms import ModelSelect2MultipleWidget, Select2Widget
 from dynamic_preferences.forms import PreferenceForm
+from image_cropping import ImageCropWidget
 from material import Fieldset, Layout, Row
 
 from .mixins import ExtensibleForm, SchoolTermRelatedExtensibleForm
@@ -309,3 +310,13 @@ class SchoolTermForm(ExtensibleForm):
     class Meta:
         model = SchoolTerm
         exclude = []
+
+class EditPersonPhotoForm(ExtensibleForm):
+    """Form to edit a persons photo."""
+
+    class Meta:
+        model = Person
+        fields = ["photo"]
+        widgets = {
+            'photo': ImageCropWidget,
+        }
diff --git a/aleksis/core/templates/core/person/edit_photo.html b/aleksis/core/templates/core/person/edit_photo.html
new file mode 100644
index 000000000..17e6c79bc
--- /dev/null
+++ b/aleksis/core/templates/core/person/edit_photo.html
@@ -0,0 +1,23 @@
+{# -*- engine:django -*- #}
+
+{% extends "core/base.html" %}
+
+{% load i18n %}
+
+{% block extra_head %}
+  {{ photo_form.media }}
+{% endblock %}
+
+{% block browser_title %}{% blocktrans %}Edit photo{% endblocktrans %}{% endblock %}
+{% block page_title %}{% blocktrans %}Edit photo{% endblocktrans %}{% endblock %}
+
+
+{% block content %}
+
+  <form method="post" enctype="multipart/form-data">
+    {% csrf_token %}
+    {{ photo_form }}
+    {% include "core/partials/save_button.html" %}
+  </form>
+
+{% endblock %}
diff --git a/aleksis/core/templates/core/person/full.html b/aleksis/core/templates/core/person/full.html
index 80aff9b9f..41bd848bc 100644
--- a/aleksis/core/templates/core/person/full.html
+++ b/aleksis/core/templates/core/person/full.html
@@ -22,6 +22,10 @@
           <i class="material-icons left">edit</i>
           {% trans "Edit" %}
         </a>
+        <a href="{% url 'edit_person_photo_by_id' person.id %}" class="btn waves-effect waves-light">
+          <i class="material-icons left">insert_photo</i>
+          {% trans "Edit photo" %}
+        </a>
       {% endif %}
 
       {% if can_delete_person %}
diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py
index 51048e5c8..19c4a9c5b 100644
--- a/aleksis/core/urls.py
+++ b/aleksis/core/urls.py
@@ -32,6 +32,7 @@ urlpatterns = [
     path("person/create", views.edit_person, name="create_person"),
     path("person/<int:id_>", views.person, name="person_by_id"),
     path("person/<int:id_>/edit", views.edit_person, name="edit_person_by_id"),
+    path("person/<int:id_>/photo/edit", views.edit_person_photo, name="edit_person_photo_by_id"),
     path("person/<int:id_>/delete", views.delete_person, name="delete_person_by_id"),
     path("groups", views.groups, name="groups"),
     path("groups/additional_fields", views.additional_fields, name="additional_fields"),
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index af2f285a7..9ab49dfcb 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -678,3 +678,25 @@ def delete_group_type(request: HttpRequest, id_: int) -> HttpResponse:
     messages.success(request, _("The group type has been deleted."))
 
     return redirect("group_types")
+
+@permission_required("core.edit_person", fn=objectgetter_optional(Person))
+def edit_person_photo(request: HttpRequest, id_: Optional[int] = None) -> HttpResponse:
+    """Edit view for a single person, defaulting to logged-in person."""
+    context = {}
+
+    person = get_object_or_404(Person, id_)
+    context["person"] = person
+
+    # Edit form for existing group
+    edit_person_photo_form = EditPersonPhotoForm(
+        request.POST or None, request.FILES or None, instance=person
+    )
+    if request.method == "POST":
+        if edit_person_photo_form.is_valid():
+            with reversion.create_revision():
+                edit_person_photo_form.save(commit=True)
+            messages.success(request, _("The person has been saved."))
+
+    context["edit_person_photo_form"] = edit_person_photo_form
+
+    return render(request, "core/person/edit_photo.html", context)
-- 
GitLab