# Reviews Listing Page Implementation Prompt

## Django Parity Reference
**Django Implementation**: `reviews/views.py` - `ReviewListView` (similar patterns to other listing views)
**Django Template**: `reviews/templates/reviews/review_list.html`
**Django Features**: Social interaction display, sentiment analysis, review verification, context-aware filtering, real-time engagement metrics

## Core Implementation Requirements

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

```bash
# Generate main reviews listing with social interaction support
php artisan make:thrillwiki-livewire ReviewsListing --paginated --cached --with-tests

# Generate social interaction components
php artisan make:thrillwiki-livewire ReviewSocialInteractions --reusable --with-tests

# Generate sentiment analysis display
php artisan make:thrillwiki-livewire ReviewSentimentAnalysis --reusable --cached

# Generate review verification system
php artisan make:thrillwiki-livewire ReviewVerificationBadges --reusable --with-tests

# Generate context-aware filters
php artisan make:thrillwiki-livewire ReviewsContextFilters --reusable --cached

# Generate real-time engagement metrics
php artisan make:thrillwiki-livewire ReviewEngagementMetrics --reusable --with-tests

# Generate review quality indicators
php artisan make:thrillwiki-livewire ReviewQualityIndicators --reusable --cached

# Generate user credibility system
php artisan make:thrillwiki-livewire UserCredibilityBadges --reusable --with-tests
```

### Django Parity Features

#### 1. Social Review Search Functionality
**Django Implementation**: Multi-faceted search across:
- Review content (`content__icontains`)
- Reviewer username (`user__username__icontains`)
- Reviewable entity (`reviewable__name__icontains`)
- Review tags (`tags__name__icontains`)
- Experience context (`experience_context__icontains`)
- Visit verification status (`verified_visit`)

**Laravel Implementation**:
```php
public function socialReviewSearch($query, $context = 'all')
{
    return Review::query()
        ->when($query, function ($q) use ($query) {
            $terms = explode(' ', $query);
            foreach ($terms as $term) {
                $q->where(function ($subQuery) use ($term) {
                    $subQuery->where('content', 'ilike', "%{$term}%")
                            ->orWhere('title', 'ilike', "%{$term}%")
                            ->orWhere('experience_context', 'ilike', "%{$term}%")
                            ->orWhereHas('user', function($userQuery) use ($term) {
                                $userQuery->where('username', 'ilike', "%{$term}%")
                                         ->orWhere('display_name', 'ilike', "%{$term}%");
                            })
                            ->orWhereHas('reviewable', function($entityQuery) use ($term) {
                                $entityQuery->where('name', 'ilike', "%{$term}%");
                            })
                            ->orWhereHas('tags', function($tagQuery) use ($term) {
                                $tagQuery->where('name', 'ilike', "%{$term}%");
                            });
                });
            }
        })
        ->when($context !== 'all', function ($q) use ($context) {
            $q->where('reviewable_type', $this->getModelClass($context));
        })
        ->with([
            'user' => fn($q) => $q->with(['profile', 'credibilityBadges']),
            'reviewable',
            'likes' => fn($q) => $q->with('user:id,username'),
            'comments' => fn($q) => $q->with('user:id,username')->limit(3),
            'tags',
            'verificationBadges'
        ])
        ->withCount(['likes', 'dislikes', 'comments', 'shares'])
        ->addSelect([
            'engagement_score' => DB::raw('(likes_count * 2 + comments_count * 3 + shares_count * 4)')
        ]);
}
```

#### 2. Advanced Social Filtering
**Django Filters**:
- Review rating (1-5 stars)
- Verification status (verified, unverified, disputed)
- Sentiment analysis (positive, neutral, negative)
- Social engagement level (high, medium, low)
- Review recency (last_day, last_week, last_month, last_year)
- User credibility level (expert, trusted, verified, new)
- Review context (solo_visit, group_visit, family_visit, enthusiast_visit)
- Review completeness (photos, detailed, brief)

