# Parks Listing Page - Comprehensive Documentation

## Overview

The parks listing page is the primary interface for browsing and discovering theme parks in ThrillWiki. It provides search, filtering, and listing capabilities with both grid and list view modes.

## Current Architecture

### Models

#### Park Model (`parks/models/parks.py`)
The core Park model contains these key fields:
- **Basic Info**: `name`, `slug`, `description`, `status`
- **Operations**: `opening_date`, `closing_date`, `operating_season`
- **Metadata**: `size_acres`, `website`, `average_rating`
- **Statistics**: `ride_count`, `coaster_count` (manual fields)
- **Relationships**: 
  - `operator` (ForeignKey to Company)
  - `property_owner` (ForeignKey to Company)
  - `photos` (GenericRelation)
  - `location` (OneToOneField via ParkLocation reverse relation)

#### Park Status System
The status system uses predefined choices with corresponding CSS classes:

**Status Options:**
- `OPERATING`: "Operating" - Green badge (`bg-green-100 text-green-800`)
- `CLOSED_TEMP`: "Temporarily Closed" - Yellow badge (`bg-yellow-100 text-yellow-800`)
- `CLOSED_PERM`: "Permanently Closed" - Red badge (`bg-red-100 text-red-800`)
- `UNDER_CONSTRUCTION`: "Under Construction" - Blue badge (`bg-blue-100 text-blue-800`)
- `DEMOLISHED`: "Demolished" - Gray badge (`bg-gray-100 text-gray-800`)
- `RELOCATED`: "Relocated" - Purple badge (`bg-purple-100 text-purple-800`)

**Status Badge Implementation:**
```html
<span class="status-badge status-{{ park.status|lower }}">
    {{ park.get_status_display }}
</span>
```

**CSS Classes:**
```css
.status-badge {
    @apply inline-flex items-center px-3 py-1 text-sm font-medium rounded-full;
}

.status-operating {
    @apply text-green-800 bg-green-100 dark:bg-green-700 dark:text-green-50;
}

.status-closed {
    @apply text-red-800 bg-red-100 dark:bg-red-700 dark:text-red-50;
}

.status-construction {
    @apply text-yellow-800 bg-yellow-100 dark:bg-yellow-600 dark:text-yellow-50;
}
```

#### ParkLocation Model (`parks/models/location.py`)
Handles geographic data with PostGIS support:
- **Coordinates**: `point` (PointField with SRID 4326)
- **Address**: `street_address`, `city`, `state`, `country`, `postal_code`
- **Trip Planning**: `highway_exit`, `parking_notes`, `best_arrival_time`, `seasonal_notes`
- **OSM Integration**: `osm_id`, `osm_type`

### Views

#### ParkListView (`parks/views.py:212-272`)
Inherits from `HTMXFilterableMixin` and `ListView`:
- **Template**: `parks/park_list.html` (full page) or `parks/partials/park_list_item.html` (HTMX)
- **Pagination**: 20 items per page
- **Filter Class**: `ParkFilter`
- **Context**: Includes `view_mode`, `is_search`, `search_query`
- **Error Handling**: Graceful degradation with error messages

**Key Methods:**
- `get_template_names()`: Returns different templates for HTMX requests
- `get_view_mode()`: Handles grid/list toggle
- `get_queryset()`: Uses `get_base_park_queryset()` with filters applied
- `get_context_data()`: Adds view mode and search context

#### Supporting View Functions
- `add_park_button()`: Returns add park button partial
- `park_actions()`: Returns park actions partial
- `get_park_areas()`: Dynamic area options for select elements
- `location_search()`: OpenStreetMap Nominatim API integration
- `reverse_geocode()`: Coordinate to address conversion
- `search_parks()`: HTMX search endpoint

### Templates

#### Main Template (`parks/templates/parks/park_list.html`)
Extends `search/layouts/filtered_list.html` with these sections:

**List Actions Block:**
- Page title ("Parks")
- View mode toggle (Grid/List) with HTMX
- Add Park button (authenticated users only)

**Filter Section Block:**
- Search autocomplete with Alpine.js
- Filter form with HTMX updates
- Loading indicators and accessibility features

**Results List Block:**
- Contains park results container
- Includes `park_list_item.html` partial

#### Park List Item Partial (`parks/templates/parks/partials/park_list_item.html`)
Displays individual park cards:
- **Grid Layout**: 3-column responsive grid (`md:grid-cols-2 lg:grid-cols-3`)
- **Card Design**: White background, shadow, hover transform
- **Content**: Park name (linked), status badge, operator link
- **Empty State**: Helpful message with option to add parks
- **Error Handling**: Error display with icon

### Filtering System

#### ParkFilter (`parks/filters.py`)
Comprehensive filter system with validation:

**Core Filters:**
- `search`: Multi-field search (name, description, location fields)
- `status`: Operating status dropdown
- `operator`: Operating company selector
- `has_operator`: Boolean filter for operator presence

**Numeric Filters:**
- `min_rides`: Minimum ride count with validation
- `min_coasters`: Minimum coaster count with validation
- `min_size`: Minimum size in acres with validation

**Date Filters:**
- `opening_date`: Date range filter

**Location Filters:**
- `location_search`: Search by city, state, country, address
- `near_location`: Proximity search with geocoding
- `radius_km`: Search radius (used with near_location)
- `country_filter`: Country-specific filtering
- `state_filter`: State/region filtering

**Advanced Features:**
- Custom `qs` property ensures base queryset with annotations
- Geocoding integration with OpenStreetMap Nominatim
- Distance calculations with PostGIS
- Input validation with custom validators

