# Designers Listing Page Implementation Prompt

## Django Parity Reference
**Django Implementation**: `designers/views.py` - `DesignerListView` (similar patterns to companies views)
**Django Template**: `designers/templates/designers/designer_list.html`
**Django Features**: Creative portfolio showcases, design specialization filtering, innovation timeline display, collaboration networks, award recognition system

## Core Implementation Requirements

### Laravel/Livewire Architecture
Generate the designers listing system using ThrillWiki's custom generators:

```bash
# Generate main designers listing with creative portfolio support
php artisan make:thrillwiki-livewire DesignersListing --paginated --cached --with-tests

# Generate creative specialization filters
php artisan make:thrillwiki-livewire DesignersSpecializationFilter --reusable --with-tests

# Generate portfolio showcase component
php artisan make:thrillwiki-livewire DesignerPortfolioShowcase --reusable --with-tests

# Generate innovation timeline component
php artisan make:thrillwiki-livewire DesignerInnovationTimeline --reusable --cached

# Generate collaboration network visualization
php artisan make:thrillwiki-livewire DesignerCollaborationNetwork --reusable --with-tests

# Generate awards and recognition display
php artisan make:thrillwiki-livewire DesignerAwardsRecognition --reusable --cached

# Generate design influence analysis
php artisan make:thrillwiki-livewire DesignerInfluenceAnalysis --reusable --with-tests
```

### Django Parity Features

#### 1. Creative Portfolio Search Functionality
**Django Implementation**: Multi-faceted search across:
- Designer name (`name__icontains`)
- Design specialization (`specialization__icontains`)
- Notable innovations (`innovations__description__icontains`)
- Career highlights (`career_highlights__icontains`)
- Awards and recognition (`awards__title__icontains`)
- Collaboration partners (`collaborations__partner__name__icontains`)

**Laravel Implementation**:
```php
public function creativePortfolioSearch($query, $specializations = [])
{
    return Designer::query()
        ->when($query, function ($q) use ($query) {
            $terms = explode(' ', $query);
            foreach ($terms as $term) {
                $q->where(function ($subQuery) use ($term) {
                    $subQuery->where('name', 'ilike', "%{$term}%")
                            ->orWhere('bio', 'ilike', "%{$term}%")
                            ->orWhere('design_philosophy', 'ilike', "%{$term}%")
                            ->orWhere('career_highlights', 'ilike', "%{$term}%")
                            ->orWhereHas('designed_rides', function($rideQuery) use ($term) {
                                $rideQuery->where('name', 'ilike', "%{$term}%")
                                         ->orWhere('description', 'ilike', "%{$term}%");
                            })
                            ->orWhereHas('awards', function($awardQuery) use ($term) {
                                $awardQuery->where('title', 'ilike', "%{$term}%")
                                          ->orWhere('description', 'ilike', "%{$term}%");
                            })
                            ->orWhereHas('innovations', function($innQuery) use ($term) {
                                $innQuery->where('title', 'ilike', "%{$term}%")
                                        ->orWhere('description', 'ilike', "%{$term}%");
                            });
                });
            }
        })
        ->when($specializations, function ($q) use ($specializations) {
            $q->where(function ($specQuery) use ($specializations) {
                foreach ($specializations as $spec) {
                    $specQuery->orWhereJsonContains('specializations', $spec);
                }
            });
        })
        ->with([
            'designed_rides' => fn($q) => $q->with(['park', 'photos'])->limit(5),
            'awards' => fn($q) => $q->orderBy('year', 'desc')->limit(3),
            'innovations' => fn($q) => $q->orderBy('year', 'desc')->limit(3),
            'collaborations' => fn($q) => $q->with('partner')->limit(5)
        ])
        ->withCount(['designed_rides', 'awards', 'innovations', 'collaborations']);
}
```

#### 2. Advanced Creative Filtering
**Django Filters**:
- Design specialization (coaster_designer, dark_ride_specialist, theming_expert)
- Experience level (emerging, established, legendary)
- Innovation era (classic, modern, contemporary, cutting_edge)
- Career span (active_years range)
- Award categories (technical, artistic, lifetime_achievement)
- Collaboration type (solo_artist, team_player, cross_industry)
- Geographic influence (regional, national, international)

