initial geodjango implementation

This commit is contained in:
pacnpal
2024-11-05 04:10:47 +00:00
parent f1977cde3f
commit 9cd7ee94a5
22 changed files with 768 additions and 229 deletions

View File

@@ -4,7 +4,7 @@
{% block title %}{{ park.name }} - ThrillWiki{% endblock %}
{% block extra_head %}
{% if park.latitude and park.longitude %}
{% if park.location.exists %}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
{% endif %}
{% endblock %}
@@ -19,7 +19,7 @@
})
</script>
<div class="container px-4 mx-auto">
<div class="container px-4 mx-auto sm:px-6 lg:px-8">
<!-- Action Buttons - Above header -->
{% if user.is_authenticated %}
<div class="flex justify-end gap-2 mb-2">
@@ -37,18 +37,16 @@
{% endif %}
<!-- Header Grid -->
<div class="grid grid-cols-1 gap-4 mb-8 sm:grid-cols-12">
<div class="grid grid-cols-2 gap-4 mb-8 sm:grid-cols-12">
<!-- Park Info Card -->
<div class="flex flex-col items-center justify-center h-full col-span-1 p-4 text-center bg-white rounded-lg shadow-lg sm:col-span-3 dark:bg-gray-800">
<h1 class="text-2xl font-bold leading-tight text-gray-900 sm:text-3xl dark:text-white">{{ park.name }}</h1>
<div class="flex flex-col items-center justify-center h-full col-span-2 p-4 text-center bg-white rounded-lg shadow-lg sm:col-span-3 dark:bg-gray-800">
<h1 class="text-2xl font-bold leading-tight text-gray-900 sm:text-lg lg:text-4xl md:text-lg dark:text-white">{{ park.name }}</h1>
{% if park.formatted_location %}
<div class="flex items-center justify-center mt-2 text-sm text-gray-600 dark:text-gray-400">
<i class="mr-1 fas fa-map-marker-alt"></i>
<p>{{ park.formatted_location }}</p>
</div>
{% endif %}
<div class="flex items-center justify-center mt-2 text-sm text-gray-600 dark:text-gray-400">
<i class="mr-1 fas fa-map-marker-alt"></i>
<p>{{ park.formatted_location }}</p>
</div>
{% endif %}
<div class="flex flex-wrap items-center justify-center gap-2 mt-3">
<span class="status-badge text-xs sm:text-sm font-medium py-1 px-3 {% if park.status == 'OPERATING' %}status-operating
{% elif park.status == 'CLOSED_TEMP' or park.status == 'CLOSED_PERM' %}status-closed
@@ -67,36 +65,36 @@
</div>
<!-- Stats and Quick Facts -->
<div class="grid h-full grid-cols-12 col-span-1 gap-4 sm:col-span-9">
<div class="grid h-full grid-cols-2 col-span-2 gap-4 sm:col-span-9">
<!-- Stats Column -->
<div class="grid grid-cols-2 col-span-12 gap-4 sm:col-span-4">
<!-- Total Rides Card -->
{% if park.total_rides %}
<a href="{% url 'parks:rides:ride_list' park.slug %}"
class="flex flex-col items-center justify-center p-4 text-center transition-transform bg-white rounded-lg shadow-lg hover:scale-[1.02] dark:bg-gray-800">
<dt class="text-sm font-semibold text-gray-900 sm:text-base dark:text-white">Total Rides</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 hover:text-sky-800 sm:text-2xl dark:text-sky-400 dark:hover:text-sky-300">{{ park.total_rides }}</dd>
<dt class="text-sm font-semibold text-gray-900 sm:text-base lg:text-lg dark:text-white">Total Rides</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 hover:text-sky-800 sm:text-2xl lg:text-3xl dark:text-sky-400 dark:hover:text-sky-300">
{{ park.total_rides|default:"N/A" }}
</dd>
</a>
{% endif %}
<!-- Total Roller Coasters Card -->
{% if park.total_roller_coasters %}
<div class="flex flex-col items-center justify-center p-4 text-center bg-white rounded-lg shadow-lg dark:bg-gray-800">
<dt class="text-sm font-semibold text-gray-900 sm:text-base dark:text-white">Roller Coasters</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 hover:text-sky-800 sm:text-2xl dark:text-sky-400 dark:hover:text-sky-300">{{ park.total_roller_coasters }}</dd>
<dt class="text-sm font-semibold text-gray-900 sm:text-base lg:text-lg dark:text-white">Roller Coasters</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 hover:text-sky-800 sm:text-2xl lg:text-3xl dark:text-sky-400 dark:hover:text-sky-300">
{{ park.total_roller_coasters|default:"N/A" }}
</dd>
</div>
{% endif %}
</div>
<!-- Quick Facts Grid -->
<div class="grid h-full grid-cols-3 col-span-12 gap-2 p-4 bg-white rounded-lg shadow-lg sm:col-span-8 dark:bg-gray-800">
{% if park.owner %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-building dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Owner</dt>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-building dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Owner</dt>
<dd>
<a href="{% url 'companies:company_detail' park.owner.slug %}"
class="text-xs text-blue-600 sm:text-sm hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300">
class="text-xs text-blue-600 sm:text-sm lg:text-base hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300">
{{ park.owner.name }}
</a>
</dd>
@@ -105,19 +103,19 @@
{% if park.opening_date %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-calendar-alt dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Opened</dt>
<dd class="text-xs text-gray-900 sm:text-sm dark:text-white">{{ park.opening_date }}</dd>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-calendar-alt dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Opened</dt>
<dd class="text-xs text-gray-900 sm:text-sm lg:text-base dark:text-white">{{ park.opening_date }}</dd>
</div>
{% endif %}
{% if park.website %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-globe dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Website</dt>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-globe dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Website</dt>
<dd>
<a href="{{ park.website }}"
class="inline-flex items-center text-xs text-blue-600 sm:text-sm hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
class="inline-flex items-center text-xs text-blue-600 sm:text-sm lg:text-base hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
target="_blank" rel="noopener noreferrer">
Visit
<i class="ml-1 text-xs fas fa-external-link-alt"></i>
@@ -186,7 +184,7 @@
<!-- Right Column - Map and Additional Info -->
<div class="lg:col-span-1">
<!-- Location Map -->
{% if park.latitude and park.longitude %}
{% if park.location.exists %}
<div class="p-6 mb-6 bg-white rounded-lg shadow dark:bg-gray-800">
<h2 class="mb-4 text-xl font-semibold text-gray-900 dark:text-white">Location</h2>
<div id="park-map" class="relative rounded-lg" style="z-index: 0;"></div>
@@ -253,6 +251,7 @@
</div>
{% endif %}
{% endblock %}
{% block extra_js %}
@@ -260,12 +259,14 @@
<script src="{% static 'js/photo-gallery.js' %}"></script>
<!-- Map Script (if location exists) -->
{% if park.latitude and park.longitude %}
{% if park.location.exists %}
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="{% static 'js/park-map.js' %}"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
initParkMap({{ park.latitude }}, {{ park.longitude }}, "{{ park.name }}");
{% with location=park.location.first %}
initParkMap({{ location.latitude }}, {{ location.longitude }}, "{{ park.name }}");
{% endwith %}
});
</script>
{% endif %}

View File

@@ -4,7 +4,7 @@
{% block title %}{{ ride.name }} at {{ ride.park.name }} - ThrillWiki{% endblock %}
{% block content %}
<div class="container px-4 mx-auto">
<div class="container px-4 mx-auto sm:px-6 lg:px-8">
<!-- Action Buttons - Above header -->
{% if user.is_authenticated %}
<div class="flex justify-end gap-2 mb-2">
@@ -25,7 +25,7 @@
<div class="grid grid-cols-1 gap-4 mb-8 sm:grid-cols-12">
<!-- Ride Info Card -->
<div class="flex flex-col items-center justify-center h-full col-span-1 p-4 text-center bg-white rounded-lg shadow-lg sm:col-span-3 dark:bg-gray-800">
<h1 class="text-2xl font-bold leading-tight text-gray-900 sm:text-3xl dark:text-white">{{ ride.name }}</h1>
<h1 class="text-2xl font-bold leading-tight text-gray-900 sm:text-3xl lg:text-4xl dark:text-white">{{ ride.name }}</h1>
<div class="flex items-center justify-center mt-2 text-sm text-gray-600 dark:text-gray-400">
at <a href="{% url 'parks:park_detail' ride.park.slug %}" class="ml-1 text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300">
@@ -37,18 +37,18 @@
</div>
<div class="flex flex-wrap items-center justify-center gap-2 mt-3">
<span class="px-3 py-1 text-xs font-medium status-badge sm:text-sm {% if ride.status == 'OPERATING' %}status-operating
<span class="px-3 py-1 text-xs font-medium status-badge sm:text-sm lg:text-base {% if ride.status == 'OPERATING' %}status-operating
{% elif ride.status == 'CLOSED_TEMP' or ride.status == 'CLOSED_PERM' %}status-closed
{% elif ride.status == 'UNDER_CONSTRUCTION' %}status-construction
{% elif ride.status == 'DEMOLISHED' %}status-demolished
{% elif ride.status == 'RELOCATED' %}status-relocated{% endif %}">
{{ ride.get_status_display }}
</span>
<span class="px-3 py-1 text-xs font-medium text-blue-800 bg-blue-100 status-badge sm:text-sm dark:bg-blue-700 dark:text-blue-50">
<span class="px-3 py-1 text-xs font-medium text-blue-800 bg-blue-100 status-badge sm:text-sm lg:text-base dark:bg-blue-700 dark:text-blue-50">
{{ ride.get_category_display }}
</span>
{% if ride.average_rating %}
<span class="flex items-center px-3 py-1 text-xs font-medium text-yellow-800 bg-yellow-100 status-badge sm:text-sm dark:bg-yellow-600 dark:text-yellow-50">
<span class="flex items-center px-3 py-1 text-xs font-medium text-yellow-800 bg-yellow-100 status-badge sm:text-sm lg:text-base dark:bg-yellow-600 dark:text-yellow-50">
<span class="mr-1 text-yellow-500 dark:text-yellow-200"></span>
{{ ride.average_rating|floatformat:1 }}/10
</span>
@@ -63,28 +63,32 @@
{% if coaster_stats %}
{% if coaster_stats.height_ft %}
<div class="flex flex-col items-center justify-center p-4 text-center bg-white rounded-lg shadow-lg dark:bg-gray-800">
<dt class="text-sm font-semibold text-gray-900 sm:text-base dark:text-white">Height</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl dark:text-sky-400">{{ coaster_stats.height_ft }} ft</dd>
<dt class="text-sm font-semibold text-gray-900 sm:text-base lg:text-lg dark:text-white">Height</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl lg:text-3xl dark:text-sky-400">{{ coaster_stats.height_ft }} ft</dd>
</div>
{% endif %}
{% if coaster_stats.speed_mph %}
<div class="flex flex-col items-center justify-center p-4 text-center bg-white rounded-lg shadow-lg dark:bg-gray-800">
<dt class="text-sm font-semibold text-gray-900 sm:text-base dark:text-white">Speed</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl dark:text-sky-400">{{ coaster_stats.speed_mph }} mph</dd>
<dt class="text-sm font-semibold text-gray-900 sm:text-base lg:text-lg dark:text-white">Speed</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl lg:text-3xl dark:text-sky-400">{{ coaster_stats.speed_mph }} mph</dd>
</div>
{% endif %}
{% if coaster_stats.inversions %}
<div class="flex flex-col items-center justify-center p-4 text-center bg-white rounded-lg shadow-lg dark:bg-gray-800">
<dt class="text-sm font-semibold text-gray-900 sm:text-base dark:text-white">Inversions</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl dark:text-sky-400">{{ coaster_stats.inversions }}</dd>
<dt class="text-sm font-semibold text-gray-900 sm:text-base lg:text-lg dark:text-white">Inversions</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl lg:text-3xl dark:text-sky-400">{{ coaster_stats.inversions }}</dd>
</div>
{% endif %}
{% if coaster_stats.length_ft %}
<div class="flex flex-col items-center justify-center p-4 text-center bg-white rounded-lg shadow-lg dark:bg-gray-800">
<dt class="text-sm font-semibold text-gray-900 sm:text-base dark:text-white">Length</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl dark:text-sky-400">{{ coaster_stats.length_ft }} ft</dd>
<dt class="text-sm font-semibold text-gray-900 sm:text-base lg:text-lg dark:text-white">Length</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl lg:text-3xl dark:text-sky-400">{{ coaster_stats.length_ft }} ft</dd>
</div>
{% else %}
<div class="flex flex-col items-center justify-center p-4 text-center bg-white rounded-lg shadow-lg dark:bg-gray-800">
<dt class="text-sm font-semibold text-gray-900 sm:text-base lg:text-lg dark:text-white">Length</dt>
<dd class="mt-2 text-xl font-bold text-sky-900 sm:text-2xl lg:text-3xl dark:text-sky-400">N/A</dd>
</div>
{% endif %}
{% endif %}
</div>
@@ -92,24 +96,20 @@
<div class="grid h-full grid-cols-3 col-span-12 gap-2 p-4 bg-white rounded-lg shadow-lg sm:col-span-8 dark:bg-gray-800">
{% if ride.manufacturer %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-industry dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Manufacturer</dt>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-industry dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Manufacturer</dt>
<dd>
<a href="{% url 'companies:manufacturer_detail' ride.manufacturer.slug %}"
class="text-xs text-blue-600 sm:text-sm hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300">
{{ ride.manufacturer.name }}
</a>
</dd>
</div>
class="text-xs text-blue-600 sm:text-sm lg:text-base hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300">
{% endif %}
{% if ride.designer %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-drafting-compass dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Designer</dt>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-drafting-compass dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Designer</dt>
<dd>
<a href="{% url 'designers:designer_detail' ride.designer.slug %}"
class="text-xs text-blue-600 sm:text-sm hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300">
class="text-xs text-blue-600 sm:text-sm lg:text-base hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300">
{{ ride.designer.name }}
</a>
</dd>
@@ -118,41 +118,41 @@
{% if coaster_stats.roller_coaster_type %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-train dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Coaster Type</dt>
<dd class="text-xs text-gray-900 sm:text-sm dark:text-white">{{ coaster_stats.get_roller_coaster_type_display }}</dd>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-train dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Coaster Type</dt>
<dd class="text-xs text-gray-900 sm:text-sm lg:text-base dark:text-white">{{ coaster_stats.get_roller_coaster_type_display }}</dd>
</div>
{% endif %}
{% if coaster_stats.track_material %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-layer-group dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Track Material</dt>
<dd class="text-xs text-gray-900 sm:text-sm dark:text-white">{{ coaster_stats.get_track_material_display }}</dd>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-layer-group dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Track Material</dt>
<dd class="text-xs text-gray-900 sm:text-sm lg:text-base dark:text-white">{{ coaster_stats.get_track_material_display }}</dd>
</div>
{% endif %}
{% if ride.opening_date %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-calendar-alt dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Opened</dt>
<dd class="text-xs text-gray-900 sm:text-sm dark:text-white">{{ ride.opening_date }}</dd>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-calendar-alt dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Opened</dt>
<dd class="text-xs text-gray-900 sm:text-sm lg:text-base dark:text-white">{{ ride.opening_date }}</dd>
</div>
{% endif %}
{% if ride.capacity_per_hour %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-users dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Capacity</dt>
<dd class="text-xs text-gray-900 sm:text-sm dark:text-white">{{ ride.capacity_per_hour }}/hr</dd>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-users dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Capacity</dt>
<dd class="text-xs text-gray-900 sm:text-sm lg:text-base dark:text-white">{{ ride.capacity_per_hour }}/hr</dd>
</div>
{% endif %}
{% if coaster_stats.launch_type %}
<div class="flex flex-col items-center justify-center p-2 text-center">
<i class="text-lg text-blue-600 sm:text-xl fas fa-rocket dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 dark:text-gray-400">Launch Type</dt>
<dd class="text-xs text-gray-900 sm:text-sm dark:text-white">{{ coaster_stats.get_launch_type_display }}</dd>
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-rocket dark:text-blue-400"></i>
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Launch Type</dt>
<dd class="text-xs text-gray-900 sm:text-sm lg:text-base dark:text-white">{{ coaster_stats.get_launch_type_display }}</dd>
</div>
{% endif %}
</div>