diff --git a/parks/static/parks/css/search.css b/parks/static/parks/css/search.css index 250a8745..15cfba9a 100644 --- a/parks/static/parks/css/search.css +++ b/parks/static/parks/css/search.css @@ -1,21 +1,47 @@ /* Loading indicator */ .htmx-indicator { opacity: 0; + transition: opacity 200ms ease-in-out; } .htmx-request .htmx-indicator { opacity: 1; } -/* Search results spacing */ +/* Search results container */ #search-results { margin-top: 0.5rem; + border: 1px solid #e5e7eb; + border-radius: 0.5rem; + background-color: white; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + max-height: 400px; + overflow-y: auto; +} + +#search-results:empty { + display: none; +} + +/* Search result items */ +#search-results .border-b { + border-color: #e5e7eb; +} + +#search-results a { + display: block; + transition: background-color 150ms ease-in-out; +} + +#search-results a:hover { + background-color: #f3f4f6; } /* Dark mode adjustments */ @media (prefers-color-scheme: dark) { - #search-results .bg-white { + #search-results { background-color: #1f2937; + border-color: #374151; } #search-results .text-gray-900 { @@ -26,7 +52,11 @@ color: #9ca3af; } - #search-results .hover\:bg-gray-50:hover { + #search-results .border-b { + border-color: #374151; + } + + #search-results a:hover { background-color: #374151; } } \ No newline at end of file diff --git a/parks/static/parks/js/search.js b/parks/static/parks/js/search.js deleted file mode 100644 index f022966e..00000000 --- a/parks/static/parks/js/search.js +++ /dev/null @@ -1,28 +0,0 @@ -document.addEventListener('DOMContentLoaded', function() { - const searchInput = document.getElementById('search'); - const searchResults = document.getElementById('search-results'); - - if (!searchInput || !searchResults) return; - - // Clear search results when clicking outside - document.addEventListener('click', function(e) { - if (!searchResults.contains(e.target) && e.target !== searchInput) { - searchResults.innerHTML = ''; - } - }); - - // Clear results on escape key - searchInput.addEventListener('keydown', function(e) { - if (e.key === 'Escape') { - searchResults.innerHTML = ''; - searchInput.value = ''; - searchInput.blur(); - } - }); - - // Handle back button - window.addEventListener('popstate', function() { - searchResults.innerHTML = ''; - searchInput.value = ''; - }); -}); \ No newline at end of file diff --git a/parks/templates/parks/park_list.html b/parks/templates/parks/park_list.html index 1606969a..05be74c4 100644 --- a/parks/templates/parks/park_list.html +++ b/parks/templates/parks/park_list.html @@ -38,19 +38,54 @@ Browse and filter amusement parks, theme parks, and water parks from around the
{# Quick Search #}
-
+
- + @keydown="onKeyDown($event)" + autocomplete="off" + role="combobox" + aria-expanded="false" + aria-controls="search-results" + aria-autocomplete="list">
@@ -60,7 +95,10 @@ Browse and filter amusement parks, theme parks, and water parks from around the
-
+
@@ -87,7 +125,7 @@ Browse and filter amusement parks, theme parks, and water parks from around the {% block results_section %}
{% for park in parks %} - {% include "search/partials/park_results.html" with park=park %} + {% include "parks/partials/park_list_item.html" with park=park %} {% endfor %}
{% endblock %} \ No newline at end of file diff --git a/parks/templates/parks/partials/park_list_item.html b/parks/templates/parks/partials/park_list_item.html new file mode 100644 index 00000000..5afe06ed --- /dev/null +++ b/parks/templates/parks/partials/park_list_item.html @@ -0,0 +1,78 @@ +{% if error %} +
+
+ + + + {{ error }} +
+
+{% else %} +
+{% for park in object_list|default:parks %} +
+ {% if park.photos.exists %} + {{ park.name }} + {% else %} +
+ {{ park.name|first|upper }} +
+ {% endif %} + +
+

+ + {{ park.name }} + +

+ +
+ {% with location=park.location.first %} + {% if location %} + {{ location.city }}{% if location.state %}, {{ location.state }}{% endif %}{% if location.country %}, {{ location.country }}{% endif %} + {% else %} + Location unknown + {% endif %} + {% endwith %} +
+ +
+ + {{ park.get_status_display }} + + + {% if park.opening_date %} + + Opened {{ park.opening_date|date:"Y" }} + + {% endif %} + + {% if park.ride_count %} + + {{ park.ride_count }} rides + + {% endif %} + + {% if park.coaster_count %} + + {{ park.coaster_count }} coasters + + {% endif %} +
+
+
+{% empty %} +
+ No parks found matching your search. +
+{% endfor %} +
+{% endif %} \ No newline at end of file diff --git a/parks/templates/parks/partials/park_search_results.html b/parks/templates/parks/partials/park_search_results.html deleted file mode 100644 index 735ec671..00000000 --- a/parks/templates/parks/partials/park_search_results.html +++ /dev/null @@ -1,58 +0,0 @@ -{% if error %} - -{% else %} - -{% endif %} \ No newline at end of file diff --git a/parks/views.py b/parks/views.py index a386173b..12f5a6ad 100644 --- a/parks/views.py +++ b/parks/views.py @@ -74,17 +74,20 @@ def search_parks(request: HttpRequest) -> HttpResponse: parks = park_filter.qs[:8] # Limit to 8 suggestions - response = render(request, "parks/partials/park_search_results.html", { - "parks": parks, - "is_quick_search": True + if not parks: + return HttpResponse( + '
No parks found matching your search.
' + ) + + response = render(request, "parks/partials/park_list_item.html", { + "object_list": parks # Use object_list to match template's for loop }) response['HX-Trigger'] = 'searchComplete' return response except Exception as e: - response = render(request, "parks/partials/park_search_results.html", { - "error": f"Error performing search: {str(e)}", - "is_quick_search": True + response = render(request, "parks/partials/park_list_item.html", { + "error": f"Error performing search: {str(e)}" }) response['HX-Trigger'] = 'searchError' return response diff --git a/search/templates/search/partials/park_results.html b/search/templates/search/partials/park_results.html deleted file mode 100644 index 0dc5f606..00000000 --- a/search/templates/search/partials/park_results.html +++ /dev/null @@ -1,72 +0,0 @@ -
- {% if error %} -
-
- - - - {{ error }} -
-
- {% else %} - {% for park in object_list %} -
- {% if park.photos.exists %} - {{ park.name }} - {% endif %} - -
-

- {{ park.name }} -

- -
- {% with location=park.location.first %} - {% if location %} - {{ location.city }}{% if location.state %}, {{ location.state }}{% endif %}{% if location.country %}, {{ location.country }}{% endif %} - {% else %} - Location unknown - {% endif %} - {% endwith %} -
- -
- - {{ park.get_status_display }} - - - {% if park.opening_date %} - - Opened {{ park.opening_date|date:"Y" }} - - {% endif %} - - {% if park.total_rides %} - - {{ park.total_rides }} rides - - {% endif %} - - {% if park.total_coasters %} - - {{ park.total_coasters }} coasters - - {% endif %} - - {% if park.average_rating %} - - {{ park.average_rating }} ★ - - {% endif %} -
-
-
- {% empty %} -
- No parks found matching your criteria -
- {% endfor %} - {% endif %} -
\ No newline at end of file