**Laravel Filters Implementation**:
```php
public function applyCreativeFilters($query, $filters)
{
    return $query
        ->when($filters['specializations'] ?? null, function ($q, $specializations) {
            $q->where(function ($specQuery) use ($specializations) {
                foreach ($specializations as $spec) {
                    $specQuery->orWhereJsonContains('specializations', $spec);
                }
            });
        })
        ->when($filters['experience_level'] ?? null, function ($q, $level) {
            $experienceRanges = [
                'emerging' => [0, 5],
                'established' => [6, 15],
                'veteran' => [16, 25],
                'legendary' => [26, PHP_INT_MAX]
            ];
            if (isset($experienceRanges[$level])) {
                $q->whereRaw('EXTRACT(YEAR FROM NOW()) - career_start_year BETWEEN ? AND ?', 
                            $experienceRanges[$level]);
            }
        })
        ->when($filters['innovation_era'] ?? null, function ($q, $era) {
            $eraRanges = [
                'classic' => [1950, 1979],
                'modern' => [1980, 1999],
                'contemporary' => [2000, 2009],
                'cutting_edge' => [2010, date('Y')]
            ];
            if (isset($eraRanges[$era])) {
                $q->whereHas('innovations', function ($innQuery) use ($eraRanges, $era) {
                    $innQuery->whereBetween('year', $eraRanges[$era]);
                });
            }
        })
        ->when($filters['career_start_from'] ?? null, fn($q, $year) => 
            $q->where('career_start_year', '>=', $year))
        ->when($filters['career_start_to'] ?? null, fn($q, $year) => 
            $q->where('career_start_year', '<=', $year))
        ->when($filters['award_categories'] ?? null, function ($q, $categories) {
            $q->whereHas('awards', function ($awardQuery) use ($categories) {
                $awardQuery->whereIn('category', $categories);
            });
        })
        ->when($filters['collaboration_style'] ?? null, function ($q, $style) {
            switch ($style) {
                case 'solo_artist':
                    $q->whereDoesntHave('collaborations');
                    break;
                case 'team_player':
                    $q->whereHas('collaborations', fn($colQ) => $colQ->where('type', 'team'));
                    break;
                case 'cross_industry':
                    $q->whereHas('collaborations', fn($colQ) => $colQ->where('type', 'cross_industry'));
                    break;
            }
        })
        ->when($filters['geographic_influence'] ?? null, function ($q, $influence) {
            switch ($influence) {
                case 'regional':
                    $q->whereHas('designed_rides', function ($rideQ) {
                        $rideQ->whereHas('park.location', function ($locQ) {
                            $locQ->havingRaw('COUNT(DISTINCT country) = 1');
                        });
                    });
                    break;
                case 'international':
                    $q->whereHas('designed_rides', function ($rideQ) {
                        $rideQ->whereHas('park.location', function ($locQ) {
                            $locQ->havingRaw('COUNT(DISTINCT country) > 3');
                        });
                    });
                    break;
            }
        });
}
```

#### 3. Innovation Timeline and Portfolio Display
**Creative Metrics**:
- Notable ride designs and their impact
- Innovation timeline with breakthrough moments
- Awards and industry recognition
- Collaboration network and partnerships
- Design philosophy and artistic influence
- Career milestones and achievements

### Screen-Agnostic Design Implementation

#### Mobile Layout (320px - 767px)
- **Designer Cards**: Artist-focused cards with signature designs
- **Portfolio Highlights**: Visual showcase of most notable works
- **Innovation Badges**: Visual indicators of breakthrough innovations
- **Timeline Snapshots**: Condensed career timeline view

