mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 06:31:09 -05:00
- Implemented park card component with image, status badge, favorite button, and quick stats overlay. - Developed ride card component featuring thrill level badge, status badge, favorite button, and detailed stats. - Created advanced search page with filters for parks and rides, including location, type, status, and thrill level. - Added dynamic quick search functionality with results display. - Enhanced user experience with JavaScript for filter toggling, range slider updates, and view switching. - Included custom CSS for improved styling of checkboxes and search results layout.
167 lines
6.2 KiB
HTML
167 lines
6.2 KiB
HTML
<!-- Park Card Component -->
|
|
<div class="card-park hover-lift group"
|
|
hx-get="{% url 'parks:detail' park.slug %}"
|
|
hx-target="#main-content"
|
|
hx-swap="innerHTML transition:true">
|
|
|
|
<!-- Park Image with Overlay -->
|
|
<div class="relative overflow-hidden rounded-t-2xl">
|
|
{% if park.featured_image %}
|
|
<img src="{{ park.featured_image.url }}"
|
|
alt="{{ park.name }}"
|
|
class="card-park-image"
|
|
loading="lazy">
|
|
{% else %}
|
|
<div class="card-park-image bg-gradient-to-br from-thrill-primary/20 to-thrill-secondary/20 flex items-center justify-center">
|
|
<i class="fas fa-map-marked-alt text-6xl text-thrill-primary/40"></i>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Status Badge -->
|
|
<div class="absolute top-4 left-4">
|
|
{% if park.status == 'OPERATING' %}
|
|
<span class="badge-operating">
|
|
<i class="fas fa-check-circle mr-1"></i>
|
|
Operating
|
|
</span>
|
|
{% elif park.status == 'CONSTRUCTION' %}
|
|
<span class="badge-construction">
|
|
<i class="fas fa-hard-hat mr-1"></i>
|
|
Under Construction
|
|
</span>
|
|
{% elif park.status == 'CLOSED_PERMANENTLY' %}
|
|
<span class="badge-closed">
|
|
<i class="fas fa-times-circle mr-1"></i>
|
|
Closed
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Favorite Button -->
|
|
<div class="absolute top-4 right-4">
|
|
<button class="w-10 h-10 bg-white/90 dark:bg-neutral-800/90 backdrop-blur-sm rounded-full flex items-center justify-center hover:bg-white dark:hover:bg-neutral-800 transition-all duration-200 hover:scale-110"
|
|
hx-post="{% url 'parks:toggle_favorite' park.slug %}"
|
|
hx-swap="outerHTML"
|
|
onclick="event.stopPropagation()">
|
|
{% if park.is_favorited %}
|
|
<i class="fas fa-heart text-red-500"></i>
|
|
{% else %}
|
|
<i class="far fa-heart text-neutral-600 dark:text-neutral-400"></i>
|
|
{% endif %}
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Gradient Overlay -->
|
|
<div class="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
|
|
<!-- Quick Stats Overlay -->
|
|
<div class="absolute bottom-4 left-4 right-4 transform translate-y-4 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300">
|
|
<div class="flex items-center justify-between text-white text-sm">
|
|
<div class="flex items-center space-x-4">
|
|
{% if park.ride_count %}
|
|
<div class="flex items-center">
|
|
<i class="fas fa-rocket mr-1"></i>
|
|
{{ park.ride_count }} rides
|
|
</div>
|
|
{% endif %}
|
|
{% if park.area %}
|
|
<div class="flex items-center">
|
|
<i class="fas fa-expand-arrows-alt mr-1"></i>
|
|
{{ park.area }} acres
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% if park.rating %}
|
|
<div class="flex items-center">
|
|
<i class="fas fa-star text-yellow-400 mr-1"></i>
|
|
{{ park.rating|floatformat:1 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Park Content -->
|
|
<div class="card-park-content">
|
|
<!-- Park Name and Location -->
|
|
<div class="space-y-2">
|
|
<h3 class="text-xl font-bold text-neutral-900 dark:text-neutral-100 group-hover:text-thrill-primary transition-colors duration-200">
|
|
{{ park.name }}
|
|
</h3>
|
|
|
|
{% if park.location %}
|
|
<div class="flex items-center text-neutral-600 dark:text-neutral-400 text-sm">
|
|
<i class="fas fa-map-marker-alt mr-2 text-thrill-primary"></i>
|
|
{{ park.location.city }}{% if park.location.region %}, {{ park.location.region }}{% endif %}
|
|
{% if park.location.country %}, {{ park.location.country }}{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Park Description -->
|
|
{% if park.description %}
|
|
<p class="text-neutral-600 dark:text-neutral-400 text-sm line-clamp-2">
|
|
{{ park.description|truncatewords:20 }}
|
|
</p>
|
|
{% endif %}
|
|
|
|
<!-- Park Features/Tags -->
|
|
{% if park.features.all %}
|
|
<div class="flex flex-wrap gap-2">
|
|
{% for feature in park.features.all|slice:":3" %}
|
|
<span class="px-2 py-1 bg-thrill-primary/10 text-thrill-primary text-xs rounded-full">
|
|
{{ feature.name }}
|
|
</span>
|
|
{% endfor %}
|
|
{% if park.features.count > 3 %}
|
|
<span class="px-2 py-1 bg-neutral-100 dark:bg-neutral-700 text-neutral-600 dark:text-neutral-400 text-xs rounded-full">
|
|
+{{ park.features.count|add:"-3" }} more
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Park Stats -->
|
|
<div class="flex items-center justify-between pt-4 border-t border-neutral-200/50 dark:border-neutral-700/50">
|
|
<div class="flex items-center space-x-4 text-sm text-neutral-600 dark:text-neutral-400">
|
|
{% if park.opened_date %}
|
|
<div class="flex items-center">
|
|
<i class="fas fa-calendar mr-1"></i>
|
|
{{ park.opened_date.year }}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if park.park_type %}
|
|
<div class="flex items-center">
|
|
<i class="fas fa-tag mr-1"></i>
|
|
{{ park.get_park_type_display }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Action Button -->
|
|
<button class="btn-primary btn-sm opacity-0 group-hover:opacity-100 transition-all duration-200 transform translate-x-2 group-hover:translate-x-0">
|
|
<i class="fas fa-arrow-right mr-2"></i>
|
|
Explore
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Loading State Overlay -->
|
|
<div class="absolute inset-0 bg-white/80 dark:bg-neutral-800/80 backdrop-blur-sm rounded-2xl flex items-center justify-center opacity-0 htmx-request:opacity-100 transition-opacity duration-200 pointer-events-none">
|
|
<div class="loading-spinner opacity-100">
|
|
<i class="fas fa-spinner text-2xl text-thrill-primary"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- CSS for line-clamp utility -->
|
|
<style>
|
|
.line-clamp-2 {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
</style>
|