**Laravel Filters Implementation**:
```php
public function applySocialFilters($query, $filters)
{
    return $query
        ->when($filters['rating_range'] ?? null, function ($q, $range) {
            [$min, $max] = explode('-', $range);
            $q->whereBetween('rating', [$min, $max]);
        })
        ->when($filters['verification_status'] ?? null, function ($q, $status) {
            switch ($status) {
                case 'verified':
                    $q->where('verified_visit', true);
                    break;
                case 'unverified':
                    $q->where('verified_visit', false);
                    break;
                case 'disputed':
                    $q->where('verification_disputed', true);
                    break;
            }
        })
        ->when($filters['sentiment'] ?? null, function ($q, $sentiment) {
            $sentimentRanges = [
                'positive' => [0.6, 1.0],
                'neutral' => [0.4, 0.6],
                'negative' => [0.0, 0.4]
            ];
            if (isset($sentimentRanges[$sentiment])) {
                $q->whereBetween('sentiment_score', $sentimentRanges[$sentiment]);
            }
        })
        ->when($filters['engagement_level'] ?? null, function ($q, $level) {
            $engagementThresholds = [
                'high' => 20,
                'medium' => 5,
                'low' => 0
            ];
            if (isset($engagementThresholds[$level])) {
                $q->havingRaw('(likes_count + comments_count + shares_count) >= ?', 
                             [$engagementThresholds[$level]]);
            }
        })
        ->when($filters['recency'] ?? null, function ($q, $recency) {
            $timeRanges = [
                'last_day' => now()->subDay(),
                'last_week' => now()->subWeek(),
                'last_month' => now()->subMonth(),
                'last_year' => now()->subYear()
            ];
            if (isset($timeRanges[$recency])) {
                $q->where('created_at', '>=', $timeRanges[$recency]);
            }
        })
        ->when($filters['user_credibility'] ?? null, function ($q, $credibility) {
            $q->whereHas('user', function ($userQuery) use ($credibility) {
                switch ($credibility) {
                    case 'expert':
                        $userQuery->whereHas('credibilityBadges', fn($badge) => 
                                   $badge->where('type', 'expert'));
                        break;
                    case 'trusted':
                        $userQuery->where('trust_score', '>=', 80);
                        break;
                    case 'verified':
                        $userQuery->whereNotNull('email_verified_at');
                        break;
                    case 'new':
                        $userQuery->where('created_at', '>=', now()->subMonths(3));
                        break;
                }
            });
        })
        ->when($filters['review_context'] ?? null, function ($q, $context) {
            $q->where('visit_context', $context);
        })
        ->when($filters['completeness'] ?? null, function ($q, $completeness) {
            switch ($completeness) {
                case 'photos':
                    $q->whereHas('photos');
                    break;
                case 'detailed':
                    $q->whereRaw('LENGTH(content) > 500');
                    break;
                case 'brief':
                    $q->whereRaw('LENGTH(content) <= 200');
                    break;
            }
        });
}
```

#### 3. Real-Time Social Engagement Display
**Social Metrics**:
- Like/dislike counts with user attribution
- Comment threads with nested replies
- Share counts across platforms
- User credibility and verification badges
- Sentiment analysis visualization
- Engagement trend tracking

### Screen-Agnostic Design Implementation

#### Mobile Layout (320px - 767px)
- **Social Review Cards**: Compact cards with engagement metrics
- **Touch Interactions**: Swipe-to-like, pull-to-refresh, tap interactions
- **Social Actions**: Prominent like/comment/share buttons
- **User Attribution**: Clear reviewer identification with badges

**Mobile Component Structure**:
```blade
<div class="reviews-mobile-layout">
    <!-- Social Search Bar -->
    <div class="sticky top-0 bg-white dark:bg-gray-900 z-20 p-4">
        <livewire:reviews-social-search />
        <div class="flex items-center mt-2 space-x-2">
            <button wire:click="filterByContext('park')" 
                    class="flex items-center space-x-1 px-3 py-1 {{ $activeContext === 'park' ? 'bg-blue-500 text-white' : 'bg-blue-100 dark:bg-blue-900' }} rounded-full">
                <span class="text-sm">Parks</span>
            </button>
            <button wire:click="filterByContext('ride')" 
                    class="flex items-center space-x-1 px-3 py-1 {{ $activeContext === 'ride' ? 'bg-green-500 text-white' : 'bg-green-100 dark:bg-green-900' }} rounded-full">
                <span class="text-sm">Rides</span>
            </button>
            <button wire:click="toggleVerifiedOnly" 
                    class="flex items-center space-x-1 px-2 py-1 {{ $verifiedOnly ? 'bg-orange-500 text-white' : 'bg-orange-100 dark:bg-orange-900' }} rounded-full">
                <svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
                    <path fill-rule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
                </svg>
                <span class="text-xs">Verified</span>
            </button>
        </div>
    </div>
    
    <!-- Community Engagement Banner -->
    <div class="bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 text-white p-4 m-4 rounded-lg">
        <livewire:reviews-community-stats :compact="true" />
    </div>
    
    <!-- Quick Filters -->
    <div class="horizontal-scroll p-4 pb-2">
        <livewire:reviews-quick-filters />
    </div>
    
    <!-- Review Cards -->
    <div class="space-y-4 p-4">
        @foreach($reviews as $review)
            <livewire:review-mobile-card :review="$review" :show-social="true" :key="$review->id" />
        @endforeach
    </div>
    
    <!-- Mobile Pagination -->
    <div class="sticky bottom-0 bg-white dark:bg-gray-900 p-4">
        {{ $reviews->links('pagination.mobile') }}
    </div>
</div>
```