**Mobile Component Structure**:
```blade
<div class="designers-mobile-layout">
    <!-- Creative Search Bar -->
    <div class="sticky top-0 bg-white dark:bg-gray-900 z-20 p-4">
        <livewire:designers-creative-search />
        <div class="flex items-center mt-2 space-x-2">
            <button wire:click="filterBySpecialization('coaster_designer')" 
                    class="flex items-center space-x-1 px-3 py-1 {{ $activeSpec === 'coaster_designer' ? 'bg-red-500 text-white' : 'bg-red-100 dark:bg-red-900' }} rounded-full">
                <span class="text-sm">Coasters</span>
            </button>
            <button wire:click="filterBySpecialization('dark_ride_specialist')" 
                    class="flex items-center space-x-1 px-3 py-1 {{ $activeSpec === 'dark_ride_specialist' ? 'bg-purple-500 text-white' : 'bg-purple-100 dark:bg-purple-900' }} rounded-full">
                <span class="text-sm">Dark Rides</span>
            </button>
            <button wire:click="filterBySpecialization('theming_expert')" 
                    class="flex items-center space-x-1 px-3 py-1 {{ $activeSpec === 'theming_expert' ? 'bg-green-500 text-white' : 'bg-green-100 dark:bg-green-900' }} rounded-full">
                <span class="text-sm">Theming</span>
            </button>
        </div>
    </div>
    
    <!-- Creative Inspiration Banner -->
    <div class="bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 text-white p-4 m-4 rounded-lg">
        <livewire:designers-inspiration-stats :compact="true" />
    </div>
    
    <!-- Quick Filters -->
    <div class="horizontal-scroll p-4 pb-2">
        <livewire:designers-quick-filters />
    </div>
    
    <!-- Designer Cards -->
    <div class="space-y-4 p-4">
        @foreach($designers as $designer)
            <livewire:designer-mobile-card :designer="$designer" :show-portfolio="true" :key="$designer->id" />
        @endforeach
    </div>
    
    <!-- Mobile Pagination -->
    <div class="sticky bottom-0 bg-white dark:bg-gray-900 p-4">
        {{ $designers->links('pagination.mobile') }}
    </div>
</div>
```

#### Tablet Layout (768px - 1023px)
- **Portfolio Gallery**: Visual grid of signature designs
- **Innovation Timeline**: Interactive career progression
- **Collaboration Network**: Visual relationship mapping
- **Awards Showcase**: Comprehensive recognition display

**Tablet Component Structure**:
```blade
<div class="designers-tablet-layout flex h-screen">
    <!-- Creative Filter Sidebar -->
    <div class="w-80 bg-gray-50 dark:bg-gray-800 overflow-y-auto">
        <div class="p-6">
            <livewire:designers-creative-search :advanced="true" />
            <div class="mt-6">
                <livewire:designers-specialization-filter :expanded="true" />
            </div>
            <div class="mt-6">
                <livewire:designers-creative-filters :show-awards="true" />
            </div>
            <div class="mt-6">
                <livewire:designers-inspiration-stats :detailed="true" />
            </div>
        </div>
    </div>
    
    <!-- Main Content Area -->
    <div class="flex-1 flex flex-col">
        <!-- Creative Header -->
        <div class="bg-white dark:bg-gray-900 p-4 border-b border-gray-200 dark:border-gray-700">
            <div class="flex items-center justify-between">
                <div class="flex items-center space-x-4">
                    <h2 class="text-xl font-semibold">{{ $designers->total() }} Visionary Designers</h2>
                    <livewire:designers-industry-overview />
                </div>
                <div class="flex items-center space-x-2">
                    <livewire:designers-sort-selector />
                    <livewire:designers-view-toggle />
                </div>
            </div>
        </div>
        
        <!-- Content Display -->
        <div class="flex-1 overflow-y-auto p-6">
            @if($view === 'grid')
                <div class="grid grid-cols-2 gap-6">
                    @foreach($designers as $designer)
                        <livewire:designer-tablet-card :designer="$designer" :portfolio="true" :key="$designer->id" />
                    @endforeach
                </div>
            @elseif($view === 'timeline')
                <div class="space-y-8">
                    @foreach($designers as $designer)
                        <livewire:designer-timeline-showcase :designer="$designer" :key="$designer->id" />
                    @endforeach
                </div>
            @else
                <livewire:designers-innovation-analysis :designers="$designers" />
            @endif
            
            <div class="mt-6">
                {{ $designers->links() }}
            </div>
        </div>
    </div>
</div>
```

