# 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
@foreach($reviews as $review) @endforeach
{{ $reviews->links('pagination.mobile') }}
``` #### 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

{{ $reviews->total() }} Community Reviews

@if($view === 'stream')
@foreach($reviews as $review) @endforeach
@elseif($view === 'sentiment') @else @endif
{{ $reviews->links() }}
``` #### 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

{{ $reviews->total() }} Community Reviews

@if($view === 'feed')
@foreach($reviews as $review) @endforeach
{{ $reviews->links('pagination.desktop') }}
@elseif($view === 'sentiment')
@elseif($view === 'moderation')
@else
@endif
``` #### 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.