mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-23 11:31:09 -05:00
Improve moderation dashboard UI and functionality
- Add status tabs (Pending, Approved, Rejected, Escalated) - Implement HTMX for smooth tab switching and status changes - Add proper permissions for escalated submissions - Change Status filter to Submission Type (Text/Photo) - Move navigation into dashboard content - Fix tab menu visibility and transitions - Add contextual loading indicator - Update styling to match dark theme - Ensure consistent styling across components
This commit is contained in:
@@ -1,62 +1,120 @@
|
||||
{% 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="flex items-center p-4 space-x-4 bg-gray-900 rounded-lg">
|
||||
<a href="{% url 'moderation:submission_list' %}?status=NEW"
|
||||
class="flex items-center px-4 py-2.5 rounded-lg font-medium transition-all duration-200 {% if request.GET.status == 'NEW' or not request.GET.status %}bg-blue-900/40 text-blue-400{% else %}text-gray-400 hover:text-gray-300{% endif %}"
|
||||
hx-get="{% url 'moderation:submission_list' %}?status=NEW"
|
||||
hx-target="#dashboard-content"
|
||||
hx-push-url="true"
|
||||
hx-indicator="#loading-indicator">
|
||||
<i class="mr-2.5 text-lg fas fa-clock"></i>
|
||||
<span>Pending</span>
|
||||
</a>
|
||||
|
||||
<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>
|
||||
<a href="{% url 'moderation:submission_list' %}?status=APPROVED"
|
||||
class="flex items-center px-4 py-2.5 rounded-lg font-medium transition-all duration-200 {% if request.GET.status == 'APPROVED' %}bg-blue-900/40 text-blue-400{% else %}text-gray-400 hover:text-gray-300{% endif %}"
|
||||
hx-get="{% url 'moderation:submission_list' %}?status=APPROVED"
|
||||
hx-target="#dashboard-content"
|
||||
hx-push-url="true"
|
||||
hx-indicator="#loading-indicator">
|
||||
<i class="mr-2.5 text-lg fas fa-check"></i>
|
||||
<span>Approved</span>
|
||||
</a>
|
||||
|
||||
<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>
|
||||
<a href="{% url 'moderation:submission_list' %}?status=REJECTED"
|
||||
class="flex items-center px-4 py-2.5 rounded-lg font-medium transition-all duration-200 {% if request.GET.status == 'REJECTED' %}bg-blue-900/40 text-blue-400{% else %}text-gray-400 hover:text-gray-300{% endif %}"
|
||||
hx-get="{% url 'moderation:submission_list' %}?status=REJECTED"
|
||||
hx-target="#dashboard-content"
|
||||
hx-push-url="true"
|
||||
hx-indicator="#loading-indicator">
|
||||
<i class="mr-2.5 text-lg fas fa-times"></i>
|
||||
<span>Rejected</span>
|
||||
</a>
|
||||
|
||||
<a href="{% url 'moderation:submission_list' %}?status=ESCALATED"
|
||||
class="flex items-center px-4 py-2.5 rounded-lg font-medium transition-all duration-200 {% if request.GET.status == 'ESCALATED' %}bg-blue-900/40 text-blue-400{% else %}text-gray-400 hover:text-gray-300{% endif %}"
|
||||
hx-get="{% url 'moderation:submission_list' %}?status=ESCALATED"
|
||||
hx-target="#dashboard-content"
|
||||
hx-push-url="true"
|
||||
hx-indicator="#loading-indicator">
|
||||
<i class="mr-2.5 text-lg fas fa-exclamation-triangle"></i>
|
||||
<span>Escalated</span>
|
||||
</a>
|
||||
</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 class="p-6 bg-gray-900 rounded-lg">
|
||||
<form class="flex flex-wrap items-end gap-4 mb-6"
|
||||
hx-get="{% url 'moderation:submission_list' %}"
|
||||
hx-target="#dashboard-content"
|
||||
hx-trigger="change"
|
||||
hx-push-url="true">
|
||||
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-400">
|
||||
Submission Type
|
||||
</label>
|
||||
<select name="submission_type" class="w-full px-3 py-2 text-gray-300 bg-gray-800 border border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
<option value="">All Submissions</option>
|
||||
<option value="text" {% if request.GET.submission_type == 'text' %}selected{% endif %}>Text Submissions</option>
|
||||
<option value="photo" {% if request.GET.submission_type == 'photo' %}selected{% endif %}>Photo Submissions</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-400">
|
||||
Type
|
||||
</label>
|
||||
<select name="type" class="w-full px-3 py-2 text-gray-300 bg-gray-800 border border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
<option value="">All Types</option>
|
||||
<option value="CREATE" {% if request.GET.type == 'CREATE' %}selected{% endif %}>New Submissions</option>
|
||||
<option value="EDIT" {% if request.GET.type == 'EDIT' %}selected{% endif %}>Edit Submissions</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-400">
|
||||
Content Type
|
||||
</label>
|
||||
<select name="content_type" class="w-full px-3 py-2 text-gray-300 bg-gray-800 border border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
<option value="">All Content</option>
|
||||
<option value="park" {% if request.GET.content_type == 'park' %}selected{% endif %}>Parks</option>
|
||||
<option value="ride" {% if request.GET.content_type == 'ride' %}selected{% endif %}>Rides</option>
|
||||
<option value="company" {% if request.GET.content_type == 'company' %}selected{% endif %}>Companies</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="space-y-4">
|
||||
{% include "moderation/partials/submission_list.html" with submissions=submissions user=user %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="toast-success"
|
||||
class="fixed flex items-center w-full max-w-xs p-4 mb-4 text-gray-400 transition-all duration-300 transform translate-y-full bg-gray-800 rounded-lg shadow opacity-0 bottom-4 right-4"
|
||||
role="alert"
|
||||
x-data="{ show: false }"
|
||||
x-show="show"
|
||||
x-init="$watch('show', value => {
|
||||
if (value) {
|
||||
setTimeout(() => show = false, 3000);
|
||||
}
|
||||
})"
|
||||
@htmx:afterOnLoad="show = true"
|
||||
x-transition:enter="ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0 translate-y-full"
|
||||
x-transition:enter-end="opacity-100 translate-y-0"
|
||||
x-transition:leave="ease-in duration-200"
|
||||
x-transition:leave-start="opacity-100 translate-y-0"
|
||||
x-transition:leave-end="opacity-0 translate-y-full">
|
||||
<div class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-green-400 rounded-lg bg-green-900/40">
|
||||
<i class="fas fa-check"></i>
|
||||
</div>
|
||||
<div class="ml-3 text-sm font-normal" id="toast-message">Status updated successfully</div>
|
||||
<button type="button"
|
||||
class="ml-auto -mx-1.5 -my-1.5 text-gray-400 hover:text-gray-300 rounded-lg p-1.5 inline-flex h-8 w-8"
|
||||
@click="show = false">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user