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,42 @@
<div class="relative w-full" x-data="{ open: false, selected: [], query: '' }">
<label class="block mb-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
{{ label }}
</label>
<div class="relative">
<button type="button"
@click="open = !open"
class="flex items-center justify-between w-full h-10 px-3 py-2 text-sm border rounded-md border-input bg-background ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50">
<span x-text="selected.length ? `${selected.length} selected` : '{{ placeholder|default:'Select options...' }}'"></span>
<svg class="w-4 h-4 opacity-50" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div x-show="open"
@click.away="open = false"
class="absolute z-50 w-full mt-2 border rounded-md shadow-md outline-none top-full bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95">
<div class="p-2 border-b">
<input type="text"
x-model="query"
class="flex w-full px-3 py-1 text-sm transition-colors bg-transparent rounded-md shadow-sm h-9 placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
placeholder="Search...">
</div>
<div class="max-h-[200px] overflow-y-auto p-1">
{% for option in options %}
<label class="flex items-center p-2 space-x-2 rounded-sm cursor-pointer hover:bg-accent hover:text-accent-foreground"
x-show="query === '' || '{{ option.label }}'.toLowerCase().includes(query.toLowerCase())">
<input type="checkbox"
name="{{ name }}"
value="{{ option.value }}"
x-model="selected"
class="w-4 h-4 rounded border-primary text-primary focus:ring-primary">
<span class="text-sm">{{ option.label }}</span>
</label>
{% endfor %}
</div>
</div>
</div>
</div>