Portatour Reviews Review
protected $casts = [ 'images' => 'array', 'replies' => 'array', 'is_verified_purchase' => 'boolean', 'is_approved' => 'boolean', ];
$review = PortaTourReview::create([ 'tour_id' => $tourId, 'user_id' => auth()->id(), 'booking_id' => $booking->id, 'rating' => $request->rating, 'title' => $request->title, 'comment' => $request->comment, 'images' => $request->images, 'is_verified_purchase' => true, 'is_approved' => false, // auto-approve or require moderation ]); portatour reviews
// POST /api/tours/tourId/reviews public function store(Request $request, $tourId) max:5', 'images.*' => 'url' ]); $booking = Booking::where('tour_id', $tourId) ->where('user_id', auth()->id()) ->where('status', 'completed') ->firstOrFail(); protected $casts = [ 'images' => 'array', 'replies'
return response()->json($review, 201); // GET /api/tours/tourId/reviews public function index($tourId) protected $casts = [ 'images' =>
return response()->json(['stats' => $stats, 'reviews' => $reviews]); import useState, useEffect from 'react'; import StarRating from './StarRating'; const PortaTourReviews = ( tourId ) => const [reviews, setReviews] = useState([]); const [stats, setStats] = useState(null); const [newReview, setNewReview] = useState( rating: 5, title: '', comment: '' );
return $this->belongsTo(Tour::class);
protected $table = 'portatour_reviews'; protected $fillable = [ 'tour_id', 'user_id', 'booking_id', 'rating', 'title', 'comment', 'images', 'replies', 'is_verified_purchase', 'is_approved', 'helpful_count', 'reported_count' ];