mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 07:11:08 -05:00
Improve moderation dashboard UI and HTMX integration:
- Create partial templates for dashboard, edit submissions, and photo submissions - Update views to properly handle HTMX requests - Fix duplicate UI issues when navigating - Improve overall UI design and transitions
This commit is contained in:
@@ -7,7 +7,7 @@ from django.template.loader import render_to_string
|
||||
from django.db.models import Q
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from typing import Optional, Any, cast
|
||||
from accounts.models import User # Import custom User model
|
||||
from accounts.models import User
|
||||
|
||||
from .models import EditSubmission, PhotoSubmission
|
||||
|
||||
@@ -30,7 +30,10 @@ class ModeratorRequiredMixin(UserPassesTestMixin):
|
||||
raise PermissionDenied("You do not have moderator permissions.")
|
||||
|
||||
class DashboardView(LoginRequiredMixin, ModeratorRequiredMixin, TemplateView):
|
||||
template_name = 'moderation/dashboard.html'
|
||||
def get_template_names(self):
|
||||
if self.request.headers.get('HX-Request'):
|
||||
return ['moderation/partials/dashboard_content.html']
|
||||
return ['moderation/dashboard.html']
|
||||
|
||||
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||
context = super().get_context_data(**kwargs)
|
||||
@@ -60,9 +63,13 @@ class EditSubmissionListView(LoginRequiredMixin, ModeratorRequiredMixin, ListVie
|
||||
return queryset
|
||||
|
||||
class PhotoSubmissionListView(LoginRequiredMixin, ModeratorRequiredMixin, ListView):
|
||||
template_name = 'moderation/photo_submission_list.html'
|
||||
context_object_name = 'submissions'
|
||||
|
||||
def get_template_names(self):
|
||||
if self.request.headers.get('HX-Request'):
|
||||
return ['moderation/partials/photo_submission_content.html']
|
||||
return ['moderation/photo_submission_list.html']
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = PhotoSubmission.objects.all().order_by('-created_at')
|
||||
|
||||
@@ -71,18 +78,6 @@ class PhotoSubmissionListView(LoginRequiredMixin, ModeratorRequiredMixin, ListVi
|
||||
|
||||
return queryset
|
||||
|
||||
def _update_submission_notes(submission: EditSubmission, notes: Optional[str]) -> None:
|
||||
"""Update submission notes if provided."""
|
||||
if notes:
|
||||
submission.notes = notes
|
||||
submission.save()
|
||||
|
||||
def _render_submission_response(template: str, submission: Any, request: HttpRequest) -> HttpResponse:
|
||||
"""Render submission template response."""
|
||||
context = {'submission': submission}
|
||||
html = render_to_string(template, context, request=request)
|
||||
return HttpResponse(html)
|
||||
|
||||
@login_required
|
||||
def submission_list(request: HttpRequest) -> HttpResponse:
|
||||
"""HTMX endpoint for filtered submission list"""
|
||||
@@ -174,3 +169,15 @@ def reject_photo(request: HttpRequest, submission_id: int) -> HttpResponse:
|
||||
submission.reject(user, request.POST.get('notes', ''))
|
||||
|
||||
return _render_submission_response('moderation/partials/photo_submission.html', submission, request)
|
||||
|
||||
def _update_submission_notes(submission: EditSubmission, notes: Optional[str]) -> None:
|
||||
"""Update submission notes if provided."""
|
||||
if notes:
|
||||
submission.notes = notes
|
||||
submission.save()
|
||||
|
||||
def _render_submission_response(template: str, submission: Any, request: HttpRequest) -> HttpResponse:
|
||||
"""Render submission template response."""
|
||||
context = {'submission': submission}
|
||||
html = render_to_string(template, context, request=request)
|
||||
return HttpResponse(html)
|
||||
|
||||
62
templates/moderation/partials/dashboard_content.html
Normal file
62
templates/moderation/partials/dashboard_content.html
Normal file
@@ -0,0 +1,62 @@
|
||||
{% load static %}
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-3">
|
||||
<div class="p-6 transition-shadow duration-200 bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50 hover:shadow-xl">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-medium text-gray-900 dark:text-white">Pending Reviews</h3>
|
||||
<span class="px-3 py-1 text-sm font-medium text-yellow-800 bg-yellow-100 rounded-full dark:bg-yellow-900/50 dark:text-yellow-200">
|
||||
{{ submissions|length }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Submissions awaiting moderation</p>
|
||||
</div>
|
||||
|
||||
<div class="p-6 transition-shadow duration-200 bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50 hover:shadow-xl">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-medium text-gray-900 dark:text-white">Recent Activity</h3>
|
||||
<i class="text-gray-400 fas fa-history"></i>
|
||||
</div>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Latest moderation actions</p>
|
||||
</div>
|
||||
|
||||
<div class="p-6 transition-shadow duration-200 bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50 hover:shadow-xl">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-medium text-gray-900 dark:text-white">Quick Actions</h3>
|
||||
<i class="text-gray-400 fas fa-bolt"></i>
|
||||
</div>
|
||||
<div class="mt-4 space-y-2">
|
||||
<a href="{% url 'moderation:edit_submissions' %}"
|
||||
class="block px-4 py-2 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700"
|
||||
hx-get="{% url 'moderation:edit_submissions' %}"
|
||||
hx-target="#submissions-content"
|
||||
hx-push-url="true">
|
||||
<i class="mr-2 fas fa-edit"></i> Review Edit Submissions
|
||||
</a>
|
||||
<a href="{% url 'moderation:photo_submissions' %}"
|
||||
class="block px-4 py-2 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700"
|
||||
hx-get="{% url 'moderation:photo_submissions' %}"
|
||||
hx-target="#submissions-content"
|
||||
hx-push-url="true">
|
||||
<i class="mr-2 fas fa-image"></i> Review Photo Submissions
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50">
|
||||
<div class="p-6">
|
||||
<h3 class="mb-4 text-lg font-medium text-gray-900 dark:text-white">Recent Submissions</h3>
|
||||
<div class="space-y-4">
|
||||
{% for submission in submissions %}
|
||||
{% include "moderation/partials/submission_list.html" %}
|
||||
{% empty %}
|
||||
<div class="py-8 text-center">
|
||||
<i class="mb-3 text-4xl text-green-500 fas fa-check-circle"></i>
|
||||
<p class="text-gray-600 dark:text-gray-400">No pending submissions</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
23
templates/moderation/partials/photo_submission_content.html
Normal file
23
templates/moderation/partials/photo_submission_content.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{% load static %}
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="p-6 bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="text-lg font-medium text-gray-900 dark:text-white">Photo Submissions</h3>
|
||||
<span class="px-3 py-1 text-sm font-medium text-yellow-800 bg-yellow-100 rounded-full dark:bg-yellow-900/50 dark:text-yellow-200">
|
||||
{{ submissions|length }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
{% for submission in submissions %}
|
||||
{% include "moderation/partials/photo_submission.html" %}
|
||||
{% empty %}
|
||||
<div class="py-8 text-center col-span-full">
|
||||
<i class="mb-3 text-4xl text-gray-400 fas fa-camera"></i>
|
||||
<p class="text-gray-600 dark:text-gray-400">No photo submissions found</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,16 +1,7 @@
|
||||
{% extends "moderation/dashboard.html" %}
|
||||
|
||||
{% block moderation_content %}
|
||||
<div id="submissions-content" class="submission-list">
|
||||
{% for submission in submissions %}
|
||||
{% include "moderation/partials/photo_submission.html" %}
|
||||
{% empty %}
|
||||
<div class="p-8 text-center bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50">
|
||||
<div class="text-gray-500 dark:text-gray-400">
|
||||
<i class="mb-3 text-4xl fas fa-camera"></i>
|
||||
<p>No photo submissions found.</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div id="submissions-content">
|
||||
{% include "moderation/partials/photo_submission_content.html" %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user