#### Tablet Layout (768px - 1023px)
- **Social Stream Layout**: Two-column review stream with engagement sidebar
- **Interactive Comments**: Expandable comment threads
- **Multi-Touch Gestures**: Pinch-to-zoom on photos, swipe between reviews
- **Social Activity Feed**: Real-time updates on review interactions

**Tablet Component Structure**:
```blade
<div class="reviews-tablet-layout flex h-screen">
    <!-- Social Filter Sidebar -->
    <div class="w-80 bg-gray-50 dark:bg-gray-800 overflow-y-auto">
        <div class="p-6">
            <livewire:reviews-social-search :advanced="true" />
            <div class="mt-6">
                <livewire:reviews-context-filters :expanded="true" />
            </div>
            <div class="mt-6">
                <livewire:reviews-social-filters :show-engagement="true" />
            </div>
            <div class="mt-6">
                <livewire:reviews-community-stats :detailed="true" />
            </div>
        </div>
    </div>
    
    <!-- Main Content Area -->
    <div class="flex-1 flex flex-col">
        <!-- Social 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">{{ $reviews->total() }} Community Reviews</h2>
                    <livewire:reviews-engagement-overview />
                </div>
                <div class="flex items-center space-x-2">
                    <livewire:reviews-sort-selector />
                    <livewire:reviews-view-toggle />
                </div>
            </div>
        </div>
        
        <!-- Content Stream -->
        <div class="flex-1 overflow-y-auto p-6">
            @if($view === 'stream')
                <div class="space-y-6">
                    @foreach($reviews as $review)
                        <livewire:review-tablet-card :review="$review" :interactive="true" :key="$review->id" />
                    @endforeach
                </div>
            @elseif($view === 'sentiment')
                <livewire:reviews-sentiment-analysis :reviews="$reviews" />
            @else
                <livewire:reviews-engagement-dashboard :reviews="$reviews" />
            @endif
            
            <div class="mt-6">
                {{ $reviews->links() }}
            </div>
        </div>
    </div>
</div>
```

#### Desktop Layout (1024px - 1919px)
- **Three-Pane Social Layout**: Filters + reviews + activity feed
- **Advanced Social Features**: Real-time notifications, user following
- **Rich Interaction**: Hover states, contextual menus, drag-and-drop
- **Community Moderation**: Flagging, reporting, and moderation tools

**Desktop Component Structure**:
```blade
<div class="reviews-desktop-layout flex h-screen">
    <!-- Advanced Social Filters -->
    <div class="w-80 bg-gray-50 dark:bg-gray-800 overflow-y-auto">
        <div class="p-6">
            <livewire:reviews-social-search :advanced="true" :autocomplete="true" />
            <div class="mt-6">
                <livewire:reviews-context-filters :advanced="true" :show-statistics="true" />
            </div>
            <div class="mt-6">
                <livewire:reviews-social-filters :advanced="true" :show-engagement="true" />
            </div>
        </div>
    </div>
    
    <!-- Main Content -->
    <div class="flex-1 flex flex-col">
        <!-- Social 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">{{ $reviews->total() }} Community Reviews</h1>
                    <livewire:reviews-social-summary />
                </div>
                <div class="flex items-center space-x-4">
                    <livewire:reviews-sort-selector :advanced="true" />
                    <livewire:reviews-view-selector />
                    <livewire:reviews-moderation-tools />
                </div>
            </div>
            <livewire:reviews-advanced-search />
        </div>
        
        <!-- Content Area -->
        <div class="flex-1 overflow-y-auto">
            @if($view === 'feed')
                <div class="p-6 space-y-6">
                    @foreach($reviews as $review)
                        <livewire:review-desktop-card :review="$review" :comprehensive="true" :key="$review->id" />
                    @endforeach
                    <div class="mt-8">
                        {{ $reviews->links('pagination.desktop') }}
                    </div>
                </div>
            @elseif($view === 'sentiment')
                <div class="p-6">
                    <livewire:reviews-sentiment-dashboard :reviews="$reviews" :interactive="true" />
                </div>
            @elseif($view === 'moderation')
                <div class="p-6">
                    <livewire:reviews-moderation-dashboard :reviews="$reviews" />
                </div>
            @else
                <div class="p-6">
                    <livewire:reviews-social-analytics :reviews="$reviews" />
                </div>
            @endif
        </div>
    </div>
    
    <!-- Social Activity Panel -->
    <div class="w-80 bg-gray-50 dark:bg-gray-800 overflow-y-auto">
        <div class="p-6">
            <livewire:reviews-social-activity />
            <div class="mt-6">
                <livewire:reviews-trending-topics />
            </div>
            <div class="mt-6">
                <livewire:reviews-featured-reviewers />
            </div>
        </div>
    </div>
</div>
```

