mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 08:31:08 -05:00
code commit
This commit is contained in:
150
templates/moderation/partials/coaster_fields.html
Normal file
150
templates/moderation/partials/coaster_fields.html
Normal file
@@ -0,0 +1,150 @@
|
||||
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||
<!-- Left Column -->
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<label for="id_height_ft" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Height (ft)
|
||||
</label>
|
||||
<input type="number"
|
||||
name="stats.height_ft"
|
||||
id="id_height_ft"
|
||||
class="w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||
placeholder="Total height of the coaster in feet"
|
||||
min="0"
|
||||
value="{{ stats.height_ft }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_length_ft" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Length (ft)
|
||||
</label>
|
||||
<input type="number"
|
||||
name="stats.length_ft"
|
||||
id="id_length_ft"
|
||||
class="w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||
placeholder="Total track length in feet"
|
||||
min="0"
|
||||
value="{{ stats.length_ft }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_speed_mph" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Speed (mph)
|
||||
</label>
|
||||
<input type="number"
|
||||
name="stats.speed_mph"
|
||||
id="id_speed_mph"
|
||||
class="w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||
placeholder="Maximum speed in miles per hour"
|
||||
min="0"
|
||||
value="{{ stats.speed_mph }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_inversions" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Inversions
|
||||
</label>
|
||||
<input type="number"
|
||||
name="stats.inversions"
|
||||
id="id_inversions"
|
||||
class="w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||
placeholder="Number of inversions"
|
||||
min="0"
|
||||
value="{{ stats.inversions }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_trains_count" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Number of Trains
|
||||
</label>
|
||||
<input type="number"
|
||||
name="stats.trains_count"
|
||||
id="id_trains_count"
|
||||
class="w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||
placeholder="Number of trains"
|
||||
min="0"
|
||||
value="{{ stats.trains_count }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_cars_per_train" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Cars per Train
|
||||
</label>
|
||||
<input type="number"
|
||||
name="stats.cars_per_train"
|
||||
id="id_cars_per_train"
|
||||
class="w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||
placeholder="Number of cars per train"
|
||||
min="0"
|
||||
value="{{ stats.cars_per_train }}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_seats_per_car" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Seats per Car
|
||||
</label>
|
||||
<input type="number"
|
||||
name="stats.seats_per_car"
|
||||
id="id_seats_per_car"
|
||||
class="w-full border-gray-300 rounded-lg form-input dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||
placeholder="Number of seats per car"
|
||||
min="0"
|
||||
value="{{ stats.seats_per_car }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column -->
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<label for="id_track_material" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Track Material
|
||||
</label>
|
||||
<select name="stats.track_material"
|
||||
id="id_track_material"
|
||||
class="w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white">
|
||||
<option value="">Select track material...</option>
|
||||
<option value="STEEL" {% if stats.track_material == 'STEEL' %}selected{% endif %}>Steel</option>
|
||||
<option value="WOOD" {% if stats.track_material == 'WOOD' %}selected{% endif %}>Wood</option>
|
||||
<option value="HYBRID" {% if stats.track_material == 'HYBRID' %}selected{% endif %}>Hybrid</option>
|
||||
<option value="OTHER" {% if stats.track_material == 'OTHER' %}selected{% endif %}>Other</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_roller_coaster_type" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Coaster Type
|
||||
</label>
|
||||
<select name="stats.roller_coaster_type"
|
||||
id="id_roller_coaster_type"
|
||||
class="w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white">
|
||||
<option value="">Select coaster type...</option>
|
||||
<option value="SITDOWN" {% if stats.roller_coaster_type == 'SITDOWN' %}selected{% endif %}>Sit-Down</option>
|
||||
<option value="INVERTED" {% if stats.roller_coaster_type == 'INVERTED' %}selected{% endif %}>Inverted</option>
|
||||
<option value="FLYING" {% if stats.roller_coaster_type == 'FLYING' %}selected{% endif %}>Flying</option>
|
||||
<option value="STANDUP" {% if stats.roller_coaster_type == 'STANDUP' %}selected{% endif %}>Stand-Up</option>
|
||||
<option value="WING" {% if stats.roller_coaster_type == 'WING' %}selected{% endif %}>Wing</option>
|
||||
<option value="SUSPENDED" {% if stats.roller_coaster_type == 'SUSPENDED' %}selected{% endif %}>Suspended</option>
|
||||
<option value="BOBSLED" {% if stats.roller_coaster_type == 'BOBSLED' %}selected{% endif %}>Bobsled</option>
|
||||
<option value="PIPELINE" {% if stats.roller_coaster_type == 'PIPELINE' %}selected{% endif %}>Pipeline</option>
|
||||
<option value="MOTORBIKE" {% if stats.roller_coaster_type == 'MOTORBIKE' %}selected{% endif %}>Motorbike</option>
|
||||
<option value="FLOORLESS" {% if stats.roller_coaster_type == 'FLOORLESS' %}selected{% endif %}>Floorless</option>
|
||||
<option value="DIVE" {% if stats.roller_coaster_type == 'DIVE' %}selected{% endif %}>Dive</option>
|
||||
<option value="FAMILY" {% if stats.roller_coaster_type == 'FAMILY' %}selected{% endif %}>Family</option>
|
||||
<option value="WILD_MOUSE" {% if stats.roller_coaster_type == 'WILD_MOUSE' %}selected{% endif %}>Wild Mouse</option>
|
||||
<option value="SPINNING" {% if stats.roller_coaster_type == 'SPINNING' %}selected{% endif %}>Spinning</option>
|
||||
<option value="FOURTH_DIMENSION" {% if stats.roller_coaster_type == 'FOURTH_DIMENSION' %}selected{% endif %}>4th Dimension</option>
|
||||
<option value="OTHER" {% if stats.roller_coaster_type == 'OTHER' %}selected{% endif %}>Other</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_launch_type" class="block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Launch Type
|
||||
</label>
|
||||
<select name="stats.launch_type"
|
||||
id="id_launch_type"
|
||||
class="w-full border-gray-300 rounded-lg form-select dark:border-gray-600 dark:bg-gray-700 dark:text-white">
|
||||
<option value="">Select launch type...</option>
|
||||
<option value="CHAIN" {% if stats.launch_type == 'CHAIN' %}selected{% endif %}>Chain Lift</option>
|
||||
<option value="CABLE" {% if stats.launch_type == 'CABLE' %}selected{% endif %}>Cable Launch</option>
|
||||
<option value="HYDRAULIC" {% if stats.launch_type == 'HYDRAULIC' %}selected{% endif %}>Hydraulic Launch</option>
|
||||
<option value="LSM" {% if stats.launch_type == 'LSM' %}selected{% endif %}>Linear Synchronous Motor</option>
|
||||
<option value="LIM" {% if stats.launch_type == 'LIM' %}selected{% endif %}>Linear Induction Motor</option>
|
||||
<option value="GRAVITY" {% if stats.launch_type == 'GRAVITY' %}selected{% endif %}>Gravity</option>
|
||||
<option value="OTHER" {% if stats.launch_type == 'OTHER' %}selected{% endif %}>Other</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -5,9 +5,9 @@
|
||||
<div class="space-y-6">
|
||||
<div class="flex items-center justify-between p-4 bg-white border rounded-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50">
|
||||
<div class="flex items-center space-x-4">
|
||||
<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-100 text-blue-900 dark:bg-blue-900/40 dark:text-blue-400{% else %}text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-300{% endif %}"
|
||||
hx-get="{% url 'moderation:submission_list' %}?status=NEW"
|
||||
<a href="{% url 'moderation:submission_list' %}?status=PENDING"
|
||||
class="flex items-center px-4 py-2.5 rounded-lg font-medium transition-all duration-200 {% if request.GET.status == 'PENDING' or not request.GET.status %}bg-blue-100 text-blue-900 dark:bg-blue-900/40 dark:text-blue-400{% else %}text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-300{% endif %}"
|
||||
hx-get="{% url 'moderation:submission_list' %}?status=PENDING"
|
||||
hx-target="#dashboard-content"
|
||||
hx-push-url="true"
|
||||
hx-indicator="#loading-indicator">
|
||||
|
||||
67
templates/moderation/partials/designer_search_results.html
Normal file
67
templates/moderation/partials/designer_search_results.html
Normal file
@@ -0,0 +1,67 @@
|
||||
<div class="w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg dark:bg-gray-700 dark:border-gray-600" style="max-height: 240px; overflow-y: auto;">
|
||||
{% if designers %}
|
||||
{% for designer in designers %}
|
||||
<button type="button"
|
||||
class="w-full px-4 py-2 text-left text-gray-900 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600"
|
||||
onclick="selectDesignerForSubmission('{{ designer.id }}', '{{ designer.name|escapejs }}', '{{ submission_id }}')">
|
||||
{{ designer.name }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="px-4 py-2 text-gray-700 dark:text-gray-300">
|
||||
{% if search_term %}
|
||||
No designers found
|
||||
{% else %}
|
||||
Start typing to search...
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function selectDesignerForSubmission(id, name, submissionId) {
|
||||
// Debug logging
|
||||
console.log('Selecting designer:', {id, name, submissionId});
|
||||
|
||||
// Find elements
|
||||
const designerInput = document.querySelector(`#designer-input-${submissionId}`);
|
||||
const searchInput = document.querySelector(`#designer-search-${submissionId}`);
|
||||
const resultsDiv = document.querySelector(`#designer-search-results-${submissionId}`);
|
||||
|
||||
// Debug logging
|
||||
console.log('Found elements:', {
|
||||
designerInput: designerInput?.id,
|
||||
searchInput: searchInput?.id,
|
||||
resultsDiv: resultsDiv?.id
|
||||
});
|
||||
|
||||
// Update hidden input
|
||||
if (designerInput) {
|
||||
designerInput.value = id;
|
||||
console.log('Updated designer input value:', designerInput.value);
|
||||
}
|
||||
|
||||
// Update search input
|
||||
if (searchInput) {
|
||||
searchInput.value = name;
|
||||
console.log('Updated search input value:', searchInput.value);
|
||||
}
|
||||
|
||||
// Clear results
|
||||
if (resultsDiv) {
|
||||
resultsDiv.innerHTML = '';
|
||||
console.log('Cleared results div');
|
||||
}
|
||||
}
|
||||
|
||||
// Close search results when clicking outside
|
||||
document.addEventListener('click', function(e) {
|
||||
const searchResults = document.querySelectorAll('[id^="designer-search-results-"]');
|
||||
searchResults.forEach(function(resultsDiv) {
|
||||
const searchInput = document.querySelector(`#designer-search-${resultsDiv.id.split('-').pop()}`);
|
||||
if (!resultsDiv.contains(e.target) && e.target !== searchInput) {
|
||||
resultsDiv.innerHTML = '';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
132
templates/moderation/partials/edit_submission_form.html
Normal file
132
templates/moderation/partials/edit_submission_form.html
Normal file
@@ -0,0 +1,132 @@
|
||||
{% load moderation_tags %}
|
||||
|
||||
<div class="p-6 bg-white border rounded-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50"
|
||||
id="edit-form-{{ submission.id }}">
|
||||
<h3 class="mb-4 text-lg font-semibold text-gray-900 dark:text-gray-300">
|
||||
Edit Submission
|
||||
</h3>
|
||||
|
||||
<form hx-post="{% url 'moderation:edit_submission' submission.id %}"
|
||||
hx-target="#submissions-content"
|
||||
class="space-y-4">
|
||||
|
||||
{% for field, value in changes.items %}
|
||||
{% if field != 'model_name' %}
|
||||
<div class="p-4 bg-gray-100 border rounded-lg dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">
|
||||
{% if field == 'stats' %}
|
||||
Coaster Stats:
|
||||
{% elif field == 'park_area' %}
|
||||
Park Area:
|
||||
{% elif field == 'ride_model' %}
|
||||
Ride Model:
|
||||
{% elif field == 'min_height_in' %}
|
||||
Minimum Height:
|
||||
{% elif field == 'max_height_in' %}
|
||||
Maximum Height:
|
||||
{% elif field == 'capacity_per_hour' %}
|
||||
Hourly Capacity:
|
||||
{% elif field == 'ride_duration_seconds' %}
|
||||
Ride Duration:
|
||||
{% elif field == 'opening_date' %}
|
||||
Opening Date:
|
||||
{% elif field == 'closing_date' %}
|
||||
Closing Date:
|
||||
{% elif field == 'status_since' %}
|
||||
Status Since:
|
||||
{% elif field == 'operating_season' %}
|
||||
Operating Season:
|
||||
{% elif field == 'size_acres' %}
|
||||
Size (Acres):
|
||||
{% elif field == 'post_closing_status' %}
|
||||
Post-Closing Status:
|
||||
{% else %}
|
||||
{{ field|title }}:
|
||||
{% endif %}
|
||||
</label>
|
||||
|
||||
{% if field == 'stats' %}
|
||||
<div class="space-y-2">
|
||||
{% for stat_name, stat_value in value.items %}
|
||||
<div class="flex items-center gap-2">
|
||||
<label class="text-sm text-gray-700 dark:text-gray-400">{{ stat_name|title }}:</label>
|
||||
<input type="text"
|
||||
name="stats.{{ stat_name }}"
|
||||
value="{{ stat_value }}"
|
||||
class="flex-1 px-3 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50">
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% elif field == 'park' %}
|
||||
<select name="{{ field }}"
|
||||
class="w-full px-3 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50">
|
||||
{% for park_id, park_name in parks %}
|
||||
<option value="{{ park_id }}" {% if park_id == value %}selected{% endif %}>{{ park_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% elif field == 'designer' %}
|
||||
<select name="{{ field }}"
|
||||
class="w-full px-3 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50">
|
||||
<option value="">None</option>
|
||||
{% for designer_id, designer_name in designers %}
|
||||
<option value="{{ designer_id }}" {% if designer_id == value %}selected{% endif %}>{{ designer_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% elif field == 'manufacturer' %}
|
||||
<select name="{{ field }}"
|
||||
class="w-full px-3 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50">
|
||||
<option value="">None</option>
|
||||
{% for manufacturer_id, manufacturer_name in manufacturers %}
|
||||
<option value="{{ manufacturer_id }}" {% if manufacturer_id == value %}selected{% endif %}>{{ manufacturer_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% elif field == 'ride_model' %}
|
||||
<select name="{{ field }}"
|
||||
class="w-full px-3 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50">
|
||||
<option value="">None</option>
|
||||
{% for model_id, model_name in ride_models %}
|
||||
<option value="{{ model_id }}" {% if model_id == value %}selected{% endif %}>{{ model_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% elif field == 'park_area' %}
|
||||
<select name="{{ field }}"
|
||||
class="w-full px-3 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50">
|
||||
<option value="">None</option>
|
||||
{% for area_id, area_name in park_areas %}
|
||||
<option value="{{ area_id }}" {% if area_id == value %}selected{% endif %}>{{ area_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<input type="{% if field == 'opening_date' or field == 'closing_date' or field == 'status_since' %}date{% else %}text{% endif %}"
|
||||
name="{{ field }}"
|
||||
value="{{ value }}"
|
||||
class="w-full px-3 py-2 text-gray-900 bg-white border rounded-lg dark:text-gray-300 dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50">
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<div class="p-4 border rounded-lg bg-blue-50 dark:bg-blue-900/30 border-blue-200/50 dark:border-blue-700/50">
|
||||
<label class="block mb-2 text-sm font-medium text-blue-900 dark:text-blue-300">
|
||||
Notes (required):
|
||||
</label>
|
||||
<textarea name="notes"
|
||||
class="w-full px-3 py-2 text-gray-900 bg-white border rounded-lg resize-none dark:text-gray-300 dark:bg-gray-900 border-gray-200/50 dark:border-gray-700/50"
|
||||
rows="3"
|
||||
required
|
||||
placeholder="Explain why you're editing this submission"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end gap-3">
|
||||
<button type="button"
|
||||
class="px-4 py-2 font-medium text-gray-700 transition-all duration-200 bg-gray-100 rounded-lg hover:bg-gray-200 hover:text-gray-900 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
@click="showEditForm = false">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="submit"
|
||||
class="px-4 py-2 font-medium text-white transition-all duration-200 bg-blue-600 rounded-lg hover:bg-blue-500 dark:bg-blue-700 dark:hover:bg-blue-600">
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -11,7 +11,7 @@
|
||||
</label>
|
||||
<select name="status" class="w-full form-select">
|
||||
<option value="">All Statuses</option>
|
||||
<option value="NEW" {% if request.GET.status == 'NEW' %}selected{% endif %}>Pending</option>
|
||||
<option value="PENDING" {% if request.GET.status == 'PENDING' %}selected{% endif %}>Pending</option>
|
||||
<option value="APPROVED" {% if request.GET.status == 'APPROVED' %}selected{% endif %}>Approved</option>
|
||||
<option value="REJECTED" {% if request.GET.status == 'REJECTED' %}selected{% endif %}>Rejected</option>
|
||||
<option value="ESCALATED" {% if request.GET.status == 'ESCALATED' %}selected{% endif %}>Escalated</option>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<div class="w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg dark:bg-gray-700 dark:border-gray-600" style="max-height: 240px; overflow-y: auto;">
|
||||
{% if manufacturers %}
|
||||
{% for manufacturer in manufacturers %}
|
||||
<button type="button"
|
||||
class="w-full px-4 py-2 text-left text-gray-900 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600"
|
||||
onclick="selectManufacturerForSubmission('{{ manufacturer.id }}', '{{ manufacturer.name|escapejs }}', '{{ submission_id }}')">
|
||||
{{ manufacturer.name }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="px-4 py-2 text-gray-700 dark:text-gray-300">
|
||||
{% if search_term %}
|
||||
No manufacturers found
|
||||
{% else %}
|
||||
Start typing to search...
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function selectManufacturerForSubmission(id, name, submissionId) {
|
||||
// Debug logging
|
||||
console.log('Selecting manufacturer:', {id, name, submissionId});
|
||||
|
||||
// Find elements
|
||||
const manufacturerInput = document.querySelector(`#manufacturer-input-${submissionId}`);
|
||||
const searchInput = document.querySelector(`#manufacturer-search-${submissionId}`);
|
||||
const resultsDiv = document.querySelector(`#manufacturer-search-results-${submissionId}`);
|
||||
|
||||
// Debug logging
|
||||
console.log('Found elements:', {
|
||||
manufacturerInput: manufacturerInput?.id,
|
||||
searchInput: searchInput?.id,
|
||||
resultsDiv: resultsDiv?.id
|
||||
});
|
||||
|
||||
// Update hidden input
|
||||
if (manufacturerInput) {
|
||||
manufacturerInput.value = id;
|
||||
console.log('Updated manufacturer input value:', manufacturerInput.value);
|
||||
}
|
||||
|
||||
// Update search input
|
||||
if (searchInput) {
|
||||
searchInput.value = name;
|
||||
console.log('Updated search input value:', searchInput.value);
|
||||
}
|
||||
|
||||
// Clear results
|
||||
if (resultsDiv) {
|
||||
resultsDiv.innerHTML = '';
|
||||
console.log('Cleared results div');
|
||||
}
|
||||
}
|
||||
|
||||
// Close search results when clicking outside
|
||||
document.addEventListener('click', function(e) {
|
||||
const searchResults = document.querySelectorAll('[id^="manufacturer-search-results-"]');
|
||||
searchResults.forEach(function(resultsDiv) {
|
||||
const searchInput = document.querySelector(`#manufacturer-search-${resultsDiv.id.split('-').pop()}`);
|
||||
if (!resultsDiv.contains(e.target) && e.target !== searchInput) {
|
||||
resultsDiv.innerHTML = '';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
73
templates/moderation/partials/park_search_results.html
Normal file
73
templates/moderation/partials/park_search_results.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<div class="w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg dark:bg-gray-700 dark:border-gray-600" style="max-height: 240px; overflow-y: auto;">
|
||||
{% if parks %}
|
||||
{% for park in parks %}
|
||||
<button type="button"
|
||||
class="w-full px-4 py-2 text-left text-gray-900 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600"
|
||||
onclick="selectParkForSubmission('{{ park.id }}', '{{ park.name|escapejs }}', '{{ submission_id }}')">
|
||||
{{ park.name }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="px-4 py-2 text-gray-700 dark:text-gray-300">
|
||||
{% if search_term %}
|
||||
No parks found
|
||||
{% else %}
|
||||
Start typing to search...
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function selectParkForSubmission(id, name, submissionId) {
|
||||
// Debug logging
|
||||
console.log('Selecting park:', {id, name, submissionId});
|
||||
|
||||
// Find elements
|
||||
const parkInput = document.querySelector(`#park-input-${submissionId}`);
|
||||
const searchInput = document.querySelector(`#park-search-${submissionId}`);
|
||||
const resultsDiv = document.querySelector(`#park-search-results-${submissionId}`);
|
||||
|
||||
// Debug logging
|
||||
console.log('Found elements:', {
|
||||
parkInput: parkInput?.id,
|
||||
searchInput: searchInput?.id,
|
||||
resultsDiv: resultsDiv?.id
|
||||
});
|
||||
|
||||
// Update hidden input
|
||||
if (parkInput) {
|
||||
parkInput.value = id;
|
||||
console.log('Updated park input value:', parkInput.value);
|
||||
}
|
||||
|
||||
// Update search input
|
||||
if (searchInput) {
|
||||
searchInput.value = name;
|
||||
console.log('Updated search input value:', searchInput.value);
|
||||
}
|
||||
|
||||
// Clear results
|
||||
if (resultsDiv) {
|
||||
resultsDiv.innerHTML = '';
|
||||
console.log('Cleared results div');
|
||||
}
|
||||
|
||||
// Trigger park areas update
|
||||
if (parkInput) {
|
||||
htmx.trigger(parkInput, 'change');
|
||||
console.log('Triggered change event');
|
||||
}
|
||||
}
|
||||
|
||||
// Close search results when clicking outside
|
||||
document.addEventListener('click', function(e) {
|
||||
const searchResults = document.querySelectorAll('[id^="park-search-results-"]');
|
||||
searchResults.forEach(function(resultsDiv) {
|
||||
const searchInput = document.querySelector(`#park-search-${resultsDiv.id.split('-').pop()}`);
|
||||
if (!resultsDiv.contains(e.target) && e.target !== searchInput) {
|
||||
resultsDiv.innerHTML = '';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -3,10 +3,14 @@
|
||||
<div>
|
||||
<h3 class="flex items-center gap-2 text-lg font-semibold text-gray-900 dark:text-white">
|
||||
<span class="status-badge
|
||||
{% if submission.status == 'NEW' %}status-pending
|
||||
{% if submission.status == 'PENDING' %}status-pending
|
||||
{% elif submission.status == 'APPROVED' %}status-approved
|
||||
{% elif submission.status == 'REJECTED' %}status-rejected
|
||||
{% elif submission.status == 'AUTO_APPROVED' %}status-approved{% endif %}">
|
||||
{% elif submission.status == 'ESCALATED' %}status-escalated{% endif %}">
|
||||
<i class="mr-1.5 fas fa-{% if submission.status == 'PENDING' %}clock
|
||||
{% elif submission.status == 'APPROVED' %}check
|
||||
{% elif submission.status == 'REJECTED' %}times
|
||||
{% elif submission.status == 'ESCALATED' %}exclamation{% endif %}"></i>
|
||||
{{ submission.get_status_display }}
|
||||
</span>
|
||||
Photo for {{ submission.content_object }}
|
||||
@@ -45,7 +49,14 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if submission.status == 'NEW' %}
|
||||
{% if submission.notes %}
|
||||
<div class="p-4 mt-4 border rounded-lg bg-blue-50 dark:bg-blue-900/30 border-blue-200/50 dark:border-blue-700/50">
|
||||
<div class="text-sm font-medium text-blue-900 dark:text-blue-300">Review Notes:</div>
|
||||
<div class="mt-1.5 text-blue-800 dark:text-blue-200">{{ submission.notes }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if submission.status == 'PENDING' or submission.status == 'ESCALATED' and user.role in 'ADMIN,SUPERUSER' %}
|
||||
<div class="mt-4 review-notes" x-data="{ showNotes: false }">
|
||||
<textarea x-show="showNotes"
|
||||
name="notes"
|
||||
@@ -60,6 +71,7 @@
|
||||
Add Notes
|
||||
</button>
|
||||
|
||||
{% if submission.status != 'ESCALATED' or user.role in 'ADMIN,SUPERUSER' %}
|
||||
<button class="btn-approve"
|
||||
hx-post="{% url 'moderation:approve_photo' submission.id %}"
|
||||
hx-target="#submission-{{ submission.id }}"
|
||||
@@ -79,6 +91,19 @@
|
||||
<i class="mr-2 fas fa-times"></i>
|
||||
Reject
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
{% if user.role == 'MODERATOR' and submission.status != 'ESCALATED' %}
|
||||
<button class="btn-escalate"
|
||||
hx-post="{% url 'moderation:escalate_photo' submission.id %}"
|
||||
hx-target="#submission-{{ submission.id }}"
|
||||
hx-include="closest .review-notes"
|
||||
hx-confirm="Are you sure you want to escalate this photo?"
|
||||
hx-indicator="#loading-indicator">
|
||||
<i class="mr-2 fas fa-arrow-up"></i>
|
||||
Escalate
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
67
templates/moderation/partials/ride_model_search_results.html
Normal file
67
templates/moderation/partials/ride_model_search_results.html
Normal file
@@ -0,0 +1,67 @@
|
||||
<div class="w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg dark:bg-gray-700 dark:border-gray-600" style="max-height: 240px; overflow-y: auto;">
|
||||
{% if ride_models %}
|
||||
{% for model in ride_models %}
|
||||
<button type="button"
|
||||
class="w-full px-4 py-2 text-left text-gray-900 hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600"
|
||||
onclick="selectRideModelForSubmission('{{ model.id }}', '{{ model.name|escapejs }}', '{{ submission_id }}')">
|
||||
{{ model.name }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="px-4 py-2 text-gray-700 dark:text-gray-300">
|
||||
{% if search_term %}
|
||||
No ride models found
|
||||
{% else %}
|
||||
Start typing to search...
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function selectRideModelForSubmission(id, name, submissionId) {
|
||||
// Debug logging
|
||||
console.log('Selecting ride model:', {id, name, submissionId});
|
||||
|
||||
// Find elements
|
||||
const modelInput = document.querySelector(`#ride-model-input-${submissionId}`);
|
||||
const searchInput = document.querySelector(`#ride-model-search-${submissionId}`);
|
||||
const resultsDiv = document.querySelector(`#ride-model-search-results-${submissionId}`);
|
||||
|
||||
// Debug logging
|
||||
console.log('Found elements:', {
|
||||
modelInput: modelInput?.id,
|
||||
searchInput: searchInput?.id,
|
||||
resultsDiv: resultsDiv?.id
|
||||
});
|
||||
|
||||
// Update hidden input
|
||||
if (modelInput) {
|
||||
modelInput.value = id;
|
||||
console.log('Updated ride model input value:', modelInput.value);
|
||||
}
|
||||
|
||||
// Update search input
|
||||
if (searchInput) {
|
||||
searchInput.value = name;
|
||||
console.log('Updated search input value:', searchInput.value);
|
||||
}
|
||||
|
||||
// Clear results
|
||||
if (resultsDiv) {
|
||||
resultsDiv.innerHTML = '';
|
||||
console.log('Cleared results div');
|
||||
}
|
||||
}
|
||||
|
||||
// Close search results when clicking outside
|
||||
document.addEventListener('click', function(e) {
|
||||
const searchResults = document.querySelectorAll('[id^="ride-model-search-results-"]');
|
||||
searchResults.forEach(function(resultsDiv) {
|
||||
const searchInput = document.querySelector(`#ride-model-search-${resultsDiv.id.split('-').pop()}`);
|
||||
if (!resultsDiv.contains(e.target) && e.target !== searchInput) {
|
||||
resultsDiv.innerHTML = '';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user