diff --git a/parks/templates/parks/park_list.html b/parks/templates/parks/park_list.html index 7bb94828..b54e4e2e 100644 --- a/parks/templates/parks/park_list.html +++ b/parks/templates/parks/park_list.html @@ -52,7 +52,7 @@ id="search" class="block w-full rounded-md border-gray-300 bg-white py-3 pl-4 pr-10 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 sm:text-sm" placeholder="Search parks by name or location..." - hx-get="{% url 'parks:search_parks' %}" + hx-get="{% url 'parks:search_parks' %}?view_mode={{ view_mode|default:'grid' }}" hx-trigger="input delay:300ms, search" hx-target="#park-results" hx-push-url="true" diff --git a/parks/templates/parks/partials/park_list_item.html b/parks/templates/parks/partials/park_list_item.html index 3a483eed..23c204d2 100644 --- a/parks/templates/parks/partials/park_list_item.html +++ b/parks/templates/parks/partials/park_list_item.html @@ -11,80 +11,33 @@ {% else %} -
+
{% for park in object_list|default:parks %} -
- - - -
- {% if park.photos.exists %} - Photo of {{ park.name }} - {% else %} -
+
{% empty %} -
+
{% if search_query %} No parks found matching "{{ search_query }}". Try adjusting your search terms. {% else %} diff --git a/parks/views.py b/parks/views.py index 6048fad1..5786d0ae 100644 --- a/parks/views.py +++ b/parks/views.py @@ -1,6 +1,8 @@ +import requests from decimal import Decimal, ROUND_DOWN from typing import Any, Optional, cast, Literal from django.views.generic import DetailView, ListView, CreateView, UpdateView +from decimal import InvalidOperation from django.shortcuts import get_object_or_404, render from django.urls import reverse from django.db.models import Q, Count, QuerySet @@ -23,6 +25,70 @@ from search.mixins import HTMXFilterableMixin ViewMode = Literal["grid", "list"] +def normalize_osm_result(result: dict) -> dict: + """Normalize OpenStreetMap result to a consistent format with enhanced address details""" + from .location_utils import get_english_name, normalize_coordinate + + # Get address details + address = result.get('address', {}) + + # Normalize coordinates + lat = normalize_coordinate(float(result.get('lat')), 9, 6) + lon = normalize_coordinate(float(result.get('lon')), 10, 6) + + # Get English names where possible + name = '' + if 'namedetails' in result: + name = get_english_name(result['namedetails']) + + # Build street address from available components + street_parts = [] + if address.get('house_number'): + street_parts.append(address['house_number']) + if address.get('road') or address.get('street'): + street_parts.append(address.get('road') or address.get('street')) + elif address.get('pedestrian'): + street_parts.append(address['pedestrian']) + elif address.get('footway'): + street_parts.append(address['footway']) + + # Handle additional address components + suburb = address.get('suburb', '') + district = address.get('district', '') + neighborhood = address.get('neighbourhood', '') + + # Build city from available components + city = (address.get('city') or + address.get('town') or + address.get('village') or + address.get('municipality') or + '') + + # Get detailed state/region information + state = (address.get('state') or + address.get('province') or + address.get('region') or + '') + + # Get postal code with fallbacks + postal_code = (address.get('postcode') or + address.get('postal_code') or + '') + + return { + 'display_name': name or result.get('display_name', ''), + 'lat': lat, + 'lon': lon, + 'street': ' '.join(street_parts).strip(), + 'suburb': suburb, + 'district': district, + 'neighborhood': neighborhood, + 'city': city, + 'state': state, + 'country': address.get('country', ''), + 'postal_code': postal_code, + } + def get_view_mode(request: HttpRequest) -> ViewMode: """Get the current view mode from request, defaulting to grid""" view_mode = request.GET.get('view_mode', 'grid') @@ -202,6 +268,8 @@ def search_parks(request: HttpRequest) -> HttpResponse: if not search_query: return HttpResponse('') + # Get current view mode from request + current_view_mode = request.GET.get('view_mode', 'grid') park_filter = ParkFilter({ 'search': search_query }, queryset=get_base_park_queryset()) @@ -215,7 +283,7 @@ def search_parks(request: HttpRequest) -> HttpResponse: "parks/partials/park_list_item.html", { "parks": parks, - "view_mode": get_view_mode(request), + "view_mode": current_view_mode, "search_query": search_query, "is_search": True }