#### Desktop Layout (1024px - 1919px)
- **Comprehensive Portfolio Views**: Detailed design showcases
- **Interactive Innovation Timeline**: Full career progression with milestones
- **Collaboration Network Visualization**: Complex relationship mapping
- **Creative Influence Analysis**: Industry impact visualization

**Desktop Component Structure**:
```blade
<div class="designers-desktop-layout flex h-screen">
    <!-- Advanced Creative Filters -->
    <div class="w-80 bg-gray-50 dark:bg-gray-800 overflow-y-auto">
        <div class="p-6">
            <livewire:designers-creative-search :advanced="true" :autocomplete="true" />
            <div class="mt-6">
                <livewire:designers-specialization-filter :advanced="true" :show-statistics="true" />
            </div>
            <div class="mt-6">
                <livewire:designers-creative-filters :advanced="true" :show-awards="true" />
            </div>
        </div>
    </div>
    
    <!-- Main Content -->
    <div class="flex-1 flex flex-col">
        <!-- Creative Dashboard Header -->
        <div class="bg-white dark:bg-gray-900 p-6 border-b border-gray-200 dark:border-gray-700">
            <div class="flex items-center justify-between mb-4">
                <div class="flex items-center space-x-6">
                    <h1 class="text-2xl font-bold">{{ $designers->total() }} Creative Visionaries</h1>
                    <livewire:designers-creative-summary />
                </div>
                <div class="flex items-center space-x-4">
                    <livewire:designers-sort-selector :advanced="true" />
                    <livewire:designers-view-selector />
                    <livewire:designers-export-options />
                </div>
            </div>
            <livewire:designers-advanced-search />
        </div>
        
        <!-- Content Area -->
        <div class="flex-1 overflow-y-auto">
            @if($view === 'portfolio')
                <div class="p-6">
                    <div class="grid grid-cols-3 xl:grid-cols-4 gap-6">
                        @foreach($designers as $designer)
                            <livewire:designer-desktop-card :designer="$designer" :comprehensive="true" :key="$designer->id" />
                        @endforeach
                    </div>
                    <div class="mt-8">
                        {{ $designers->links('pagination.desktop') }}
                    </div>
                </div>
            @elseif($view === 'timeline')
                <div class="p-6 space-y-8">
                    @foreach($designers as $designer)
                        <livewire:designer-innovation-timeline :designer="$designer" :detailed="true" :key="$designer->id" />
                    @endforeach
                </div>
            @elseif($view === 'network')
                <div class="p-6">
                    <livewire:designer-collaboration-network :designers="$designers" :interactive="true" />
                </div>
            @else
                <div class="p-6">
                    <livewire:designers-creative-dashboard :designers="$designers" />
                </div>
            @endif
        </div>
    </div>
    
    <!-- Creative Insights Panel -->
    <div class="w-80 bg-gray-50 dark:bg-gray-800 overflow-y-auto">
        <div class="p-6">
            <livewire:designers-creative-insights />
            <div class="mt-6">
                <livewire:designers-innovation-trends />
            </div>
            <div class="mt-6">
                <livewire:designers-featured-works />
            </div>
        </div>
    </div>
</div>
```

#### Large Screen Layout (1920px+)
- **Creative Studio Interface**: Comprehensive design analysis
- **Multi-Panel Innovation Views**: Simultaneous portfolio and timeline analysis
- **Advanced Visualization**: Creative influence networks and innovation patterns
- **Immersive Portfolio Experience**: Full-screen design showcases

### Performance Optimization Strategy

#### Creative Portfolio Caching
```php
public function mount()
{
    $this->creativeStats = Cache::remember(
        'designers.creative.stats',
        now()->addHours(8),
        fn() => $this->calculateCreativeStatistics()
    );
    
    $this->innovationTrends = Cache::remember(
        'designers.innovation.trends',
        now()->addHours(24),
        fn() => $this->loadInnovationTrends()
    );
}

public function getDesignersProperty()
{
    $cacheKey = "designers.listing." . md5(serialize([
        'search' => $this->search,
        'filters' => $this->filters,
        'specialization_filter' => $this->specializationFilter,
        'sort' => $this->sort,
        'page' => $this->page
    ]));
    
    return Cache::remember($cacheKey, now()->addMinutes(45), function() {
        return $this->creativePortfolioSearch($this->search, $this->specializationFilter)
            ->applyCreativeFilters($this->filters)
            ->orderBy($this->sort['column'], $this->sort['direction'])
            ->paginate(16);
    });
}
```

