feat: Add detailed park and ride pages with HTMX integration

- Implemented park detail page with dynamic content loading for rides and weather.
- Created park list page with filters and search functionality.
- Developed ride detail page showcasing ride stats, reviews, and similar rides.
- Added ride list page with filtering options and dynamic loading.
- Introduced search results page with tabs for parks, rides, and users.
- Added HTMX tests for global search functionality.
This commit is contained in:
pacnpal
2025-12-19 19:53:20 -05:00
parent bf04e4d854
commit b9063ff4f8
154 changed files with 4536 additions and 2570 deletions

View File

@@ -0,0 +1,120 @@
{% extends "base/htmx-base.html" %}
{% load static %}
{% block title %}Search Results - ThrillWiki{% endblock %}
{% block main %}
<div class="container py-8">
<div class="max-w-4xl mx-auto">
<!-- Search Header -->
<div class="mb-8 text-center">
<h1 class="mb-4 text-3xl font-bold tracking-tight">Search Results</h1>
<div class="max-w-xl mx-auto">
<form action="{% url 'search:results' %}" method="get" class="relative">
<input type="text"
name="q"
value="{{ query|default:'' }}"
placeholder="Search parks, rides, manufacturers..."
class="w-full h-12 pl-12 pr-4 text-lg transition-all border rounded-lg shadow-sm border-input bg-background focus:ring-2 focus:ring-primary focus:border-primary">
<div class="absolute -translate-y-1/2 left-4 top-1/2 text-muted-foreground">
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
<button type="submit" class="absolute right-2 top-1/2 -translate-y-1/2 px-4 py-1.5 bg-primary text-primary-foreground rounded-md text-sm font-medium hover:bg-primary/90 transition-colors">
Search
</button>
</form>
</div>
</div>
<!-- Filters Tabs -->
<div class="flex items-center justify-center gap-2 pb-2 mb-8 overflow-x-auto" x-data="{ tab: 'all' }">
<button @click="tab = 'all'"
:class="tab === 'all' ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground hover:bg-muted/80'"
class="px-4 py-2 text-sm font-medium transition-colors rounded-full whitespace-nowrap">
All Results
</button>
<button @click="tab = 'parks'"
:class="tab === 'parks' ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground hover:bg-muted/80'"
class="px-4 py-2 text-sm font-medium transition-colors rounded-full whitespace-nowrap">
Parks
</button>
<button @click="tab = 'rides'"
:class="tab === 'rides' ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground hover:bg-muted/80'"
class="px-4 py-2 text-sm font-medium transition-colors rounded-full whitespace-nowrap">
Rides
</button>
<button @click="tab = 'users'"
:class="tab === 'users' ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground hover:bg-muted/80'"
class="px-4 py-2 text-sm font-medium transition-colors rounded-full whitespace-nowrap">
Users
</button>
</div>
<!-- Results Grid -->
<div class="space-y-8">
{% if not query %}
<div class="py-12 text-center">
<div class="flex items-center justify-center w-16 h-16 mx-auto mb-4 rounded-full bg-muted">
<svg class="w-8 h-8 text-muted-foreground" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
<h3 class="text-lg font-medium text-foreground">Start Searching</h3>
<p class="mt-1 text-muted-foreground">Enter a keyword to find parks, rides, and more.</p>
</div>
{% else %}
<!-- Parks Section -->
<section x-show="tab === 'all' || tab === 'parks'">
<div class="flex items-center justify-between mb-4">
<h2 class="text-xl font-bold">Parks</h2>
<span class="text-sm text-muted-foreground">3 results</span>
</div>
<div class="grid gap-4 sm:grid-cols-2">
{% for i in "123"|make_list %}
<a href="#" class="flex gap-4 p-4 transition-colors border rounded-lg bg-card hover:bg-muted/50">
<div class="w-20 h-20 rounded-md bg-muted shrink-0"></div>
<div>
<h3 class="text-lg font-semibold">Cedar Point</h3>
<p class="text-sm text-muted-foreground">Sandusky, OH, United States</p>
<div class="flex items-center gap-2 mt-2 text-xs text-muted-foreground">
<span class="bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400 px-2 py-0.5 rounded-full">Operating</span>
<span></span>
<span>72 Rides</span>
</div>
</div>
</a>
{% endfor %}
</div>
</section>
<!-- Rides Section -->
<section x-show="tab === 'all' || tab === 'rides'">
<div class="flex items-center justify-between mb-4">
<h2 class="text-xl font-bold">Rides</h2>
<span class="text-sm text-muted-foreground">5 results</span>
</div>
<div class="grid gap-4 sm:grid-cols-2">
{% for i in "12345"|make_list %}
<a href="#" class="flex gap-4 p-4 transition-colors border rounded-lg bg-card hover:bg-muted/50">
<div class="w-20 h-20 rounded-md bg-muted shrink-0"></div>
<div>
<h3 class="text-lg font-semibold">Millennium Force</h3>
<p class="text-sm text-muted-foreground">Cedar Point</p>
<div class="flex items-center gap-2 mt-2 text-xs text-muted-foreground">
<span class="font-medium text-yellow-600 dark:text-yellow-400">★ 4.9</span>
<span></span>
<span>Giga Coaster</span>
</div>
</div>
</a>
{% endfor %}
</div>
</section>
{% endif %}
</div>
</div>
</div>
{% endblock %}