mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 12:31:22 -05:00
fix location add
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -28,3 +28,4 @@ moderation/__pycache__
|
|||||||
rides/__pycache__
|
rides/__pycache__
|
||||||
ssh_tools.jsonc
|
ssh_tools.jsonc
|
||||||
thrillwiki/__pycache__/settings.cpython-312.pyc
|
thrillwiki/__pycache__/settings.cpython-312.pyc
|
||||||
|
parks/__pycache__/views.cpython-312.pyc
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ def upload_photo(request):
|
|||||||
|
|
||||||
# Get the object instance
|
# Get the object instance
|
||||||
try:
|
try:
|
||||||
obj = content_type.get_object_for_this_type(id=object_id)
|
obj = content_type.get_object_for_this_type(pk=object_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
{
|
{
|
||||||
@@ -82,17 +82,17 @@ def upload_photo(request):
|
|||||||
photo = Photo.objects.create(
|
photo = Photo.objects.create(
|
||||||
image=request.FILES["image"],
|
image=request.FILES["image"],
|
||||||
content_type=content_type,
|
content_type=content_type,
|
||||||
object_id=obj.id,
|
object_id=obj.pk,
|
||||||
uploaded_by=request.user, # Add the user who uploaded the photo
|
uploaded_by=request.user, # Add the user who uploaded the photo
|
||||||
is_primary=not Photo.objects.filter(
|
is_primary=not Photo.objects.filter(
|
||||||
content_type=content_type, object_id=obj.id
|
content_type=content_type, object_id=obj.pk
|
||||||
).exists(),
|
).exists(),
|
||||||
is_approved=is_approved # Auto-approve if the user is a moderator, admin, or superuser
|
is_approved=is_approved # Auto-approve if the user is a moderator, admin, or superuser
|
||||||
)
|
)
|
||||||
|
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
{
|
{
|
||||||
"id": photo.id,
|
"id": photo.pk,
|
||||||
"url": photo.image.url,
|
"url": photo.image.url,
|
||||||
"caption": photo.caption,
|
"caption": photo.caption,
|
||||||
"is_primary": photo.is_primary,
|
"is_primary": photo.is_primary,
|
||||||
@@ -113,7 +113,7 @@ def upload_photo(request):
|
|||||||
def set_primary_photo(request, photo_id):
|
def set_primary_photo(request, photo_id):
|
||||||
"""Set a photo as primary"""
|
"""Set a photo as primary"""
|
||||||
try:
|
try:
|
||||||
photo = get_object_or_404(Photo, id=photo_id)
|
photo = get_object_or_404(Photo, pk=photo_id)
|
||||||
|
|
||||||
# Check if user has permission to edit photos
|
# Check if user has permission to edit photos
|
||||||
if not request.user.has_perm("media.change_photo"):
|
if not request.user.has_perm("media.change_photo"):
|
||||||
@@ -137,7 +137,7 @@ def set_primary_photo(request, photo_id):
|
|||||||
def update_caption(request, photo_id):
|
def update_caption(request, photo_id):
|
||||||
"""Update a photo's caption"""
|
"""Update a photo's caption"""
|
||||||
try:
|
try:
|
||||||
photo = get_object_or_404(Photo, id=photo_id)
|
photo = get_object_or_404(Photo, pk=photo_id)
|
||||||
|
|
||||||
# Check if user has permission to edit photos
|
# Check if user has permission to edit photos
|
||||||
if not request.user.has_perm("media.change_photo"):
|
if not request.user.has_perm("media.change_photo"):
|
||||||
@@ -150,7 +150,7 @@ def update_caption(request, photo_id):
|
|||||||
photo.caption = data.get("caption", "")
|
photo.caption = data.get("caption", "")
|
||||||
photo.save()
|
photo.save()
|
||||||
|
|
||||||
return JsonResponse({"id": photo.id, "caption": photo.caption})
|
return JsonResponse({"id": photo.pk, "caption": photo.caption})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error in update_caption: {str(e)}", exc_info=True)
|
logger.error(f"Error in update_caption: {str(e)}", exc_info=True)
|
||||||
@@ -162,7 +162,7 @@ def update_caption(request, photo_id):
|
|||||||
def delete_photo(request, photo_id):
|
def delete_photo(request, photo_id):
|
||||||
"""Delete a photo"""
|
"""Delete a photo"""
|
||||||
try:
|
try:
|
||||||
photo = get_object_or_404(Photo, id=photo_id)
|
photo = get_object_or_404(Photo, pk=photo_id)
|
||||||
|
|
||||||
# Check if user has permission to delete photos
|
# Check if user has permission to delete photos
|
||||||
if not request.user.has_perm("media.delete_photo"):
|
if not request.user.has_perm("media.delete_photo"):
|
||||||
|
|||||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from decimal import Decimal, InvalidOperation, ROUND_DOWN
|
from decimal import Decimal, InvalidOperation, ROUND_DOWN
|
||||||
from .models import Park
|
from .models import Park
|
||||||
|
from location.models import Location
|
||||||
|
|
||||||
|
|
||||||
class ParkForm(forms.ModelForm):
|
class ParkForm(forms.ModelForm):
|
||||||
@@ -207,8 +208,14 @@ class ParkForm(forms.ModelForm):
|
|||||||
'postal_code': self.cleaned_data.get('postal_code'),
|
'postal_code': self.cleaned_data.get('postal_code'),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set location data to be saved with the park
|
# Handle location: update if exists, create if not
|
||||||
park.set_location(**location_data)
|
if park.location.exists():
|
||||||
|
location = park.location.first()
|
||||||
|
for key, value in location_data.items():
|
||||||
|
setattr(location, key, value)
|
||||||
|
location.save()
|
||||||
|
else:
|
||||||
|
Location.objects.create(content_object=park, **location_data)
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
park.save()
|
park.save()
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from moderation.mixins import EditSubmissionMixin, PhotoSubmissionMixin, History
|
|||||||
from moderation.models import EditSubmission
|
from moderation.models import EditSubmission
|
||||||
from media.models import Photo
|
from media.models import Photo
|
||||||
from location.models import Location
|
from location.models import Location
|
||||||
|
from reviews.models import Review # Import the Review model
|
||||||
|
|
||||||
|
|
||||||
def location_search(request):
|
def location_search(request):
|
||||||
@@ -145,7 +146,7 @@ class ParkListView(ListView):
|
|||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
# Check if this is an HTMX request
|
# Check if this is an HTMX request
|
||||||
if request.htmx:
|
if hasattr(request, 'htmx') and getattr(request, 'htmx', False):
|
||||||
# If it is, return just the parks list partial
|
# If it is, return just the parks list partial
|
||||||
self.template_name = "parks/partials/park_list.html"
|
self.template_name = "parks/partials/park_list.html"
|
||||||
return super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
@@ -167,7 +168,7 @@ class ParkDetailView(
|
|||||||
queryset = self.get_queryset()
|
queryset = self.get_queryset()
|
||||||
slug = self.kwargs.get(self.slug_url_kwarg)
|
slug = self.kwargs.get(self.slug_url_kwarg)
|
||||||
# Try to get by current or historical slug
|
# Try to get by current or historical slug
|
||||||
return self.model.get_by_slug(slug)[0]
|
return Park.get_by_slug(slug)[0]
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().prefetch_related(
|
return super().get_queryset().prefetch_related(
|
||||||
@@ -186,6 +187,17 @@ class ParkDetailView(
|
|||||||
'-status', # OPERATING will come before others
|
'-status', # OPERATING will come before others
|
||||||
'name'
|
'name'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check if the user has reviewed the park
|
||||||
|
if self.request.user.is_authenticated:
|
||||||
|
context["has_reviewed"] = Review.objects.filter(
|
||||||
|
user=self.request.user,
|
||||||
|
content_type=ContentType.objects.get_for_model(Park),
|
||||||
|
object_id=self.object.id
|
||||||
|
).exists()
|
||||||
|
else:
|
||||||
|
context["has_reviewed"] = False
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_redirect_url_pattern(self):
|
def get_redirect_url_pattern(self):
|
||||||
@@ -214,8 +226,7 @@ class ParkCreateView(LoginRequiredMixin, CreateView):
|
|||||||
data[field] = str(data[field])
|
data[field] = str(data[field])
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def form_valid(self, form):
|
def normalize_coordinates(self, form):
|
||||||
# Normalize coordinates before saving
|
|
||||||
if form.cleaned_data.get("latitude"):
|
if form.cleaned_data.get("latitude"):
|
||||||
lat = Decimal(str(form.cleaned_data["latitude"]))
|
lat = Decimal(str(form.cleaned_data["latitude"]))
|
||||||
form.cleaned_data["latitude"] = lat.quantize(Decimal('0.000001'), rounding=ROUND_DOWN)
|
form.cleaned_data["latitude"] = lat.quantize(Decimal('0.000001'), rounding=ROUND_DOWN)
|
||||||
@@ -223,6 +234,10 @@ class ParkCreateView(LoginRequiredMixin, CreateView):
|
|||||||
lon = Decimal(str(form.cleaned_data["longitude"]))
|
lon = Decimal(str(form.cleaned_data["longitude"]))
|
||||||
form.cleaned_data["longitude"] = lon.quantize(Decimal('0.000001'), rounding=ROUND_DOWN)
|
form.cleaned_data["longitude"] = lon.quantize(Decimal('0.000001'), rounding=ROUND_DOWN)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
# Normalize coordinates before saving
|
||||||
|
self.normalize_coordinates(form)
|
||||||
|
|
||||||
changes = self.prepare_changes_data(form.cleaned_data)
|
changes = self.prepare_changes_data(form.cleaned_data)
|
||||||
|
|
||||||
# Create submission record
|
# Create submission record
|
||||||
@@ -236,7 +251,7 @@ class ParkCreateView(LoginRequiredMixin, CreateView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# If user is moderator or above, auto-approve
|
# If user is moderator or above, auto-approve
|
||||||
if self.request.user.role in ["MODERATOR", "ADMIN", "SUPERUSER"]:
|
if hasattr(self.request.user, 'role') and getattr(self.request.user, 'role', None) in ["MODERATOR", "ADMIN", "SUPERUSER"]:
|
||||||
try:
|
try:
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
submission.object_id = self.object.id
|
submission.object_id = self.object.id
|
||||||
@@ -337,8 +352,7 @@ class ParkUpdateView(LoginRequiredMixin, UpdateView):
|
|||||||
data[field] = str(data[field])
|
data[field] = str(data[field])
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def form_valid(self, form):
|
def normalize_coordinates(self, form):
|
||||||
# Normalize coordinates before saving
|
|
||||||
if form.cleaned_data.get("latitude"):
|
if form.cleaned_data.get("latitude"):
|
||||||
lat = Decimal(str(form.cleaned_data["latitude"]))
|
lat = Decimal(str(form.cleaned_data["latitude"]))
|
||||||
form.cleaned_data["latitude"] = lat.quantize(Decimal('0.000001'), rounding=ROUND_DOWN)
|
form.cleaned_data["latitude"] = lat.quantize(Decimal('0.000001'), rounding=ROUND_DOWN)
|
||||||
@@ -346,6 +360,10 @@ class ParkUpdateView(LoginRequiredMixin, UpdateView):
|
|||||||
lon = Decimal(str(form.cleaned_data["longitude"]))
|
lon = Decimal(str(form.cleaned_data["longitude"]))
|
||||||
form.cleaned_data["longitude"] = lon.quantize(Decimal('0.000001'), rounding=ROUND_DOWN)
|
form.cleaned_data["longitude"] = lon.quantize(Decimal('0.000001'), rounding=ROUND_DOWN)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
# Normalize coordinates before saving
|
||||||
|
self.normalize_coordinates(form)
|
||||||
|
|
||||||
changes = self.prepare_changes_data(form.cleaned_data)
|
changes = self.prepare_changes_data(form.cleaned_data)
|
||||||
|
|
||||||
# Create submission record
|
# Create submission record
|
||||||
@@ -360,7 +378,7 @@ class ParkUpdateView(LoginRequiredMixin, UpdateView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# If user is moderator or above, auto-approve
|
# If user is moderator or above, auto-approve
|
||||||
if self.request.user.role in ["MODERATOR", "ADMIN", "SUPERUSER"]:
|
if hasattr(self.request.user, 'role') and getattr(self.request.user, 'role', None) in ["MODERATOR", "ADMIN", "SUPERUSER"]:
|
||||||
try:
|
try:
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
submission.status = "APPROVED"
|
submission.status = "APPROVED"
|
||||||
@@ -464,7 +482,7 @@ class ParkAreaDetailView(
|
|||||||
park_slug = self.kwargs.get("park_slug")
|
park_slug = self.kwargs.get("park_slug")
|
||||||
area_slug = self.kwargs.get("area_slug")
|
area_slug = self.kwargs.get("area_slug")
|
||||||
# Try to get by current or historical slug
|
# Try to get by current or historical slug
|
||||||
obj, is_old_slug = self.model.get_by_slug(area_slug)
|
obj, is_old_slug = ParkArea.get_by_slug(area_slug)
|
||||||
if obj.park.slug != park_slug:
|
if obj.park.slug != park_slug:
|
||||||
raise self.model.DoesNotExist("Park slug doesn't match")
|
raise self.model.DoesNotExist("Park slug doesn't match")
|
||||||
return obj
|
return obj
|
||||||
|
|||||||
@@ -2948,6 +2948,10 @@ select {
|
|||||||
padding: 0.125rem;
|
padding: 0.125rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-1 {
|
||||||
|
padding: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.p-1\.5 {
|
.p-1\.5 {
|
||||||
padding: 0.375rem;
|
padding: 0.375rem;
|
||||||
}
|
}
|
||||||
@@ -3912,6 +3916,11 @@ select {
|
|||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sm\:text-lg {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
line-height: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
.sm\:text-sm {
|
.sm\:text-sm {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.25rem;
|
line-height: 1.25rem;
|
||||||
@@ -3926,11 +3935,6 @@ select {
|
|||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm\:text-lg {
|
|
||||||
font-size: 1.125rem;
|
|
||||||
line-height: 1.75rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
@@ -3972,11 +3976,6 @@ select {
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:text-xl {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
line-height: 1.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md\:text-lg {
|
.md\:text-lg {
|
||||||
font-size: 1.125rem;
|
font-size: 1.125rem;
|
||||||
line-height: 1.75rem;
|
line-height: 1.75rem;
|
||||||
|
|||||||
@@ -33,22 +33,42 @@
|
|||||||
<i class="mr-1 fas fa-camera"></i>Upload Photo
|
<i class="mr-1 fas fa-camera"></i>Upload Photo
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- Add/Edit Review Button -->
|
||||||
|
{% if not park.reviews.exists %}
|
||||||
|
<a href="{% url 'reviews:add_review' park.slug %}"
|
||||||
|
class="transition-transform btn-secondary hover:scale-105">
|
||||||
|
<i class="mr-1 fas fa-star"></i>Add Review
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
{% if user.has_reviewed_park(park) %}
|
||||||
|
<a href="{% url 'reviews:edit_review' park.slug %}"
|
||||||
|
class="transition-transform btn-secondary hover:scale-105">
|
||||||
|
<i class="mr-1 fas fa-star"></i>Edit Review
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'reviews:add_review' park.slug %}"
|
||||||
|
class="transition-transform btn-secondary hover:scale-105">
|
||||||
|
<i class="mr-1 fas fa-star"></i>Add Review
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Header Grid -->
|
<!-- Header Grid -->
|
||||||
<div class="grid grid-cols-2 gap-4 mb-8 sm:grid-cols-12">
|
<div class="grid grid-cols-2 gap-2 mb-6 sm:grid-cols-12">
|
||||||
<!-- Park Info Card -->
|
<!-- Park Info Card -->
|
||||||
<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">
|
<div class="flex flex-col items-center justify-center h-full col-span-2 p-3 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>
|
<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 %}
|
{% if park.formatted_location %}
|
||||||
<div class="flex items-center justify-center mt-2 text-sm text-gray-600 dark:text-gray-400">
|
<div class="flex items-center justify-center mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||||
<i class="mr-1 fas fa-map-marker-alt"></i>
|
<i class="mr-1 fas fa-map-marker-alt"></i>
|
||||||
<p>{{ park.formatted_location }}</p>
|
<p>{{ park.formatted_location }}</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="flex flex-wrap items-center justify-center gap-2 mt-3">
|
<div class="flex flex-wrap items-center justify-center gap-1 mt-2">
|
||||||
<span class="status-badge text-xs sm:text-sm font-medium py-1 px-3 {% if park.status == 'OPERATING' %}status-operating
|
<span class="status-badge text-xs sm:text-sm font-medium py-1 px-2 {% if park.status == 'OPERATING' %}status-operating
|
||||||
{% elif park.status == 'CLOSED_TEMP' or park.status == 'CLOSED_PERM' %}status-closed
|
{% elif park.status == 'CLOSED_TEMP' or park.status == 'CLOSED_PERM' %}status-closed
|
||||||
{% elif park.status == 'UNDER_CONSTRUCTION' %}status-construction
|
{% elif park.status == 'UNDER_CONSTRUCTION' %}status-construction
|
||||||
{% elif park.status == 'DEMOLISHED' %}status-demolished
|
{% elif park.status == 'DEMOLISHED' %}status-demolished
|
||||||
@@ -56,7 +76,7 @@
|
|||||||
{{ park.get_status_display }}
|
{{ park.get_status_display }}
|
||||||
</span>
|
</span>
|
||||||
{% if park.average_rating %}
|
{% if park.average_rating %}
|
||||||
<span class="flex items-center px-3 py-1 text-xs font-medium text-yellow-800 bg-yellow-100 sm:text-sm status-badge dark:bg-yellow-600 dark:text-yellow-50">
|
<span class="flex items-center px-2 py-1 text-xs font-medium text-yellow-800 bg-yellow-100 sm:text-sm status-badge dark:bg-yellow-600 dark:text-yellow-50">
|
||||||
<span class="mr-1 text-yellow-500 dark:text-yellow-200">★</span>
|
<span class="mr-1 text-yellow-500 dark:text-yellow-200">★</span>
|
||||||
{{ park.average_rating|floatformat:1 }}/10
|
{{ park.average_rating|floatformat:1 }}/10
|
||||||
</span>
|
</span>
|
||||||
@@ -65,31 +85,31 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Stats and Quick Facts -->
|
<!-- Stats and Quick Facts -->
|
||||||
<div class="grid h-full grid-cols-2 col-span-2 gap-4 sm:col-span-9">
|
<div class="grid h-full grid-cols-2 col-span-2 gap-2 sm:col-span-9">
|
||||||
<!-- Stats Column -->
|
<!-- Stats Column -->
|
||||||
<div class="grid grid-cols-2 col-span-12 gap-4 sm:col-span-4">
|
<div class="grid grid-cols-2 col-span-12 gap-2 sm:col-span-4">
|
||||||
<!-- Total Rides Card -->
|
<!-- Total Rides Card -->
|
||||||
<a href="{% url 'parks:rides:ride_list' park.slug %}"
|
<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">
|
class="flex flex-col items-center justify-center p-3 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 lg:text-lg dark:text-white">Total Rides</dt>
|
<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">
|
<dd class="mt-1 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" }}
|
{{ park.total_rides|default:"N/A" }}
|
||||||
</dd>
|
</dd>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Total Roller Coasters Card -->
|
<!-- Total Roller Coasters Card -->
|
||||||
<div class="flex flex-col items-center justify-center p-4 text-center bg-white rounded-lg shadow-lg dark:bg-gray-800">
|
<div class="flex flex-col items-center justify-center p-3 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">Roller Coasters</dt>
|
<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">
|
<dd class="mt-1 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" }}
|
{{ park.total_roller_coasters|default:"N/A" }}
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Quick Facts Grid -->
|
<!-- 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">
|
<div class="grid h-full grid-cols-3 col-span-12 gap-1 p-3 bg-white rounded-lg shadow-lg sm:col-span-8 dark:bg-gray-800">
|
||||||
{% if park.owner %}
|
{% if park.owner %}
|
||||||
<div class="flex flex-col items-center justify-center p-2 text-center">
|
<div class="flex flex-col items-center justify-center p-1 text-center">
|
||||||
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-building dark:text-blue-400"></i>
|
<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>
|
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Owner</dt>
|
||||||
<dd>
|
<dd>
|
||||||
@@ -102,7 +122,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if park.opening_date %}
|
{% if park.opening_date %}
|
||||||
<div class="flex flex-col items-center justify-center p-2 text-center">
|
<div class="flex flex-col items-center justify-center p-1 text-center">
|
||||||
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-calendar-alt dark:text-blue-400"></i>
|
<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>
|
<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>
|
<dd class="text-xs text-gray-900 sm:text-sm lg:text-base dark:text-white">{{ park.opening_date }}</dd>
|
||||||
@@ -110,7 +130,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if park.website %}
|
{% if park.website %}
|
||||||
<div class="flex flex-col items-center justify-center p-2 text-center">
|
<div class="flex flex-col items-center justify-center p-1 text-center">
|
||||||
<i class="text-lg text-blue-600 sm:text-xl lg:text-2xl fas fa-globe dark:text-blue-400"></i>
|
<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>
|
<dt class="mt-1 text-xs font-medium text-gray-500 sm:text-sm lg:text-base dark:text-gray-400">Website</dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
|||||||
Reference in New Issue
Block a user