# ThrillWiki Admin Interface Guide

## Overview

The ThrillWiki admin interface uses **Django Unfold**, a modern, Tailwind CSS-based admin theme that provides a beautiful and intuitive user experience. This guide covers all features of the enhanced admin interface implemented in Phase 2C.

## Table of Contents

1. [Features](#features)
2. [Accessing the Admin](#accessing-the-admin)
3. [Dashboard](#dashboard)
4. [Entity Management](#entity-management)
5. [Import/Export](#importexport)
6. [Advanced Filtering](#advanced-filtering)
7. [Bulk Actions](#bulk-actions)
8. [Geographic Features](#geographic-features)
9. [Customization](#customization)

---

## Features

### ✨ Modern UI/UX
- **Tailwind CSS-based design** - Clean, modern interface
- **Dark mode support** - Automatic theme switching
- **Responsive layout** - Works on desktop, tablet, and mobile
- **Material Design icons** - Intuitive visual elements
- **Custom green color scheme** - Branded appearance

### 🎯 Enhanced Entity Management
- **Inline editing** - Edit related objects without leaving the page
- **Visual indicators** - Color-coded status badges and icons
- **Smart search** - Search across multiple fields
- **Advanced filters** - Dropdown filters for easy data navigation
- **Autocomplete fields** - Fast foreign key selection

### 📊 Dashboard Statistics
- Total entity counts (Parks, Rides, Companies, Models)
- Operating vs. total counts
- Recent additions (last 30 days)
- Top manufacturers by ride count
- Parks by type distribution

### 📥 Import/Export
- **Multiple formats** - CSV, Excel (XLS/XLSX), JSON, YAML
- **Bulk operations** - Import hundreds of records at once
- **Data validation** - Error checking during import
- **Export filtered data** - Export search results

### 🗺️ Geographic Features
- **Dual-mode support** - Works with both SQLite (lat/lng) and PostGIS
- **Coordinate display** - Visual representation of park locations
- **Map widgets** - Interactive maps for location editing (PostGIS mode)

---

## Accessing the Admin

### URL
```
http://localhost:8000/admin/
```

### Creating a Superuser

If you don't have an admin account yet:

```bash
cd django
python manage.py createsuperuser
```

Follow the prompts to create your admin account.

### Login

Navigate to `/admin/` and log in with your superuser credentials.

---

## Dashboard

The admin dashboard provides an at-a-glance view of your ThrillWiki data:

### Statistics Displayed

1. **Entity Counts**
   - Total Parks
   - Total Rides
   - Total Companies
   - Total Ride Models

2. **Operational Status**
   - Operating Parks
   - Operating Rides
   - Total Roller Coasters

3. **Recent Activity**
   - Parks added in last 30 days
   - Rides added in last 30 days

4. **Top Manufacturers**
   - List of manufacturers by ride count

5. **Parks by Type**
   - Distribution chart of park types

### Navigating from Dashboard

Use the sidebar navigation to access different sections:
- **Dashboard** - Overview and statistics
- **Entities** - Parks, Rides, Companies, Ride Models
- **User Management** - Users and Groups
- **Content** - Media and Moderation

---

## Entity Management

### Parks Admin

#### List View Features
- **Visual indicators**: Icon and emoji for park type
- **Location display**: City/Country with coordinates
- **Status badges**: Color-coded operational status
- **Ride counts**: Total rides and coaster count
- **Operator links**: Quick access to operating company

#### Detail View
- **Geographic Location section**: Latitude/longitude input with coordinate display
- **Operator selection**: Autocomplete field for company selection
- **Inline rides**: View and manage all rides in the park
- **Date precision**: Separate fields for dates and their precision levels
- **Custom data**: JSON field for additional attributes

#### Bulk Actions
- `export_admin_action` - Export selected parks
- `activate_parks` - Mark parks as operating
- `close_parks` - Mark parks as temporarily closed

#### Filters
- Park Type (dropdown)
- Status (dropdown)
- Operator (dropdown with search)
- Opening Date (range filter)
- Closing Date (range filter)

---

### Rides Admin

#### List View Features
- **Category icons**: Visual ride category identification
- **Status badges**: Color-coded operational status
- **Stats display**: Height, Speed, Inversions at a glance
- **Coaster badge**: Special indicator for roller coasters
- **Park link**: Quick navigation to parent park

#### Detail View
- **Classification section**: Category, Type, Status
- **Manufacturer & Model**: Autocomplete fields with search
- **Ride Statistics**: Height, Speed, Length, Duration, Inversions, Capacity
- **Auto-coaster detection**: Automatically marks roller coasters
- **Custom data**: JSON field for additional attributes

#### Bulk Actions
- `export_admin_action` - Export selected rides
- `activate_rides` - Mark rides as operating
- `close_rides` - Mark rides as temporarily closed

#### Filters
- Ride Category (dropdown)
- Status (dropdown)
- Is Coaster (boolean)
- Park (dropdown with search)
- Manufacturer (dropdown with search)
- Opening Date (range)
- Height (numeric range)
- Speed (numeric range)

---

### Companies Admin

#### List View Features
- **Type icons**: Manufacturer 🏭, Operator 🎡, Designer ✏️
- **Type badges**: Color-coded company type indicators
- **Entity counts**: Parks and rides associated
- **Status indicator**: Active (green) or Closed (red)
- **Location display**: Primary location

#### Detail View
- **Company types**: Multi-select for manufacturer, operator, designer
- **History section**: Founded/Closed dates with precision
- **Inline parks**: View all operated parks
- **Statistics**: Cached counts for performance

#### Bulk Actions
- `export_admin_action` - Export selected companies

#### Filters
- Company Types (dropdown)
- Founded Date (range)
- Closed Date (range)

---

### Ride Models Admin

#### List View Features
- **Model type icons**: Visual identification (🎢, 🌊, 🎡, etc.)
- **Manufacturer link**: Quick access to manufacturer
- **Typical specs**: Height, Speed, Capacity summary
- **Installation count**: Number of installations worldwide

#### Detail View
- **Manufacturer**: Autocomplete field
- **Typical Specifications**: Standard specifications for the model
- **Inline installations**: List of all rides using this model

#### Bulk Actions
- `export_admin_action` - Export selected ride models

#### Filters
- Model Type (dropdown)
- Manufacturer (dropdown with search)
- Typical Height (numeric range)
- Typical Speed (numeric range)

---

## Import/Export

### Exporting Data

1. Navigate to the entity list view (e.g., Parks)
2. Optionally apply filters to narrow down data
3. Select records to export (or none for all)
4. Choose action: "Export"
5. Select format: CSV, Excel (XLS/XLSX), JSON, YAML, HTML
6. Click "Go"
7. Download the file

### Importing Data

1. Navigate to the entity list view
2. Click "Import" button in the top right
3. Choose file format
4. Select your import file
5. Click "Submit"
6. Review import preview
7. Confirm import

### Import File Format

#### CSV/Excel Requirements
- First row must be column headers
- Use field names from the model
- For foreign keys, use the related object's name
- Dates in ISO format (YYYY-MM-DD)

#### Example Company CSV
```csv
name,slug,location,company_types,founded_date,website
Intamin,intamin,"Schaan, Liechtenstein","[""manufacturer""]",1967-01-01,https://intamin.com
Cedar Fair,cedar-fair,"Sandusky, Ohio, USA","[""operator""]",1983-03-01,https://cedarfair.com
```

#### Example Park CSV
```csv
name,slug,park_type,status,latitude,longitude,operator,opening_date
Cedar Point,cedar-point,amusement_park,operating,41.4779,-82.6838,Cedar Fair,1870-01-01
```

### Import Error Handling

If import fails:
1. Review error messages carefully
2. Check data formatting
3. Verify foreign key references exist
4. Ensure required fields are present
5. Fix issues and try again

---

## Advanced Filtering

### Filter Types

#### 1. **Dropdown Filters**
- Single selection from predefined choices
- Examples: Park Type, Status, Ride Category

#### 2. **Related Dropdown Filters**
- Dropdown with search for foreign keys
- Examples: Operator, Manufacturer, Park
- Supports autocomplete

#### 3. **Range Date Filters**
- Filter by date range
- Includes "From" and "To" fields
- Examples: Opening Date, Closing Date

#### 4. **Range Numeric Filters**
- Filter by numeric range
- Includes "Min" and "Max" fields
- Examples: Height, Speed, Capacity

#### 5. **Boolean Filters**
- Yes/No/All options
- Example: Is Coaster

### Combining Filters

Filters can be combined for precise queries:

**Example: Find all operating roller coasters at Cedar Fair parks over 50m tall**
1. Go to Rides admin
2. Set "Ride Category" = Roller Coaster
3. Set "Status" = Operating
4. Set "Park" = (search for Cedar Fair parks)
5. Set "Height Min" = 50

### Search vs. Filters

- **Search**: Text-based search across multiple fields (name, description, etc.)
- **Filters**: Structured filtering by specific attributes
- **Best Practice**: Use filters to narrow down, then search within results

---

## Bulk Actions

### Available Actions

#### All Entities
- **Export** - Export selected records to file

#### Parks
- **Activate Parks** - Set status to "operating"
- **Close Parks** - Set status to "closed_temporarily"

#### Rides  
- **Activate Rides** - Set status to "operating"
- **Close Rides** - Set status to "closed_temporarily"

### How to Use Bulk Actions

1. Select records using checkboxes
2. Choose action from dropdown at bottom of list
3. Click "Go"
4. Confirm action if prompted
5. View success message

### Tips
- Select all on page: Use checkbox in header row
- Select all in query: Click "Select all X items" link
- Bulk actions respect permissions
- Some actions cannot be undone

---

## Geographic Features

### SQLite Mode (Default for Local Development)

**Fields Available:**
- `latitude` - Decimal field for latitude (-90 to 90)
- `longitude` - Decimal field for longitude (-180 to 180)
- `location` - Text field for location name

**Coordinate Display:**
- Read-only field showing current coordinates
- Format: "Longitude: X.XXXXXX, Latitude: Y.YYYYYY"

**Search:**
- `/api/v1/parks/nearby/` uses bounding box approximation

### PostGIS Mode (Production)

**Additional Features:**
- `location_point` - PointField for geographic data
- Interactive map widget in admin
- Accurate distance calculations
- Optimized geographic queries

**Setting Up PostGIS:**
See `POSTGIS_SETUP.md` for detailed instructions.

### Entering Coordinates

1. Find coordinates using Google Maps or similar
2. Enter latitude in "Latitude" field
3. Enter longitude in "Longitude" field
4. Enter location name in "Location" field
5. Coordinates are automatically synced to `location_point` (PostGIS mode)

**Coordinate Format:**
- Latitude: -90.000000 to 90.000000
- Longitude: -180.000000 to 180.000000
- Use negative for South/West

---

## Customization

### Settings Configuration

The Unfold configuration is in `config/settings/base.py`:

```python
UNFOLD = {
    "SITE_TITLE": "ThrillWiki Admin",
    "SITE_HEADER": "ThrillWiki Administration",
    "SITE_SYMBOL": "🎢",
    "SHOW_HISTORY": True,
    "SHOW_VIEW_ON_SITE": True,
    # ... more settings
}
```

### Customizable Options

#### Branding
- `SITE_TITLE` - Browser title
- `SITE_HEADER` - Header text
- `SITE_SYMBOL` - Emoji or icon in header
- `SITE_ICON` - Logo image paths

#### Colors
- `COLORS["primary"]` - Primary color palette (currently green)
- Supports full Tailwind CSS color specification

#### Navigation
- `SIDEBAR["navigation"]` - Custom sidebar menu structure
- Can add custom links and sections

### Adding Custom Dashboard Widgets

The dashboard callback is in `apps/entities/admin.py`:

```python
def dashboard_callback(request, context):
    """Customize dashboard statistics."""
    # Add your custom statistics here
    context.update({
        'custom_stat': calculate_custom_stat(),
    })
    return context
```

### Custom Admin Actions

Add custom actions to admin classes:

```python
@admin.register(Park)
class ParkAdmin(ModelAdmin):
    actions = ['export_admin_action', 'custom_action']
    
    def custom_action(self, request, queryset):
        # Your custom logic here
        updated = queryset.update(some_field='value')
        self.message_user(request, f'{updated} records updated.')
    custom_action.short_description = 'Perform custom action'
```

---

## Tips & Best Practices

### Performance
1. **Use filters before searching** - Narrow down data set first
2. **Use autocomplete fields** - Faster than raw ID fields
3. **Limit inline records** - Use `show_change_link` for large datasets
4. **Export in batches** - For very large datasets

### Data Quality
1. **Use import validation** - Preview before confirming
2. **Verify foreign keys** - Ensure related objects exist
3. **Check date precision** - Use appropriate precision levels
4. **Review before bulk actions** - Double-check selections

### Navigation
1. **Use breadcrumbs** - Navigate back through hierarchy
2. **Bookmark frequently used filters** - Save time
3. **Use keyboard shortcuts** - Unfold supports many shortcuts
4. **Search then filter** - Or filter then search, depending on need

### Security
1. **Use strong passwords** - For admin accounts
2. **Enable 2FA** - If available (django-otp configured)
3. **Regular backups** - Before major bulk operations
4. **Audit changes** - Review history in change log

---

## Troubleshooting

### Issue: Can't see Unfold theme

**Solution:**
```bash
cd django
python manage.py collectstatic --noinput
```

### Issue: Import fails with validation errors

**Solution:**
- Check CSV formatting
- Verify column headers match field names
- Ensure required fields are present
- Check foreign key references exist

### Issue: Geographic features not working

**Solution:**
- Verify latitude/longitude are valid decimals
- Check coordinate ranges (-90 to 90, -180 to 180)
- For PostGIS: Verify PostGIS is installed and configured

### Issue: Filters not appearing

**Solution:**
- Clear browser cache
- Check admin class has list_filter defined
- Verify filter classes are imported
- Restart development server

### Issue: Inline records not saving

**Solution:**
- Check form validation errors
- Verify required fields in inline
- Check permissions for related model
- Review browser console for JavaScript errors

---

## Additional Resources

### Documentation
- **Django Unfold**: https://unfoldadmin.com/
- **django-import-export**: https://django-import-export.readthedocs.io/
- **Django Admin**: https://docs.djangoproject.com/en/4.2/ref/contrib/admin/

### ThrillWiki Docs
- `API_GUIDE.md` - REST API documentation
- `POSTGIS_SETUP.md` - Geographic features setup
- `MIGRATION_PLAN.md` - Database migration guide
- `README.md` - Project overview

---

## Support

For issues or questions:
1. Check this guide first
2. Review Django Unfold documentation
3. Check project README.md
4. Review code comments in `apps/entities/admin.py`

---

**Last Updated:** Phase 2C Implementation  
**Version:** 1.0  
**Admin Theme:** Django Unfold 0.40.0
