mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 09:51:09 -05:00
Configure PostgreSQL with PostGIS support
- Updated database settings to use dj_database_url for environment-based configuration - Added dj-database-url dependency - Configured PostGIS backend for spatial data support - Set default DATABASE_URL for production PostgreSQL connection
This commit is contained in:
313
parks_listing_comprehensive_documentation.md
Normal file
313
parks_listing_comprehensive_documentation.md
Normal file
@@ -0,0 +1,313 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user