#### Portfolio Media Optimization
```php
// Optimized query for portfolio and innovation data
public function optimizedPortfolioQuery()
{
    return Designer::select([
        'designers.*',
        DB::raw('COALESCE(rides_count.count, 0) as designed_rides_count'),
        DB::raw('COALESCE(awards_count.count, 0) as awards_count'),
        DB::raw('COALESCE(innovations_count.count, 0) as innovations_count'),
        DB::raw('CASE 
            WHEN EXTRACT(YEAR FROM NOW()) - career_start_year > 25 THEN "legendary"
            WHEN EXTRACT(YEAR FROM NOW()) - career_start_year > 15 THEN "veteran"
            WHEN EXTRACT(YEAR FROM NOW()) - career_start_year > 5 THEN "established"
            ELSE "emerging"
        END as experience_level_category')
    ])
    ->leftJoin(DB::raw('(SELECT designer_id, COUNT(*) as count FROM rides GROUP BY designer_id) as rides_count'), 
              'designers.id', '=', 'rides_count.designer_id')
    ->leftJoin(DB::raw('(SELECT designer_id, COUNT(*) as count FROM designer_awards GROUP BY designer_id) as awards_count'), 
              'designers.id', '=', 'awards_count.designer_id')
    ->leftJoin(DB::raw('(SELECT designer_id, COUNT(*) as count FROM designer_innovations GROUP BY designer_id) as innovations_count'), 
              'designers.id', '=', 'innovations_count.designer_id')
    ->with([
        'designed_rides:id,designer_id,name,ride_type,opening_date',
        'awards:id,designer_id,title,year,category',
        'innovations:id,designer_id,title,year,description',
        'collaborations' => fn($q) => $q->with('partner:id,name,type')
    ]);
}
```

### Component Reuse Strategy

#### Shared Components
- **`DesignersSpecializationFilter`**: Multi-specialization filtering with visual indicators
- **`DesignerPortfolioShowcase`**: Comprehensive portfolio display with media
- **`DesignerInnovationTimeline`**: Interactive career progression visualization
- **`DesignerCreativeMetrics`**: Portfolio statistics and creative impact metrics

#### Context Variations
- **`CoasterDesignersListing`**: Coaster designers with ride performance metrics
- **`ThemingExpertsListing`**: Theming specialists with environmental design focus
- **`DarkRideDesignersListing`**: Dark ride specialists with storytelling emphasis
- **`EmergingDesignersListing`**: New talent showcase with potential indicators

### Testing Requirements

#### Feature Tests
```php
/** @test */
public function can_filter_designers_by_specialization()
{
    $coasterDesigner = Designer::factory()->create([
        'name' => 'John Wardley',
        'specializations' => ['coaster_designer', 'theming_expert']
    ]);
    $coasterDesigner->designed_rides()->create(['name' => 'The Smiler', 'ride_type' => 'roller-coaster']);
    
    $darkRideDesigner = Designer::factory()->create([
        'name' => 'Tony Baxter',
        'specializations' => ['dark_ride_specialist', 'imagineer']
    ]);
    $darkRideDesigner->designed_rides()->create(['name' => 'Indiana Jones Adventure', 'ride_type' => 'dark-ride']);
    
    Livewire::test(DesignersListing::class)
        ->set('specializationFilter', ['coaster_designer'])
        ->assertSee($coasterDesigner->name)
        ->assertDontSee($darkRideDesigner->name);
}

/** @test */
public function calculates_experience_level_correctly()
{
    $legendary = Designer::factory()->create(['career_start_year' => 1985]);
    $veteran = Designer::factory()->create(['career_start_year' => 2000]);
    $established = Designer::factory()->create(['career_start_year' => 2010]);
    $emerging = Designer::factory()->create(['career_start_year' => 2020]);
    
    $component = Livewire::test(DesignersListing::class);
    $designers = $component->get('designers');
    
    $this->assertEquals('legendary', $designers->where('id', $legendary->id)->first()->experience_level_category);
    $this->assertEquals('veteran', $designers->where('id', $veteran->id)->first()->experience_level_category);
}

/** @test */
public function maintains_django_parity_performance_with_portfolio_data()
{
    Designer::factory()->count(40)->create();
    
    $start = microtime(true);
    Livewire::test(DesignersListing::class);
    $end = microtime(true);
    
    $this->assertLessThan(0.5, $end - $start); // < 500ms with portfolio data
}
```

