code commit

This commit is contained in:
pacnpal
2024-11-13 21:59:49 +00:00
parent 8f7f7add2d
commit 8265348a83
26 changed files with 1336 additions and 289 deletions

View 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>

View File

@@ -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">

View 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>

View 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>

View File

@@ -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>

View 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 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>

View 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>

View File

@@ -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 %}

View 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>