null, 'title' => null, 'content' => null, ]; /** * Success/error message */ public ?string $message = null; /** * Validation rules */ protected function rules() { return [ 'form.rating' => 'required|integer|min:1|max:5', 'form.title' => 'nullable|string|max:100', 'form.content' => 'required|string|min:10|max:2000', ]; } /** * Mount the component */ public function mount() { $this->statusFilter = ReviewStatus::PENDING->value; } /** * Filter by status */ public function filterByStatus(?string $status) { $this->statusFilter = $status; $this->resetPage(); } /** * Show edit modal for a review */ public function editReview(Review $review) { $this->editingReview = $review; $this->form = [ 'rating' => $review->rating, 'title' => $review->title, 'content' => $review->content, ]; $this->showEditModal = true; } /** * Save edited review */ public function saveEdit() { $this->validate(); try { $this->editingReview->update([ 'rating' => $this->form['rating'], 'title' => $this->form['title'], 'content' => $this->form['content'], 'moderated_at' => now(), 'moderated_by' => Auth::id(), ]); $this->message = 'Review updated successfully.'; $this->showEditModal = false; $this->reset(['editingReview', 'form']); } catch (\Exception $e) { $this->message = 'An error occurred while updating the review.'; } } /** * Approve a review */ public function approve(Review $review) { try { $review->update([ 'status' => ReviewStatus::APPROVED, 'moderated_at' => now(), 'moderated_by' => Auth::id(), ]); $this->message = 'Review approved successfully.'; } catch (\Exception $e) { $this->message = 'An error occurred while approving the review.'; } } /** * Reject a review */ public function reject(Review $review) { try { $review->update([ 'status' => ReviewStatus::REJECTED, 'moderated_at' => now(), 'moderated_by' => Auth::id(), ]); $this->message = 'Review rejected successfully.'; } catch (\Exception $e) { $this->message = 'An error occurred while rejecting the review.'; } } /** * Batch approve selected reviews */ public function batchApprove() { try { Review::whereIn('id', $this->selected)->update([ 'status' => ReviewStatus::APPROVED, 'moderated_at' => now(), 'moderated_by' => Auth::id(), ]); $this->message = count($this->selected) . ' reviews approved successfully.'; $this->selected = []; } catch (\Exception $e) { $this->message = 'An error occurred while approving the reviews.'; } } /** * Batch reject selected reviews */ public function batchReject() { try { Review::whereIn('id', $this->selected)->update([ 'status' => ReviewStatus::REJECTED, 'moderated_at' => now(), 'moderated_by' => Auth::id(), ]); $this->message = count($this->selected) . ' reviews rejected successfully.'; $this->selected = []; } catch (\Exception $e) { $this->message = 'An error occurred while rejecting the reviews.'; } } /** * Get the reviews query */ protected function getReviewsQuery() { $query = Review::with(['user', 'ride']) ->when($this->statusFilter, function ($query, $status) { $query->where('status', $status); }) ->when($this->search, function ($query, $search) { $query->where(function ($query) use ($search) { $query->where('title', 'like', "%{$search}%") ->orWhere('content', 'like', "%{$search}%") ->orWhereHas('user', function ($query) use ($search) { $query->where('name', 'like', "%{$search}%"); }) ->orWhereHas('ride', function ($query) use ($search) { $query->where('name', 'like', "%{$search}%"); }); }); }) ->orderBy('created_at', 'desc'); return $query; } /** * Render the component */ public function render() { return view('livewire.review-moderation-component', [ 'reviews' => $this->getReviewsQuery()->paginate(10), 'totalPending' => Review::where('status', ReviewStatus::PENDING)->count(), ]); } }