#### Large Screen Layout (1920px+)
- **Dashboard-Style Social Interface**: Comprehensive community analytics
- **Multi-Panel Views**: Simultaneous review streams and analytics
- **Advanced Visualizations**: Sentiment analysis charts and engagement networks
- **Community Management**: Advanced moderation and user management tools

### Performance Optimization Strategy

#### Social Engagement Caching
```php
public function mount()
{
    $this->socialStats = Cache::remember(
        'reviews.social.stats',
        now()->addMinutes(15),
        fn() => $this->calculateSocialStatistics()
    );
    
    $this->trendingTopics = Cache::remember(
        'reviews.trending.topics',
        now()->addHours(1),
        fn() => $this->loadTrendingTopics()
    );
}

public function getReviewsProperty()
{
    $cacheKey = "reviews.listing." . md5(serialize([
        'search' => $this->search,
        'filters' => $this->filters,
        'context_filter' => $this->contextFilter,
        'sort' => $this->sort,
        'page' => $this->page,
        'user_id' => auth()->id() // For personalized content
    ]));
    
    return Cache::remember($cacheKey, now()->addMinutes(10), function() {
        return $this->socialReviewSearch($this->search, $this->contextFilter)
            ->applySocialFilters($this->filters)
            ->orderBy($this->sort['column'], $this->sort['direction'])
            ->paginate(12);
    });
}
```

#### Real-Time Social Features
```php
// Optimized query for social engagement data
public function optimizedSocialQuery()
{
    return Review::select([
        'reviews.*',
        DB::raw('COALESCE(likes_count.count, 0) as likes_count'),
        DB::raw('COALESCE(comments_count.count, 0) as comments_count'),
        DB::raw('COALESCE(shares_count.count, 0) as shares_count'),
        DB::raw('(COALESCE(likes_count.count, 0) * 2 + 
                  COALESCE(comments_count.count, 0) * 3 + 
                  COALESCE(shares_count.count, 0) * 4) as engagement_score'),
        DB::raw('CASE 
            WHEN sentiment_score >= 0.6 THEN "positive"
            WHEN sentiment_score >= 0.4 THEN "neutral"
            ELSE "negative"
        END as sentiment_category')
    ])
    ->leftJoin(DB::raw('(SELECT review_id, COUNT(*) as count FROM review_likes GROUP BY review_id) as likes_count'), 
              'reviews.id', '=', 'likes_count.review_id')
    ->leftJoin(DB::raw('(SELECT review_id, COUNT(*) as count FROM review_comments GROUP BY review_id) as comments_count'), 
              'reviews.id', '=', 'comments_count.review_id')
    ->leftJoin(DB::raw('(SELECT review_id, COUNT(*) as count FROM review_shares GROUP BY review_id) as shares_count'), 
              'reviews.id', '=', 'shares_count.review_id')
    ->with([
        'user:id,username,display_name,avatar_url',
        'user.credibilityBadges:id,user_id,type,title',
        'reviewable:id,name,type',
        'verificationBadges:id,review_id,type,verified_at',
        'recentLikes' => fn($q) => $q->with('user:id,username')->limit(5),
        'topComments' => fn($q) => $q->with('user:id,username')->orderBy('likes_count', 'desc')->limit(3)
    ]);
}
```

### Component Reuse Strategy

#### Shared Components
- **`ReviewSocialInteractions`**: Like/comment/share functionality across all review contexts
- **`ReviewVerificationBadges`**: Trust and verification indicators for authentic reviews
- **`ReviewEngagementMetrics`**: Real-time engagement tracking and display
- **`UserCredibilityBadges`**: User reputation and expertise indicators

#### Context Variations
- **`ParkReviewsListing`**: Park-specific reviews with location context
- **`RideReviewsListing`**: Ride-specific reviews with experience context
- **`UserReviewsListing`**: User profile reviews with credibility focus
- **`FeaturedReviewsListing`**: High-engagement reviews with community highlights