#### Base Queryset (`parks/querysets.py`)
Optimized query with:
- **Relationships**: `select_related('operator', 'property_owner', 'location')`
- **Prefetches**: `photos`, `rides`
- **Annotations**: 
  - `current_ride_count`: Live count from related rides
  - `current_coaster_count`: Live count of roller coasters
- **Ordering**: Alphabetical by name

### Forms

#### ParkForm (`parks/forms.py:54-312`)
Comprehensive form for park creation/editing:
- **Model Fields**: All Park model fields
- **Location Fields**: Separate fields for coordinates and address
- **Widgets**: Tailwind CSS styled with dark mode support
- **Validation**: Coordinate range validation and precision handling
- **Location Integration**: Automatic ParkLocation creation/update

#### ParkAutocomplete (`parks/forms.py:11-38`)
Search autocomplete functionality:
- **Search Attributes**: Park name matching
- **Related Data**: Includes operator and owner information
- **Formatting**: Status and location display in results

### Styling & Design

#### Theme System
Based on Tailwind CSS v4 with custom design tokens:
- **Primary Color**: `#4f46e5` (Vibrant indigo)
- **Secondary Color**: `#e11d48` (Vibrant rose)  
- **Accent Color**: `#8b5cf6`
- **Font**: Poppins sans-serif
- **Dark Mode**: Class-based toggle support

#### Card Design Pattern
Consistent across the application:
```css
.card {
    @apply p-6 bg-white border rounded-lg shadow-lg dark:bg-gray-800 border-gray-200/50 dark:border-gray-700/50;
}

.card-hover {
    @apply transition-transform transform hover:-translate-y-1;
}
```

#### Grid System
Adaptive grid with responsive breakpoints:
```css
.grid-cards {
    @apply grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3;
}

.grid-adaptive {
    @apply grid gap-6;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
```

#### Status Badges
Semantic color coding with dark mode support:
- Consistent padding: `px-3 py-1`
- Typography: `text-sm font-medium`
- Shape: `rounded-full`
- Colors: Contextual based on status type

### JavaScript Integration

#### HTMX Features
- **Dynamic Loading**: Park list updates without page refresh
- **Search**: Real-time search with debouncing (300ms delay)
- **Filters**: Form submission with URL state management
- **View Modes**: Toggle between grid/list with state preservation
- **Pagination**: Seamless page navigation
- **Error Handling**: Custom error displays with HX-Trigger events

#### Alpine.js Components
- **Search Interface**: Query state management and escape key handling
- **Filter Integration**: Form state synchronization
- **Accessibility**: ARIA attributes for screen readers

### API Integration

#### OpenStreetMap Nominatim
- **Search Endpoint**: Location autocomplete with 10 result limit
- **Geocoding**: Address to coordinate conversion
- **Reverse Geocoding**: Coordinate to address lookup
- **Error Handling**: Graceful fallbacks for API failures
- **Rate Limiting**: 5-second timeout for requests

#### Location Utilities
- **Coordinate Normalization**: Precision handling for lat/lng
- **English Name Extraction**: Multi-language support
- **Address Parsing**: Comprehensive address component handling

### Performance Optimizations

#### Database Queries
- **Select Related**: Minimize N+1 queries for relationships
- **Prefetch Related**: Efficient loading of many-to-many relations
- **Annotations**: Database-level calculations for counts
- **Distinct**: Prevent duplicate results from joins

#### Frontend Performance
- **HTMX**: Partial page updates reduce bandwidth
- **Debouncing**: Search input optimization
- **Lazy Loading**: Progressive content loading
- **Caching**: Template fragment caching where appropriate

### Accessibility Features

#### Screen Reader Support
- **Semantic HTML**: Proper heading hierarchy and landmarks
- **ARIA Labels**: Descriptive labels for interactive elements
- **Focus Management**: Keyboard navigation support
- **Loading States**: Screen reader announcements for dynamic content

#### Keyboard Navigation
- **Escape Key**: Closes search suggestions
- **Tab Order**: Logical focus sequence
- **Enter/Space**: Activates buttons and links

### Error Handling

#### Graceful Degradation
- **Query Failures**: Empty queryset with error message
- **Filter Errors**: Form validation with user feedback
- **API Timeouts**: Fallback to basic functionality
- **JavaScript Disabled**: Basic form submission still works

#### User Feedback
- **Loading Indicators**: Spinner animations during requests
- **Error Messages**: Clear, actionable error descriptions
- **Empty States**: Helpful guidance when no results found
- **Success States**: Confirmation of actions taken

## Current Strengths

1. **Comprehensive Filtering**: Rich set of filter options for various use cases
2. **Performance**: Optimized queries with proper relationships and annotations
3. **User Experience**: Smooth HTMX interactions with instant feedback
4. **Responsive Design**: Works well on all device sizes
5. **Accessibility**: Good screen reader and keyboard support
6. **Status System**: Clear, well-designed status indicators
7. **Location Integration**: PostGIS-powered geographic capabilities
8. **Search Experience**: Real-time search with autocomplete
9. **Error Handling**: Graceful degradation and user feedback
10. **Dark Mode**: Consistent theming across light/dark modes

## Areas for Enhancement

1. **Location Filtering**: Hierarchical location filtering (Country → State → City)
2. **Advanced Search**: More sophisticated search capabilities
3. **Map Integration**: Geographic visualization of results
4. **Bulk Operations**: Multi-select actions for parks
5. **Export Functionality**: CSV/JSON export of filtered results
6. **Bookmarking**: Save filter combinations
7. **Recent Searches**: Search history functionality
8. **Advanced Sorting**: Multiple sort criteria
9. **Preview Mode**: Quick preview without navigation
10. **Comparison Tools**: Side-by-side park comparisons

This documentation provides a comprehensive foundation for understanding the current parks listing implementation and serves as a baseline for planning improvements while preserving the existing strengths and design patterns.
