diff --git a/moderation/views.py b/moderation/views.py index f0aa9cfc..42f47a1c 100644 --- a/moderation/views.py +++ b/moderation/views.py @@ -183,6 +183,14 @@ def submission_list(request: HttpRequest) -> HttpResponse: if content_type := request.GET.get('content_type'): queryset = queryset.filter(content_type__model=content_type) + # Get park areas for each park submission + park_areas_by_park = {} + for submission in queryset: + if submission.content_type.model == 'park' and submission.changes.get('park'): + park_id = submission.changes['park'] + if park_id not in park_areas_by_park: + park_areas_by_park[park_id] = [(a.id, str(a)) for a in ParkArea.objects.filter(park_id=park_id)] + context = { 'submissions': queryset, 'user': request.user, @@ -190,7 +198,8 @@ def submission_list(request: HttpRequest) -> HttpResponse: 'designers': [(d.id, str(d)) for d in Designer.objects.all()], 'manufacturers': [(m.id, str(m)) for m in Manufacturer.objects.all()], 'ride_models': [(m.id, str(m)) for m in RideModel.objects.all()], - 'owners': [(u.id, str(u)) for u in User.objects.filter(role__in=['OWNER', 'ADMIN', 'SUPERUSER'])] + 'owners': [(u.id, str(u)) for u in User.objects.filter(role__in=['OWNER', 'ADMIN', 'SUPERUSER'])], + 'park_areas_by_park': park_areas_by_park } # If it's an HTMX request, return just the content @@ -302,36 +311,42 @@ def reject_submission(request: HttpRequest, submission_id: int) -> HttpResponse: """HTMX endpoint for rejecting a submission""" user = cast(User, request.user) submission = get_object_or_404(EditSubmission, id=submission_id) - + if submission.status == 'ESCALATED' and not (user.role in ['ADMIN', 'SUPERUSER'] or user.is_superuser): return HttpResponse("Only admins can handle escalated submissions", status=403) if not (user.role in MODERATOR_ROLES or user.is_superuser): return HttpResponse(status=403) - + submission.reject(user) _update_submission_notes(submission, request.POST.get('notes')) - + # Get updated queryset with filters status = request.GET.get('status', 'PENDING') submission_type = request.GET.get('submission_type', '') - + if submission_type == 'photo': queryset = PhotoSubmission.objects.filter(status=status).order_by('-created_at') else: queryset = EditSubmission.objects.filter(status=status).order_by('-created_at') - + if type_filter := request.GET.get('type'): queryset = queryset.filter(submission_type=type_filter) - + if content_type := request.GET.get('content_type'): queryset = queryset.filter(content_type__model=content_type) - + context = { - 'submissions': queryset, + 'submission': submission, 'user': request.user, + 'parks': [(p.id, str(p)) for p in Park.objects.all()], + 'designers': [(d.id, str(d)) for d in Designer.objects.all()], + 'manufacturers': [(m.id, str(m)) for m in Manufacturer.objects.all()], + 'ride_models': [(m.id, str(m)) for m in RideModel.objects.all()], + 'owners': [(u.id, str(u)) for u in User.objects.filter(role__in=['OWNER', 'ADMIN', 'SUPERUSER'])], + 'park_areas': [(a.id, str(a)) for a in ParkArea.objects.filter(park_id=submission.changes.get('park'))] if submission.changes.get('park') else [] } - - return render(request, 'moderation/partials/dashboard_content.html', context) + return render(request, 'moderation/partials/submission_list.html', context) + @login_required def escalate_submission(request: HttpRequest, submission_id: int) -> HttpResponse: @@ -339,35 +354,36 @@ def escalate_submission(request: HttpRequest, submission_id: int) -> HttpRespons user = cast(User, request.user) if not (user.role in MODERATOR_ROLES or user.is_superuser): return HttpResponse(status=403) - + submission = get_object_or_404(EditSubmission, id=submission_id) - if submission.status == 'ESCALATED': + if submission.status == "ESCALATED": return HttpResponse("Submission is already escalated", status=400) - + submission.escalate(user) - _update_submission_notes(submission, request.POST.get('notes')) - + _update_submission_notes(submission, request.POST.get("notes")) + # Get updated queryset with filters - status = request.GET.get('status', 'PENDING') - submission_type = request.GET.get('submission_type', '') - - if submission_type == 'photo': - queryset = PhotoSubmission.objects.filter(status=status).order_by('-created_at') + status = request.GET.get("status", "PENDING") + submission_type = request.GET.get("submission_type", "") + + if submission_type == "photo": + queryset = PhotoSubmission.objects.filter(status=status).order_by("-created_at") else: - queryset = EditSubmission.objects.filter(status=status).order_by('-created_at') - - if type_filter := request.GET.get('type'): + queryset = EditSubmission.objects.filter(status=status).order_by("-created_at") + + if type_filter := request.GET.get("type"): queryset = queryset.filter(submission_type=type_filter) - - if content_type := request.GET.get('content_type'): + + if content_type := request.GET.get("content_type"): queryset = queryset.filter(content_type__model=content_type) - + context = { - 'submissions': queryset, - 'user': request.user, + "submissions": queryset, + "user": request.user, } - - return render(request, 'moderation/partials/dashboard_content.html', context) + + return render(request, "moderation/partials/dashboard_content.html", context) + @login_required def approve_photo(request: HttpRequest, submission_id: int) -> HttpResponse: @@ -375,26 +391,34 @@ def approve_photo(request: HttpRequest, submission_id: int) -> HttpResponse: user = cast(User, request.user) if not (user.role in MODERATOR_ROLES or user.is_superuser): return HttpResponse(status=403) - + submission = get_object_or_404(PhotoSubmission, id=submission_id) - + try: - submission.approve(user, request.POST.get('notes', '')) - return render(request, 'moderation/partials/photo_submission.html', {'submission': submission}) + submission.approve(user, request.POST.get("notes", "")) + return render( + request, + "moderation/partials/photo_submission.html", + {"submission": submission}, + ) except Exception as e: return HttpResponse(str(e), status=400) + @login_required def reject_photo(request: HttpRequest, submission_id: int) -> HttpResponse: """HTMX endpoint for rejecting a photo submission""" user = cast(User, request.user) if not (user.role in MODERATOR_ROLES or user.is_superuser): return HttpResponse(status=403) - + submission = get_object_or_404(PhotoSubmission, id=submission_id) - submission.reject(user, request.POST.get('notes', '')) - - return render(request, 'moderation/partials/photo_submission.html', {'submission': submission}) + submission.reject(user, request.POST.get("notes", "")) + + return render( + request, "moderation/partials/photo_submission.html", {"submission": submission} + ) + def _update_submission_notes(submission: EditSubmission, notes: Optional[str]) -> None: """Update submission notes if provided.""" diff --git a/static/css/tailwind.css b/static/css/tailwind.css index 9567116a..c7d164cb 100644 --- a/static/css/tailwind.css +++ b/static/css/tailwind.css @@ -2181,6 +2181,10 @@ select { justify-content: center; } +.visible { + visibility: visible; +} + .static { position: static; } @@ -2304,6 +2308,11 @@ select { margin-right: auto; } +.my-auto { + margin-top: auto; + margin-bottom: auto; +} + .-mb-px { margin-bottom: -1px; } @@ -2500,10 +2509,6 @@ select { max-height: 90vh; } -.min-h-\[calc\(100vh-16rem\)\] { - min-height: calc(100vh - 16rem); -} - .min-h-screen { min-height: 100vh; } @@ -3033,6 +3038,10 @@ select { background-color: rgb(220 38 38 / var(--tw-bg-opacity)); } +.bg-red-900\/40 { + background-color: rgb(127 29 29 / 0.4); +} + .bg-white { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); @@ -3065,6 +3074,10 @@ select { background-color: rgb(202 138 4 / var(--tw-bg-opacity)); } +.bg-yellow-900\/40 { + background-color: rgb(113 63 18 / 0.4); +} + .bg-opacity-50 { --tw-bg-opacity: 0.5; } @@ -3392,6 +3405,11 @@ select { color: rgb(79 70 229 / var(--tw-text-opacity)); } +.text-red-400 { + --tw-text-opacity: 1; + color: rgb(248 113 113 / var(--tw-text-opacity)); +} + .text-red-500 { --tw-text-opacity: 1; color: rgb(239 68 68 / var(--tw-text-opacity)); @@ -4313,6 +4331,11 @@ select { margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); } + .md\:py-12 { + padding-top: 3rem; + padding-bottom: 3rem; + } + .md\:text-2xl { font-size: 1.5rem; line-height: 2rem; diff --git a/templates/moderation/partials/submission_list.html b/templates/moderation/partials/submission_list.html index 4cd0bab7..3e9ceab2 100644 --- a/templates/moderation/partials/submission_list.html +++ b/templates/moderation/partials/submission_list.html @@ -5,8 +5,445 @@ {% endblock %} - -{{ existing_content_until_approve_button|safe }} +{% for submission in submissions %} +