### Testing Requirements

#### Feature Tests
```php
/** @test */
public function can_filter_reviews_by_social_engagement()
{
    $highEngagement = Review::factory()->create(['content' => 'Amazing experience!']);
    $highEngagement->likes()->createMany(15, ['user_id' => User::factory()]);
    $highEngagement->comments()->createMany(8, ['user_id' => User::factory()]);
    
    $lowEngagement = Review::factory()->create(['content' => 'Okay ride']);
    $lowEngagement->likes()->create(['user_id' => User::factory()]);
    
    Livewire::test(ReviewsListing::class)
        ->set('filters.engagement_level', 'high')
        ->assertSee($highEngagement->content)
        ->assertDontSee($lowEngagement->content);
}

/** @test */
public function displays_user_credibility_correctly()
{
    $expertUser = User::factory()->create(['username' => 'expert_reviewer']);
    $expertUser->credibilityBadges()->create(['type' => 'expert', 'title' => 'Theme Park Expert']);
    
    $expertReview = Review::factory()->create([
        'user_id' => $expertUser->id,
        'content' => 'Professional analysis'
    ]);
    
    Livewire::test(ReviewsListing::class)
        ->assertSee('Theme Park Expert')
        ->assertSee($expertReview->content);
}

/** @test */
public function maintains_django_parity_performance_with_social_data()
{
    Review::factory()->count(30)->create();
    
    $start = microtime(true);
    Livewire::test(ReviewsListing::class);
    $end = microtime(true);
    
    $this->assertLessThan(0.5, $end - $start); // < 500ms with social data
}
```

#### Social Interaction Tests
```php
/** @test */
public function calculates_engagement_scores_accurately()
{
    $review = Review::factory()->create();
    $review->likes()->createMany(10, ['user_id' => User::factory()]);
    $review->comments()->createMany(5, ['user_id' => User::factory()]);
    $review->shares()->createMany(2, ['user_id' => User::factory()]);
    
    $component = Livewire::test(ReviewsListing::class);
    $reviewData = $component->get('reviews')->first();
    
    // Engagement score = (likes * 2) + (comments * 3) + (shares * 4)
    $expectedScore = (10 * 2) + (5 * 3) + (2 * 4); // 43
    $this->assertEquals($expectedScore, $reviewData->engagement_score);
}

/** @test */
public function handles_real_time_social_updates()
{
    $review = Review::factory()->create();
    
    $component = Livewire::test(ReviewsListing::class);
    
    // Simulate real-time like
    $review->likes()->create(['user_id' => User::factory()->create()]);
    
    $component->call('refreshEngagement', $review->id)
              ->assertSee('1 like');
}
```

### Performance Targets

#### Universal Performance Standards with Social Features
- **Initial Load**: < 500ms (including engagement metrics)
- **Social Interaction Response**: < 200ms for like/comment actions
- **Real-time Updates**: < 100ms for engagement refresh
- **Sentiment Analysis**: < 150ms for sentiment visualization
- **Community Statistics**: < 100ms (cached)

#### Social Content Caching Strategy
- **Engagement Metrics**: 10 minutes (frequently changing)
- **Trending Topics**: 1 hour (community trends)
- **User Credibility**: 6 hours (reputation changes slowly)
- **Social Statistics**: 15 minutes (community activity)

### Success Criteria Checklist

#### Django Parity Verification
- [ ] Social review search matches Django behavior exactly
- [ ] Engagement metrics calculated identically to Django
- [ ] Verification systems work like Django implementation
- [ ] Sentiment analysis provides same results as Django
- [ ] Community features match Django social functionality

#### Screen-Agnostic Compliance
- [ ] Mobile layout optimized for social interaction
- [ ] Tablet layout provides effective community browsing
- [ ] Desktop layout maximizes social engagement features
- [ ] Large screen layout provides comprehensive community management
- [ ] All layouts handle real-time social updates gracefully

#### Performance Benchmarks
- [ ] Initial load under 500ms including social data
- [ ] Social interactions under 200ms response time
- [ ] Real-time updates under 100ms
- [ ] Community statistics under 100ms (cached)
- [ ] Social caching reduces server load by 70%

#### Social Feature Completeness
- [ ] Engagement metrics display accurately across all contexts
- [ ] User credibility systems provide meaningful trust indicators
- [ ] Verification badges work for authentic experience validation
- [ ] Community moderation tools function effectively
- [ ] Real-time social updates work seamlessly across devices

This prompt ensures complete Django parity while providing comprehensive social review capabilities that foster authentic community engagement while maintaining ThrillWiki's screen-agnostic design principles.