mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 07:51:09 -05:00
Update size attribute for login and join buttons in enhanced_header.html from 'sm' to 'default' to increase touch target size on mobile. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 8c9d0d4b-ca6f-406f-bbbe-b9c86b7a6f6e Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d6d61dac-164d-45dd-929f-7dcdfd771b64/8c9d0d4b-ca6f-406f-bbbe-b9c86b7a6f6e/dTiRCJZ
453 lines
22 KiB
HTML
453 lines
22 KiB
HTML
{% comment %}
|
|
Enhanced Header Component - Matches React Frontend Design
|
|
Includes: Browse menu, advanced search, theme toggle, user dropdown, mobile menu
|
|
{% endcomment %}
|
|
|
|
{% load static %}
|
|
|
|
<header class="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
<div class="flex h-14 items-center justify-between px-4 max-w-full">
|
|
|
|
<!-- Logo and Browse Menu -->
|
|
<div class="flex items-center space-x-6">
|
|
<!-- Logo -->
|
|
<a href="{% url 'home' %}" class="flex items-center space-x-2 flex-shrink-0">
|
|
<div class="w-6 h-6 bg-purple-600 rounded flex items-center justify-center">
|
|
<span class="text-white text-xs font-bold">TW</span>
|
|
</div>
|
|
<span class="font-bold text-lg">ThrillWiki</span>
|
|
</a>
|
|
|
|
<!-- Browse Menu (Desktop) -->
|
|
<div class="hidden md:block">
|
|
<div
|
|
x-data="{ open: false }"
|
|
@mouseenter="open = true"
|
|
@mouseleave="open = false"
|
|
class="relative"
|
|
>
|
|
<button
|
|
class="flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md hover:bg-accent transition-colors"
|
|
@click="open = !open"
|
|
>
|
|
<i class="fas fa-compass w-4 h-4"></i>
|
|
Browse
|
|
<i class="fas fa-chevron-down w-4 h-4"></i>
|
|
</button>
|
|
|
|
<!-- Browse Dropdown -->
|
|
<div
|
|
x-show="open"
|
|
x-transition:enter="transition ease-out duration-100"
|
|
x-transition:enter-start="transform opacity-0 scale-95"
|
|
x-transition:enter-end="transform opacity-100 scale-100"
|
|
x-transition:leave="transition ease-in duration-75"
|
|
x-transition:leave-start="transform opacity-100 scale-100"
|
|
x-transition:leave-end="transform opacity-0 scale-95"
|
|
x-cloak
|
|
class="absolute left-0 mt-2 w-[480px] p-6 bg-background border rounded-lg shadow-lg z-50"
|
|
>
|
|
<div class="grid grid-cols-2 gap-6">
|
|
<!-- Left Column -->
|
|
<div class="space-y-4">
|
|
<a
|
|
href="{% url 'parks:park_list' %}"
|
|
class="flex items-start gap-3 p-3 rounded-lg hover:bg-accent transition-colors group"
|
|
@click="open = false"
|
|
>
|
|
<i class="fas fa-map-marker-alt w-5 h-5 mt-0.5 text-muted-foreground group-hover:text-foreground"></i>
|
|
<div>
|
|
<h3 class="font-semibold text-sm mb-1">Parks</h3>
|
|
<p class="text-xs text-muted-foreground">Explore theme parks worldwide</p>
|
|
</div>
|
|
</a>
|
|
|
|
<a
|
|
href="{% url 'rides:manufacturer_list' %}"
|
|
class="flex items-start gap-3 p-3 rounded-lg hover:bg-accent transition-colors group"
|
|
@click="open = false"
|
|
>
|
|
<i class="fas fa-wrench w-5 h-5 mt-0.5 text-muted-foreground group-hover:text-foreground"></i>
|
|
<div>
|
|
<h3 class="font-semibold text-sm mb-1">Manufacturers</h3>
|
|
<p class="text-xs text-muted-foreground">Ride and attraction manufacturers</p>
|
|
</div>
|
|
</a>
|
|
|
|
<a
|
|
href="{% url 'parks:operator_list' %}"
|
|
class="flex items-start gap-3 p-3 rounded-lg hover:bg-accent transition-colors group"
|
|
@click="open = false"
|
|
>
|
|
<i class="fas fa-users w-5 h-5 mt-0.5 text-muted-foreground group-hover:text-foreground"></i>
|
|
<div>
|
|
<h3 class="font-semibold text-sm mb-1">Operators</h3>
|
|
<p class="text-xs text-muted-foreground">Theme park operating companies</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Right Column -->
|
|
<div class="space-y-4">
|
|
<a
|
|
href="{% url 'rides:global_ride_list' %}"
|
|
class="flex items-start gap-3 p-3 rounded-lg hover:bg-accent transition-colors group"
|
|
@click="open = false"
|
|
>
|
|
<i class="fas fa-rocket w-5 h-5 mt-0.5 text-muted-foreground group-hover:text-foreground"></i>
|
|
<div>
|
|
<h3 class="font-semibold text-sm mb-1">Rides</h3>
|
|
<p class="text-xs text-muted-foreground">Discover rides and attractions</p>
|
|
</div>
|
|
</a>
|
|
|
|
<a
|
|
href="{% url 'rides:designer_list' %}"
|
|
class="flex items-start gap-3 p-3 rounded-lg hover:bg-accent transition-colors group"
|
|
@click="open = false"
|
|
>
|
|
<i class="fas fa-drafting-compass w-5 h-5 mt-0.5 text-muted-foreground group-hover:text-foreground"></i>
|
|
<div>
|
|
<h3 class="font-semibold text-sm mb-1">Designers</h3>
|
|
<p class="text-xs text-muted-foreground">Ride designers and architects</p>
|
|
</div>
|
|
</a>
|
|
|
|
<a
|
|
href="#"
|
|
class="flex items-start gap-3 p-3 rounded-lg hover:bg-accent transition-colors group"
|
|
@click="open = false"
|
|
>
|
|
<i class="fas fa-trophy w-5 h-5 mt-0.5 text-muted-foreground group-hover:text-foreground"></i>
|
|
<div>
|
|
<h3 class="font-semibold text-sm mb-1">Top Lists</h3>
|
|
<p class="text-xs text-muted-foreground">Community rankings and favorites</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Desktop Right Side -->
|
|
<div class="hidden md:flex items-center space-x-4">
|
|
<!-- Enhanced Search -->
|
|
<div class="relative" x-data="searchComponent">
|
|
<div class="relative">
|
|
<i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground"></i>
|
|
<input
|
|
type="search"
|
|
placeholder="Search parks, rides..."
|
|
class="w-[300px] pl-10 pr-20 h-10 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
|
x-model="query"
|
|
@input.debounce.300ms="search()"
|
|
hx-get="{% url 'search:search' %}"
|
|
hx-trigger="input changed delay:300ms"
|
|
hx-target="#search-results"
|
|
hx-include="this"
|
|
name="q"
|
|
/>
|
|
{% include 'components/ui/button.html' with variant='default' size='sm' text='Search' class='absolute right-1 top-1/2 transform -translate-y-1/2' %}
|
|
</div>
|
|
|
|
<!-- Search Results Dropdown -->
|
|
<div
|
|
id="search-results"
|
|
x-show="results.length > 0"
|
|
x-transition
|
|
x-cloak
|
|
class="absolute top-full left-0 right-0 mt-1 bg-background border rounded-md shadow-lg z-50 max-h-96 overflow-y-auto"
|
|
>
|
|
<!-- Search results will be populated by HTMX -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Theme Toggle -->
|
|
<div x-data="themeToggle">
|
|
<button
|
|
@click="toggleTheme()"
|
|
class="inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground h-10 w-10"
|
|
>
|
|
<i class="fas fa-sun h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"></i>
|
|
<i class="fas fa-moon absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"></i>
|
|
<span class="sr-only">Toggle theme</span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- User Menu -->
|
|
{% if user.is_authenticated %}
|
|
<div class="relative" x-data="{ open: false }" @click.outside="open = false">
|
|
<button @click="open = !open" class="relative h-8 w-8 rounded-full">
|
|
{% if user.profile.avatar %}
|
|
<img
|
|
src="{{ user.profile.avatar.url }}"
|
|
alt="{{ user.get_full_name|default:user.username }}"
|
|
class="h-8 w-8 rounded-full object-cover"
|
|
/>
|
|
{% else %}
|
|
<div class="h-8 w-8 rounded-full bg-primary flex items-center justify-center text-primary-foreground text-sm font-medium">
|
|
{{ user.get_full_name.0|default:user.username.0|upper }}
|
|
</div>
|
|
{% endif %}
|
|
</button>
|
|
|
|
<!-- User Dropdown -->
|
|
<div
|
|
x-show="open"
|
|
x-transition:enter="transition ease-out duration-100"
|
|
x-transition:enter-start="transform opacity-0 scale-95"
|
|
x-transition:enter-end="transform opacity-100 scale-100"
|
|
x-transition:leave="transition ease-in duration-75"
|
|
x-transition:leave-start="transform opacity-100 scale-100"
|
|
x-transition:leave-end="transform opacity-0 scale-95"
|
|
x-cloak
|
|
class="absolute right-0 mt-2 w-56 bg-background border rounded-md shadow-lg z-50"
|
|
>
|
|
<div class="flex items-center justify-start gap-2 p-2">
|
|
<div class="flex flex-col space-y-1 leading-none">
|
|
<p class="font-medium">{{ user.get_full_name|default:user.username }}</p>
|
|
<p class="w-[200px] truncate text-sm text-muted-foreground">{{ user.email }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="border-t"></div>
|
|
<a href="{% url 'profile' user.username %}" class="flex items-center px-2 py-2 text-sm hover:bg-accent">
|
|
<i class="fas fa-user mr-2 h-4 w-4"></i>
|
|
Profile
|
|
</a>
|
|
<a href="{% url 'settings' %}" class="flex items-center px-2 py-2 text-sm hover:bg-accent">
|
|
<i class="fas fa-cog mr-2 h-4 w-4"></i>
|
|
Settings
|
|
</a>
|
|
{% if has_moderation_access %}
|
|
<a href="{% url 'moderation:dashboard' %}" class="flex items-center px-2 py-2 text-sm hover:bg-accent">
|
|
<i class="fas fa-shield-alt mr-2 h-4 w-4"></i>
|
|
Moderation
|
|
</a>
|
|
{% endif %}
|
|
<div class="border-t"></div>
|
|
<form method="post" action="{% url 'account_logout' %}">
|
|
{% csrf_token %}
|
|
<button type="submit" class="flex items-center w-full px-2 py-2 text-sm text-red-600 hover:bg-accent">
|
|
<i class="fas fa-sign-out-alt mr-2 h-4 w-4"></i>
|
|
Log out
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="flex items-center space-x-2">
|
|
<button
|
|
@click="window.authModal.show('login')"
|
|
class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 rounded-md px-3"
|
|
>
|
|
Sign In
|
|
</button>
|
|
<button
|
|
@click="window.authModal.show('register')"
|
|
class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-9 rounded-md px-3"
|
|
>
|
|
Sign Up
|
|
</button>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Mobile Menu -->
|
|
<div class="md:hidden flex items-center space-x-2 flex-shrink-0">
|
|
<!-- Theme Toggle (Mobile) -->
|
|
<div x-data="themeToggle">
|
|
<button
|
|
@click="toggleTheme()"
|
|
class="inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground h-10 w-10"
|
|
>
|
|
<i class="fas fa-sun h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"></i>
|
|
<i class="fas fa-moon absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Mobile User Menu -->
|
|
{% if user.is_authenticated %}
|
|
<div class="relative" x-data="{ open: false }" @click.outside="open = false">
|
|
<button @click="open = !open" class="relative h-8 w-8 rounded-full">
|
|
{% if user.profile.avatar %}
|
|
<img
|
|
src="{{ user.profile.avatar.url }}"
|
|
alt="{{ user.get_full_name|default:user.username }}"
|
|
class="h-8 w-8 rounded-full object-cover"
|
|
/>
|
|
{% else %}
|
|
<div class="h-8 w-8 rounded-full bg-primary flex items-center justify-center text-primary-foreground text-sm font-medium">
|
|
{{ user.get_full_name.0|default:user.username.0|upper }}
|
|
</div>
|
|
{% endif %}
|
|
</button>
|
|
|
|
<!-- Mobile User Dropdown -->
|
|
<div
|
|
x-show="open"
|
|
x-transition
|
|
x-cloak
|
|
class="absolute right-0 mt-2 w-56 bg-background border rounded-md shadow-lg z-50"
|
|
>
|
|
<div class="flex items-center justify-start gap-2 p-2">
|
|
<div class="flex flex-col space-y-1 leading-none">
|
|
<p class="font-medium">{{ user.get_full_name|default:user.username }}</p>
|
|
<p class="w-[200px] truncate text-sm text-muted-foreground">{{ user.email }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="border-t"></div>
|
|
<form method="post" action="{% url 'account_logout' %}">
|
|
{% csrf_token %}
|
|
<button type="submit" class="flex items-center w-full px-2 py-2 text-sm text-red-600 hover:bg-accent">
|
|
<i class="fas fa-sign-out-alt mr-2 h-4 w-4"></i>
|
|
Log out
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="flex items-center space-x-1">
|
|
<div
|
|
hx-get="{% url 'account_login' %}"
|
|
hx-target="body"
|
|
hx-swap="beforeend"
|
|
class="cursor-pointer"
|
|
>
|
|
{% include 'components/ui/button.html' with variant='outline' size='default' text='Login' %}
|
|
</div>
|
|
<div
|
|
hx-get="{% url 'account_signup' %}"
|
|
hx-target="body"
|
|
hx-swap="beforeend"
|
|
class="cursor-pointer"
|
|
>
|
|
{% include 'components/ui/button.html' with variant='default' size='default' text='Join' %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Mobile Menu Button -->
|
|
<div x-data="{ open: false }">
|
|
<button
|
|
@click="open = !open"
|
|
class="inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground h-10 w-10"
|
|
>
|
|
<i class="fas fa-bars h-5 w-5"></i>
|
|
</button>
|
|
|
|
<!-- Mobile Menu Overlay -->
|
|
<div
|
|
x-show="open"
|
|
x-transition:enter="transition-opacity ease-linear duration-300"
|
|
x-transition:enter-start="opacity-0"
|
|
x-transition:enter-end="opacity-100"
|
|
x-transition:leave="transition-opacity ease-linear duration-300"
|
|
x-transition:leave-start="opacity-100"
|
|
x-transition:leave-end="opacity-0"
|
|
x-cloak
|
|
class="fixed inset-0 z-50 bg-background/80 backdrop-blur-sm"
|
|
@click="open = false"
|
|
>
|
|
<!-- Mobile Menu Panel -->
|
|
<div
|
|
x-show="open"
|
|
x-transition:enter="transition ease-in-out duration-300 transform"
|
|
x-transition:enter-start="translate-x-full"
|
|
x-transition:enter-end="translate-x-0"
|
|
x-transition:leave="transition ease-in-out duration-300 transform"
|
|
x-transition:leave-start="translate-x-0"
|
|
x-transition:leave-end="translate-x-full"
|
|
class="fixed right-0 top-0 h-full w-full sm:w-96 bg-background border-l shadow-lg"
|
|
@click.stop
|
|
>
|
|
<div class="flex flex-col h-full">
|
|
<!-- Mobile Menu Header -->
|
|
<div class="flex items-center justify-between p-4 border-b">
|
|
<div class="flex items-center space-x-2">
|
|
<div class="w-6 h-6 bg-purple-600 rounded flex items-center justify-center">
|
|
<span class="text-white text-xs font-bold">TW</span>
|
|
</div>
|
|
<span class="font-bold text-lg">ThrillWiki</span>
|
|
</div>
|
|
<button
|
|
@click="open = false"
|
|
class="inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground h-10 w-10"
|
|
>
|
|
<i class="fas fa-times h-5 w-5"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Mobile Menu Content -->
|
|
<div class="flex-1 overflow-y-auto p-4 space-y-6">
|
|
<p class="text-sm text-muted-foreground">
|
|
Navigate through the ultimate theme park database
|
|
</p>
|
|
|
|
<!-- Navigation Section -->
|
|
<div>
|
|
<h3 class="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-3">
|
|
NAVIGATION
|
|
</h3>
|
|
<div class="space-y-1">
|
|
<a href="{% url 'home' %}" class="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-accent transition-colors" @click="open = false">
|
|
<i class="fas fa-home w-4 h-4"></i>
|
|
<span>Home</span>
|
|
</a>
|
|
<a href="{% url 'search:search' %}" class="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-accent transition-colors" @click="open = false">
|
|
<i class="fas fa-search w-4 h-4"></i>
|
|
<span>Search</span>
|
|
</a>
|
|
<a href="{% url 'parks:park_list' %}" class="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-accent transition-colors" @click="open = false">
|
|
<i class="fas fa-map-marker-alt w-4 h-4"></i>
|
|
<span>Parks</span>
|
|
</a>
|
|
<a href="{% url 'rides:global_ride_list' %}" class="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-accent transition-colors" @click="open = false">
|
|
<i class="fas fa-rocket w-4 h-4"></i>
|
|
<span>Rides</span>
|
|
</a>
|
|
<a href="{% url 'rides:manufacturer_list' %}" class="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-accent transition-colors" @click="open = false">
|
|
<i class="fas fa-wrench w-4 h-4"></i>
|
|
<span>Manufacturers</span>
|
|
</a>
|
|
<a href="{% url 'parks:operator_list' %}" class="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-accent transition-colors" @click="open = false">
|
|
<i class="fas fa-building w-4 h-4"></i>
|
|
<span>Operators</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Mobile Search Bar -->
|
|
<div class="md:hidden border-t bg-background">
|
|
<div class="px-4 py-3">
|
|
<div class="flex items-center gap-2 w-full">
|
|
<div class="relative flex-1">
|
|
<i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground"></i>
|
|
<input
|
|
type="search"
|
|
placeholder="Search parks, rides..."
|
|
class="w-full pl-10 pr-3 h-10 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
|
hx-get="{% url 'search:search' %}"
|
|
hx-trigger="input changed delay:300ms"
|
|
hx-target="#mobile-search-results"
|
|
hx-include="this"
|
|
name="q"
|
|
/>
|
|
</div>
|
|
<button type="submit" class="flex-shrink-0 inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 w-10">
|
|
<i class="fas fa-search h-4 w-4"></i>
|
|
</button>
|
|
</div>
|
|
<div id="mobile-search-results" class="mt-2"></div>
|
|
</div>
|
|
</div>
|
|
</header>
|