Reviews — Portatour
public function markHelpful($userId)
"@context": "https://schema.org", "@type": "Product", "name": "Paris Walking Tour", "aggregateRating": "@type": "AggregateRating", "ratingValue": "4.8", "reviewCount": "127" , "review": [ "@type": "Review", "author": "John Doe", "datePublished": "2025-03-10", "reviewRating": "@type": "Rating", "ratingValue": "5" , "reviewBody": "Amazing guide!" ] portatour reviews
export default PortaTourReviews; // Admin routes Route::get('/admin/reviews/pending', [AdminReviewController::class, 'pending']); Route::patch('/admin/reviews/id/approve', [AdminReviewController::class, 'approve']); Route::delete('/admin/reviews/id', [AdminReviewController::class, 'destroy']); Admin view filters unapproved reviews, can approve, delete, or reply. 5. SEO & Schema.org Markup Add to tour page: "name": "Paris Walking Tour"
return ( <div className="portatour-reviews"> <div className="reviews-header"> <h2>Customer Reviews</h2> <div className="rating-summary"> <span className="average">stats?.average_rating.toFixed(1)</span> <StarRating rating=stats?.average_rating /> <span>(stats?.total_reviews reviews)</span> </div> </div> "aggregateRating": "@type": "AggregateRating"
$reviews = PortaTourReview::where('tour_id', $tourId) ->where('is_approved', true) ->with('user:id,name,avatar') ->orderBy('created_at', 'desc') ->paginate(10); // Aggregate rating breakdown $stats = [ 'average_rating' => PortaTourReview::where('tour_id', $tourId) ->where('is_approved', true) ->avg('rating'), 'total_reviews' => $reviews->total(), 'rating_counts' => PortaTourReview::where('tour_id', $tourId) ->where('is_approved', true) ->selectRaw('rating, count(*) as count') ->groupBy('rating') ->pluck('count', 'rating') ];







