Files
thrillwiki_django_no_react/templates/components/cards/park_card.html
pacnpal b1c369c1bb Add park and ride card components with advanced search functionality
- 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.
2025-09-24 23:10:48 -04:00

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>