Skip to content

Commit

Permalink
Added feature that lets logged-in users edit the information on their…
Browse files Browse the repository at this point in the history
… own profile page. This partly resolves issue #194, if not completely.
  • Loading branch information
filiptypjeu committed Sep 22, 2024
1 parent 7cf770f commit f859776
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 42 deletions.
14 changes: 14 additions & 0 deletions teknologr/katalogen/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

from members.models import Member
from members.forms import BSModelForm
from members.validators import CommonValidators
from ldap import LDAPError

class EditProfileForm(BSModelForm, CommonValidators):
class Meta:
model = Member
fields = ['phone', 'email', 'street_address', 'postal_code', 'city', 'country', 'subscribed_to_modulen', 'allow_studentbladet', 'allow_publish_info']

def clean(self):
BSModelForm.clean(self)
CommonValidators.clean(self)
4 changes: 4 additions & 0 deletions teknologr/katalogen/static/css/katalogen.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
font-weight: bold;
}

#member-information button {
margin-bottom: 20px;
}

.monospace {
font-family: monospace;
}
Expand Down
144 changes: 103 additions & 41 deletions teknologr/katalogen/templates/profile_information.html
Original file line number Diff line number Diff line change
@@ -1,65 +1,104 @@

<div class="col-12 col-lg-7">
<div
id="member-information"
class="col-12 col-lg-7"
hx-target="#member-information"
hx-swap="outerHTML"
>
<table class="table table-striped table-borderless">
<tbody>
{% if show_all %}
<tr>
<th>Tilltalsnamn</th>
<td class="text-right">{{person.preferred_name}}</td>
<th>
Tilltalsnamn
{{ form.preferred_name.errors }}
</th>
<td class="text-right">
{% firstof form.preferred_name person.preferred_name %}
</td>
</tr>
<tr>
<th>Telefonnummer</th>
<td class="text-right">{{person.phone}}</td>
<th>
Telefonnummer
{{ form.phone.errors }}
</th>
<td class="text-right">
{% firstof form.phone person.phone %}
</td>
</tr>
<tr>
<th>E-postadress</th>
<td class="text-right">{{person.email}}</td>
<th>
E-postadress
{{ form.email.errors }}
</th>
<td class="text-right">
{% firstof form.email person.email %}
</td>
</tr>
<tr>
<th>Hemadress</th>
<th>
Hemadress
{{ form.street_address.errors }}
</th>
{% if form %}
<td class="text-left">
Gatuadress {% firstof form.street_address person.street_address %}
Postnummer {% firstof form.postal_code person.postal_code %}
Postanstalt {% firstof form.city person.city %}
Land {% firstof form.country person.country %}
</td>
{% else %}
<td class="text-right">
{{person.street_address}}<br/>
{{person.postal_code}} {{person.city}}<br/>
{{person.country.name}}
{{ person.full_address }}
</td>
{% endif %}
</tr>
<tr>
<th>Studieprogram</th>
<td class="text-right">{{person.degree_programme}}</td>
<th>
Studieprogram
{{ form.degree_programme.errors }}
</th>
<td class="text-right">
{% firstof form.degree_programme person.degree_programme %}
</td>
</tr>
<tr>
<th>Phuxår</th>
<th>
Phuxår
{{ form.phux_year.errors }}
</th>
<td class="text-right">
{{ person.phux_year|default_if_none:'' }}
{% firstof form.phux_year person.phux_year %}
</td>
</tr>
<tr>
<th>Färdigbliven</th>
<th>
Färdigbliven
{{ form.graduated.errors }}
</th>
<td class="text-right">
{% if person.graduated %}
{% if person.graduated_year %}
{{person.graduated_year}}
{% else %}
Ja
{% endif %}
{% else %}
Nej
{% endif %}
{% firstof form.graduated person.graduated_text %}
</td>
</tr>
{% endif %}

{% if own_profile %}
<tr>
<th>Födelsedatum</th>
<th>
Födelsedatum
{{ form.birth_date.errors }}
</th>
<td class="text-right">
{{ person.birth_date|default:'' }}
{% firstof form.birth_date person.birth_date %}
</td>
</tr>
<tr>
<th>Studienummer</th>
<th>
Studienummer
{{ form.student_id.errors }}
</th>
<td class="text-right">
{{ person.student_id|default:'' }}
{% firstof form.student_id person.student_id %}
</td>
</tr>
<tr>
Expand All @@ -75,35 +114,58 @@
</td>
</tr>
<tr>
<th>Prenumerera på Modulen</th>
<th>
Prenumerera på Modulen
{{ form.subscribed_to_modulen.errors }}
</th>
<td class="text-right">
{{person.subscribed_to_modulen_text}}
{% firstof form.subscribed_to_modulen person.subscribed_to_modulen_text %}
</td>
</tr>
<tr>
<th>Prenumerera på Studentbladet</th>
<th>
Prenumerera på Studentbladet
{{ form.allow_studentbladet.errors }}
</th>
<td class="text-right">
{{ person.allow_studentbladet_text }}
{% firstof form.allow_studentbladet person.allow_studentbladet_text %}
</td>
</tr>
<tr>
<th>Visa kontaktinformation</th>
<th>
Visa kontaktinformation
{{ form.allow_publish_info.errors }}
</th>
<td class="text-right">
{{ person.allow_publish_info_text }}
{% firstof form.allow_publish_info person.allow_publish_info_text %}
</td>
</tr>
{% endif %}

