feat: Add dedicated notification page

This commit is contained in:
2025-07-12 14:01:40 +02:00
parent bbfd4c3800
commit e2bef3efe2
4 changed files with 56 additions and 11 deletions

View File

@@ -33,7 +33,7 @@
{% if user.is_authenticated %}
<div class="navbar-item">
<div class="notification-container">
<a class="notification-label" href="{% url 'user-me' %}">
<a class="notification-label" href="{% url 'user-notifications' %}">
<i class="fas fa-bell fa-fw"></i>
</a>
{% if request.user.get_num_unread_notifications > 0 %}

View File

@@ -0,0 +1,19 @@
{% extends "fellchensammlung/base.html" %}
{% load i18n %}
{% block title %}<title>{% trans 'Benachrichtigungen' %}</title>{% endblock %}
{% block content %}
<div class="block">
<h1 class="title is-1">{% translate 'Benachrichtigungen' %}</h1>
{% with notifications=notifications_unread %}
{% include "fellchensammlung/lists/list-notifications.html" %}
{% endwith %}
</div>
<div class="block">
<h2 class="title is-2">{% translate 'Zuletzt gelesene Benachrichtigungen' %}</h2>
{% with notifications=notifications_read_last %}
{% include "fellchensammlung/lists/list-notifications.html" %}
{% endwith %}
</div>
{% endblock %}

View File

@@ -75,6 +75,7 @@ urlpatterns = [
# ex: user/1
path("user/<int:user_id>/", views.user_by_id, name="user-detail"),
path("user/me/", views.my_profile, name="user-me"),
path("user/notifications/", views.my_notifications, name="user-notifications"),
path('user/me/export/', views.export_own_profile, name='user-me-export'),
path('accounts/register/',

View File

@@ -549,6 +549,27 @@ def user_by_id(request, user_id):
return user_detail(request, user)
def process_notification_actions(request, action):
"""
As multiple views allow to mark notifications as read, this function can be used to process these actions
The function allows users to mark only their own notifications as read.
"""
if action == "notification_mark_read":
notification_id = request.POST.get("notification_id")
notification = Notification.objects.get(pk=notification_id)
# Ensures a user can only mark their own notifications as read
if not notification.user_to_notify == request.user:
return render(request, "fellchensammlung/errors/403.html", status=403)
notification.mark_read()
elif action == "notification_mark_all_read":
notifications = Notification.objects.filter(user=request.user, mark_read=False)
for notification in notifications:
notification.mark_read()
return None
@login_required()
def my_profile(request):
if request.method == 'POST':
@@ -562,16 +583,8 @@ def my_profile(request):
user.save()
action = request.POST.get("action")
if action == "notification_mark_read":
notification_id = request.POST.get("notification_id")
notification = Notification.objects.get(pk=notification_id)
notification.mark_read()
elif action == "notification_mark_all_read":
notifications = Notification.objects.filter(user=request.user, mark_read=False)
for notification in notifications:
notification.mark_read()
elif action == "search_subscription_delete":
process_notification_actions(request, action)
if action == "search_subscription_delete":
search_subscription_id = request.POST.get("search_subscription_id")
SearchSubscription.objects.get(pk=search_subscription_id).delete()
logging.info(f"Deleted subscription {search_subscription_id}")
@@ -583,6 +596,18 @@ def my_profile(request):
return user_detail(request, request.user, token)
@login_required()
def my_notifications(request):
if request.method == 'POST':
action = request.POST.get("action")
process_notification_actions(request, action)
context = {"notifications_unread": Notification.objects.filter(user_to_notify=request.user, read=False),
"notifications_read_last": Notification.objects.filter(user_to_notify=request.user,
read=True).order_by("-read_at") }
return render(request, 'fellchensammlung/notifications.html', context=context)
@user_passes_test(user_is_trust_level_or_above)
def modqueue(request):
open_reports = Report.objects.select_related("reportadoptionnotice", "reportcomment").filter(status=Report.WAITING)