Add park and ride card components with advanced search functionality

- Implemented park card component with image, status badge, favorite button, and quick stats overlay.
- Developed ride card component featuring thrill level badge, status badge, favorite button, and detailed stats.
- Created advanced search page with filters for parks and rides, including location, type, status, and thrill level.
- Added dynamic quick search functionality with results display.
- Enhanced user experience with JavaScript for filter toggling, range slider updates, and view switching.
- Included custom CSS for improved styling of checkboxes and search results layout.
This commit is contained in:
pacnpal
2025-09-24 23:10:48 -04:00
parent 4373d18176
commit b1c369c1bb
39 changed files with 5202 additions and 824 deletions

View File

@@ -0,0 +1,525 @@
# ThrillWiki Django + Vue.js Monorepo Architecture Plan
## Executive Summary
This document outlines the optimal monorepo directory structure for migrating the ThrillWiki Django project to a Django + Vue.js architecture. The design separates backend and frontend concerns while maintaining existing Django app organization and supporting modern development workflows.
## Current Project Analysis
### Django Apps Structure
- **accounts**: User management and authentication
- **parks**: Theme park data and operations
- **rides**: Ride information and management
- **moderation**: Content moderation system
- **location**: Geographic data handling
- **media**: File and image management
- **email_service**: Email functionality
- **core**: Core utilities and services
### Key Infrastructure
- **Package Management**: UV-based Python setup
- **Configuration**: `config/django/` for settings, `config/settings/` for modular settings
- **Development**: `scripts/dev_server.sh` with comprehensive setup
- **Static Assets**: Tailwind CSS integration, `static/` and `staticfiles/`
- **Media Handling**: Organized `media/` directory with park/ride subdirectories
## Proposed Monorepo Structure
```
thrillwiki-monorepo/
├── README.md
├── pyproject.toml # Python dependencies (backend only)
├── package.json # Node.js dependencies (monorepo coordination)
├── pnpm-workspace.yaml # pnpm workspace configuration
├── .env.example
├── .gitignore
├──
├── backend/ # Django Backend
│ ├── manage.py
│ ├── pyproject.toml # Backend-specific dependencies
│ ├── config/
│ │ ├── django/
│ │ │ ├── base.py
│ │ │ ├── local.py
│ │ │ ├── production.py
│ │ │ └── test.py
│ │ └── settings/
│ │ ├── database.py
│ │ ├── email.py
│ │ └── security.py
│ ├── thrillwiki/
│ │ ├── __init__.py
│ │ ├── urls.py
│ │ ├── wsgi.py
│ │ ├── asgi.py
│ │ └── views.py
│ ├── apps/ # Django apps
│ │ ├── accounts/
│ │ ├── parks/
│ │ ├── rides/
│ │ ├── moderation/
│ │ ├── location/
│ │ ├── media/
│ │ ├── email_service/
│ │ └── core/
│ ├── templates/ # Django templates (API responses, admin)
│ ├── static/ # Backend static files
│ │ └── admin/ # Django admin assets
│ ├── media/ # User uploads
│ │ ├── avatars/
│ │ ├── park/
│ │ └── submissions/
│ └── tests/ # Backend tests
├── frontend/ # Vue.js Frontend
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── vite.config.js
│ ├── tailwind.config.js
│ ├── index.html
│ ├── src/
│ │ ├── main.js
│ │ ├── App.vue
│ │ ├── router/
│ │ │ └── index.js
│ │ ├── stores/ # Pinia/Vuex stores
│ │ │ ├── auth.js
│ │ │ ├── parks.js
│ │ │ └── rides.js
│ │ ├── components/
│ │ │ ├── common/ # Shared components
│ │ │ ├── parks/ # Park-specific components
│ │ │ ├── rides/ # Ride-specific components
│ │ │ └── moderation/ # Moderation components
│ │ ├── views/ # Page components
│ │ │ ├── Home.vue
│ │ │ ├── parks/
│ │ │ ├── rides/
│ │ │ └── auth/
│ │ ├── composables/ # Vue 3 composables
│ │ │ ├── useAuth.js
│ │ │ ├── useApi.js
│ │ │ └── useTheme.js
│ │ ├── services/ # API service layer
│ │ │ ├── api.js
│ │ │ ├── auth.js
│ │ │ ├── parks.js
│ │ │ └── rides.js
│ │ ├── assets/
│ │ │ ├── images/
│ │ │ └── styles/
│ │ │ ├── globals.css
│ │ │ └── components/
│ │ └── utils/
│ ├── public/
│ │ ├── favicon.ico
│ │ └── images/
│ ├── dist/ # Build output
│ └── tests/ # Frontend tests
│ ├── unit/
│ └── e2e/
├── shared/ # Shared Resources
│ ├── docs/ # Documentation
│ │ ├── api/ # API documentation
│ │ ├── deployment/ # Deployment guides
│ │ └── development/ # Development setup
│ ├── scripts/ # Build and deployment scripts
│ │ ├── dev/
│ │ │ ├── start-backend.sh
│ │ │ ├── start-frontend.sh
│ │ │ └── start-full-stack.sh
│ │ ├── build/
│ │ │ ├── build-frontend.sh
│ │ │ └── build-production.sh
│ │ ├── deploy/
│ │ └── utils/
│ ├── config/ # Shared configuration
│ │ ├── docker/
│ │ │ ├── Dockerfile.backend
│ │ │ ├── Dockerfile.frontend
│ │ │ └── docker-compose.yml
│ │ ├── nginx/
│ │ └── ci/ # CI/CD configuration
│ │ └── github-actions/
│ └── types/ # Shared TypeScript types
│ ├── api.ts
│ ├── parks.ts
│ └── rides.ts
├── logs/ # Application logs
├── backups/ # Database backups
├── uploads/ # Temporary upload directory
└── dist/ # Production build output
├── backend/ # Django static files
└── frontend/ # Vue.js build
```
## Directory Organization Rationale
### 1. Clear Separation of Concerns
- **backend/**: Contains all Django-related code, maintaining existing app structure
- **frontend/**: Vue.js application with modern structure (Vite + Vue 3)
- **shared/**: Common resources, documentation, and configuration
### 2. Backend Structure (`backend/`)
- Preserves existing Django app organization under `apps/`
- Maintains UV-based Python dependency management
- Keeps configuration structure with `config/django/` and `config/settings/`
- Separates templates for API responses vs. frontend UI
### 3. Frontend Structure (`frontend/`)
- Modern Vue 3 + Vite setup with TypeScript support
- Organized by feature areas (parks, rides, auth)
- Composables for Vue 3 Composition API patterns
- Service layer for API communication with Django backend
- Tailwind CSS integration with shared design system
### 4. Shared Resources (`shared/`)
- Centralized documentation and deployment scripts
- Docker configuration for containerized deployment
- TypeScript type definitions shared between frontend and API
- CI/CD pipeline configuration
## Static File Strategy
### Development
```mermaid
graph LR
A[Vue Dev Server :3000] --> B[Vite HMR]
C[Django Dev Server :8000] --> D[Django Static Files]
E[Tailwind CSS] --> F[Both Frontend & Backend]
```
### Production
```mermaid
graph LR
A[Vue Build] --> B[dist/frontend/]
C[Django Collectstatic] --> D[dist/backend/]
E[Nginx] --> F[Serves Both]
F --> G[Frontend Assets]
F --> H[API Endpoints]
F --> I[Media Files]
```
### Implementation Details
1. **Development Mode**:
- Frontend: Vite dev server on port 3000 with HMR
- Backend: Django dev server on port 8000
- Proxy API calls from frontend to backend
2. **Production Mode**:
- Frontend built to `dist/frontend/`
- Django static files collected to `dist/backend/`
- Nginx serves static files and proxies API calls
## Media File Management
### Current Structure Preservation
```
media/
├── avatars/ # User profile images
├── park/ # Park-specific media
│ ├── {park-slug}/
│ │ └── {ride-slug}/
└── submissions/ # User-submitted content
└── photos/
```
### Strategy
- **Development**: Django serves media files directly
- **Production**: CDN or object storage (S3/CloudFlare) integration
- **Frontend Access**: Media URLs provided via API responses
- **Upload Handling**: Django handles all file uploads, Vue.js provides UI
## Development Workflow Integration
### Package Management
- **Root**: Node.js dependencies for frontend and tooling (using pnpm)
- **Backend**: UV for Python dependencies (existing approach)
- **Frontend**: pnpm for Vue.js dependencies
### Development Scripts
```bash
# Root level scripts
pnpm run dev # Start both backend and frontend
pnpm run dev:backend # Start only Django
pnpm run dev:frontend # Start only Vue.js
pnpm run build # Build for production
pnpm run test # Run all tests
# Backend specific (using UV)
cd backend && uv run manage.py runserver
cd backend && uv run manage.py test
# Frontend specific
cd frontend && pnpm run dev
cd frontend && pnpm run build
cd frontend && pnpm run test
```
### Environment Configuration
```bash
# Root .env (shared settings)
DATABASE_URL=
REDIS_URL=
SECRET_KEY=
# Backend .env (Django specific)
DJANGO_SETTINGS_MODULE=config.django.local
DEBUG=True
# Frontend .env (Vue specific)
VITE_API_BASE_URL=http://localhost:8000/api
VITE_APP_TITLE=ThrillWiki
```
### Package Manager Configuration
#### Root pnpm-workspace.yaml
```yaml
packages:
- 'frontend'
# Backend is managed separately with uv
```
#### Root package.json
```json
{
"name": "thrillwiki-monorepo",
"private": true,
"packageManager": "pnpm@9.0.0",
"scripts": {
"dev": "concurrently \"pnpm run dev:backend\" \"pnpm run dev:frontend\"",
"dev:backend": "cd backend && uv run manage.py runserver",
"dev:frontend": "cd frontend && pnpm run dev",
"build": "pnpm run build:frontend && cd backend && uv run manage.py collectstatic --noinput",
"build:frontend": "cd frontend && pnpm run build",
"test": "pnpm run test:backend && pnpm run test:frontend",
"test:backend": "cd backend && uv run manage.py test",
"test:frontend": "cd frontend && pnpm run test",
"lint": "cd frontend && pnpm run lint && cd ../backend && uv run flake8 .",
"format": "cd frontend && pnpm run format && cd ../backend && uv run black ."
},
"devDependencies": {
"concurrently": "^8.2.0"
}
}
```
#### Frontend package.json
```json
{
"name": "thrillwiki-frontend",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest",
"test:e2e": "playwright test",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
"format": "prettier --write src/",
"type-check": "vue-tsc --noEmit"
},
"dependencies": {
"vue": "^3.4.0",
"vue-router": "^4.3.0",
"pinia": "^2.1.0",
"axios": "^1.6.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.0",
"vite": "^5.0.0",
"vue-tsc": "^2.0.0",
"typescript": "^5.3.0",
"tailwindcss": "^3.4.0",
"autoprefixer": "^10.4.0",
"postcss": "^8.4.0",
"eslint": "^8.57.0",
"prettier": "^3.2.0",
"vitest": "^1.3.0",
"@playwright/test": "^1.42.0"
}
}
```
## File Migration Mapping
### High-Level Moves
```
Current → New Location
├── manage.py → backend/manage.py
├── pyproject.toml → backend/pyproject.toml (+ root package.json)
├── config/ → backend/config/
├── thrillwiki/ → backend/thrillwiki/
├── accounts/ → backend/apps/accounts/
├── parks/ → backend/apps/parks/
├── rides/ → backend/apps/rides/
├── moderation/ → backend/apps/moderation/
├── location/ → backend/apps/location/
├── media/ → backend/apps/media/
├── email_service/ → backend/apps/email_service/
├── core/ → backend/apps/core/
├── templates/ → backend/templates/ (API) + frontend/src/views/ (UI)
├── static/ → backend/static/ (admin) + frontend/src/assets/
├── media/ → media/ (shared, accessible to both)
├── scripts/ → shared/scripts/
├── docs/ → shared/docs/
├── tests/ → backend/tests/ + frontend/tests/
└── staticfiles/ → dist/backend/ (generated)
```
### Detailed Backend App Moves
Each Django app moves to `backend/apps/{app_name}/` with structure preserved:
- Models, views, serializers stay the same
- Templates for API responses remain in app directories
- Static files move to frontend if UI-related
- Tests remain with respective apps
## Build and Deployment Strategy
### Development Build Process
1. **Backend**: No build step, runs directly with Django dev server
2. **Frontend**: Vite development server with HMR
3. **Shared**: Scripts orchestrate starting both services
### Production Build Process
```mermaid
graph TD
A[CI/CD Trigger] --> B[Install Dependencies]
B --> C[Build Frontend]
B --> D[Collect Django Static]
C --> E[Generate Frontend Bundle]
D --> F[Collect Backend Assets]
E --> G[Create Docker Images]
F --> G
G --> H[Deploy to Production]
```
### Container Strategy
- **Multi-stage Docker builds**: Separate backend and frontend images
- **Nginx**: Reverse proxy and static file serving
- **Volume mounts**: For media files and logs
- **Environment-based configuration**: Development vs. production
## API Integration Strategy
### Backend API Structure
```python
# Enhanced DRF setup for SPA
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
}
# CORS for development
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000", # Vue dev server
]
```
### Frontend API Service
```javascript
// API service with auth integration
class ApiService {
constructor() {
this.client = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
withCredentials: true,
});
}
// Park operations
getParks(params = {}) {
return this.client.get('/parks/', { params });
}
// Ride operations
getRides(parkId, params = {}) {
return this.client.get(`/parks/${parkId}/rides/`, { params });
}
}
```
## Configuration Management
### Shared Environment Variables
- Database connections
- Redis/Cache settings
- Secret keys and API keys
- Feature flags
### Application-Specific Settings
- **Django**: `backend/config/django/`
- **Vue.js**: `frontend/.env` files
- **Docker**: `shared/config/docker/`
### Development vs. Production
- Development: Multiple local servers, hot reloading
- Production: Containerized deployment, CDN integration
## Benefits of This Structure
1. **Clear Separation**: Backend and frontend concerns are clearly separated
2. **Scalability**: Each part can be developed, tested, and deployed independently
3. **Modern Workflow**: Supports latest Vue 3, Vite, and Django patterns
4. **Backward Compatibility**: Preserves existing Django app structure
5. **Developer Experience**: Hot reloading, TypeScript support, modern tooling
6. **Deployment Flexibility**: Can deploy as SPA + API or traditional Django
## Implementation Phases
### Phase 1: Structure Setup
1. Create new directory structure
2. Move Django code to `backend/`
3. Initialize Vue.js frontend
4. Set up basic API integration
### Phase 2: Frontend Development
1. Create Vue.js components for existing Django templates
2. Implement routing and state management
3. Integrate with Django API endpoints
4. Add authentication flow
### Phase 3: Build & Deploy
1. Set up build processes
2. Configure CI/CD pipelines
3. Implement production deployment
4. Performance optimization
## Considerations and Trade-offs
### Advantages
- Modern development experience
- Better code organization
- Independent scaling
- Rich frontend interactions
- API-first architecture
### Challenges
- Increased complexity
- Build process coordination
- Authentication across services
- SEO considerations (if needed)
- Development environment setup
## Next Steps
1. **Validate Architecture**: Review with development team
2. **Prototype Setup**: Create basic structure with sample components
3. **Migration Planning**: Detailed plan for moving existing code
4. **Tool Selection**: Finalize Vue.js ecosystem choices (Pinia vs. Vuex, etc.)
5. **Implementation**: Begin phase-by-phase migration
---
This architecture provides a solid foundation for migrating ThrillWiki to a modern Django + Vue.js monorepo while preserving existing functionality and enabling future growth.