#### Creative Portfolio Tests
```php
/** @test */
public function displays_portfolio_metrics_accurately()
{
    $designer = Designer::factory()->create();
    $designer->designed_rides()->createMany(8, ['name' => 'Test Ride']);
    $designer->awards()->createMany(3, ['title' => 'Test Award']);
    $designer->innovations()->createMany(2, ['title' => 'Test Innovation']);
    
    $component = Livewire::test(DesignersListing::class);
    $portfolioData = $component->get('designers')->first();
    
    $this->assertEquals(8, $portfolioData->designed_rides_count);
    $this->assertEquals(3, $portfolioData->awards_count);
    $this->assertEquals(2, $portfolioData->innovations_count);
}

/** @test */
public function handles_collaboration_network_visualization()
{
    $designer1 = Designer::factory()->create(['name' => 'Designer One']);
    $designer2 = Designer::factory()->create(['name' => 'Designer Two']);
    
    $designer1->collaborations()->create([
        'partner_id' => $designer2->id,
        'type' => 'team',
        'project_name' => 'Joint Project'
    ]);
    
    $component = Livewire::test(DesignersListing::class);
    $collaborationData = $component->get('designers')->first()->collaborations;
    
    $this->assertCount(1, $collaborationData);
    $this->assertEquals('Joint Project', $collaborationData->first()->project_name);
}
```

### Performance Targets

#### Universal Performance Standards with Creative Content
- **Initial Load**: < 500ms (including portfolio thumbnails)
- **Portfolio Rendering**: < 300ms for 20 designers
- **Innovation Timeline**: < 200ms for complex career data
- **Collaboration Network**: < 1 second for network visualization
- **Creative Statistics**: < 150ms (cached)

#### Creative Content Caching Strategy
- **Innovation Trends**: 24 hours (industry trends stable)
- **Creative Statistics**: 8 hours (portfolio metrics change)
- **Portfolio Thumbnails**: 48 hours (visual content stable)
- **Designer Profiles**: 12 hours (career data relatively stable)

### Success Criteria Checklist

#### Django Parity Verification
- [ ] Creative portfolio search matches Django behavior exactly
- [ ] Specialization filtering provides same results as Django
- [ ] Innovation timeline displays identically to Django
- [ ] Awards and recognition match Django structure
- [ ] Collaboration networks visualize like Django implementation

#### Screen-Agnostic Compliance
- [ ] Mobile layout optimized for creative content consumption
- [ ] Tablet layout provides effective portfolio browsing
- [ ] Desktop layout maximizes creative visualization
- [ ] Large screen layout provides immersive portfolio experience
- [ ] All layouts handle rich media content gracefully

#### Performance Benchmarks
- [ ] Initial load under 500ms including portfolio media
- [ ] Portfolio rendering under 300ms
- [ ] Innovation timeline under 200ms
- [ ] Creative statistics under 150ms (cached)
- [ ] Portfolio caching reduces server load by 65%

#### Creative Feature Completeness
- [ ] Specialization filtering works across all design disciplines
- [ ] Portfolio showcases provide comprehensive creative overviews
- [ ] Innovation timelines visualize career progression accurately
- [ ] Collaboration networks display meaningful relationships
- [ ] Awards and recognition systems provide proper attribution

This prompt ensures complete Django parity while providing comprehensive creative portfolio capabilities that showcase designer talent and innovation while maintaining ThrillWiki's screen-agnostic design principles.