<tr>
<th>Medlemskapstyp</th>
<td class="text-right">
{% if person.current_member_type %}
{{ person.current_member_type }}
{% else %}
Ej medlem
{% endif %}
{{ person.current_member_type|default:'Ej medlem' }}
</td>
</tr>
</tbody>
</table>
</div>

{% if form %}
<button
class="btn btn-success"
hx-post={% url "katalogen:profile_edit" person.id %}
hx-include="#member-information"
>Spara</button>
<button
class="btn btn-primary"
hx-get={% url "katalogen:profile_info" person.id %}
>Ångra</button>
{% elif own_profile %}
<button
class="btn btn-primary"
hx-get={% url "katalogen:profile_edit" person.id %}
>Editera</button>
{% endif %}

</div>
2 changes: 2 additions & 0 deletions teknologr/katalogen/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
url(r'^([A-ZÅÄÖ])/$', views.startswith, name='startswith'),
url(r'^members/$', views.home),
url(r'^members/(\d+)/$', views.profile, name='profile'),
url(r'^members/(\d+)/info$', views.profile_info, name='profile_info'),
url(r'^members/(\d+)/edit$', views.profile_edit, name='profile_edit'),
url(r'^person/(\d+)/$', views.profile),
url(r'^profile/$', views.myprofile, name='myprofile'),
url(r'^decorations/$', views.decorations, name='decorations'),
Expand Down
50 changes: 50 additions & 0 deletions teknologr/katalogen/views.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.db.models.functions import TruncYear
from members.models import *
from members.utils import *
from katalogen.forms import EditProfileForm
from katalogen.utils import *
from django.db.models import Q, Count
from functools import reduce
from operator import and_
from collections import defaultdict
from ldap import LDAPError

def own_profile_or_403(request, member):
'''
Function for checking if the logged in user is a certain Member.
'''
if request.user.username != member.username:
raise PermissionDenied()

def _get_base_context(request):
return {
Expand Down Expand Up @@ -79,6 +88,47 @@ def profile(request, member_id):
'decoration_ownerships': person.decoration_ownerships_by_date,
})

@login_required
def profile_info(request, member_id):
"""
Only render the member information section, not the decorations etc., so no need to prefetch the extra info.
"""

member = get_object_or_404(Member, id=member_id)
own_profile = member.username == request.user.username

return render(request, 'profile_information.html', {
'own_profile': own_profile,
'show_all': own_profile or member.showContactInformation(),
'person': member,
})

@login_required
def profile_edit(request, member_id):
"""
Update the member information. This can only be done by the user himself. Returns only the HTML for the member information, not the decorations etc. This makes it possible for HTMX to swap only part of the page when saving the info.
"""

member = Member.objects.get_prefetched_or_404(member_id)
own_profile_or_403(request, member)

if request.method == 'POST':
form = EditProfileForm(request.POST, instance=member)
if form.is_valid():
try:
form.save()
form = None
except LDAPError:
form.add_error('email', 'E-postadressen kunde tyvärr inte uppdateras, vänligen kontakta en administrator')
else:
form = EditProfileForm(instance=member)

return render(request, 'profile_information.html', {
'form': form,
'own_profile': True,
'show_all': True,
'person': member,
})

@login_required
def startswith(request, letter):
Expand Down
10 changes: 9 additions & 1 deletion teknologr/members/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,15 @@ def full_address(self):
country = str(self.country.name)
city = f'{self.postal_code} {self.city}'.strip()
address_parts = [self.street_address, city, country]
return ", ".join([s for s in address_parts if s])
address = ", ".join([s for s in address_parts if s])
# Do not show only country
return address if address != country else ''

@property
def graduated_text(self):
if self.graduated_year:
return str(self.graduated_year)
return "Ja" if self.graduated else "Nej"

@property
def subscribed_to_modulen_text(self):
Expand Down

0 comments on commit f859776

Please sign in to comment.