Add
This commit is contained in:
@@ -9,10 +9,21 @@ use Illuminate\View\View;
|
||||
|
||||
class BuyerProfileController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$profiles = BuyerProfile::with('user', 'attachments', 'ratings.user');
|
||||
|
||||
if ($search = $request->string('q')->toString()) {
|
||||
$profiles->where(fn ($query) => $query
|
||||
->where('company_name', 'like', "%{$search}%")
|
||||
->orWhere('headline', 'like', "%{$search}%")
|
||||
->orWhere('service_categories', 'like', "%{$search}%")
|
||||
->orWhere('hiring_regions', 'like', "%{$search}%")
|
||||
);
|
||||
}
|
||||
|
||||
return view('buyers.index', [
|
||||
'profiles' => BuyerProfile::with('user', 'attachments')->latest()->paginate(20),
|
||||
'profiles' => $profiles->latest()->paginate(20)->withQueryString(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -55,7 +66,7 @@ class BuyerProfileController extends Controller
|
||||
public function show(BuyerProfile $buyer): View
|
||||
{
|
||||
return view('buyers.show', [
|
||||
'profile' => $buyer->load('user', 'attachments'),
|
||||
'profile' => $buyer->load('user', 'attachments', 'ratings.user'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class DisputeController extends Controller
|
||||
{
|
||||
public function show(Request $request, Dispute $dispute): View
|
||||
{
|
||||
$dispute->load('workOrder.buyer', 'workOrder.provider', 'openedBy', 'votes.user', 'comments.user', 'attachments');
|
||||
$dispute->load('workOrder.buyer', 'workOrder.provider', 'openedBy', 'votes.user', 'comments.user', 'attachments', 'ratings.user');
|
||||
|
||||
abort_unless(
|
||||
in_array($request->user()->id, [$dispute->workOrder->buyer_id, $dispute->workOrder->provider_id], true)
|
||||
|
||||
@@ -9,10 +9,25 @@ use Illuminate\View\View;
|
||||
|
||||
class JobPostController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$jobs = JobPost::with('buyer.buyerProfile', 'attachments', 'ratings.user');
|
||||
|
||||
if ($search = $request->string('q')->toString()) {
|
||||
$jobs->where(fn ($query) => $query
|
||||
->where('title', 'like', "%{$search}%")
|
||||
->orWhere('service_category', 'like', "%{$search}%")
|
||||
->orWhere('location', 'like', "%{$search}%")
|
||||
->orWhere('scope', 'like', "%{$search}%")
|
||||
);
|
||||
}
|
||||
|
||||
if ($status = $request->string('status')->toString()) {
|
||||
$jobs->where('status', $status);
|
||||
}
|
||||
|
||||
return view('jobs.index', [
|
||||
'jobs' => JobPost::with('buyer.buyerProfile', 'attachments')->latest()->paginate(20),
|
||||
'jobs' => $jobs->latest()->paginate(20)->withQueryString(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -56,7 +71,8 @@ class JobPostController extends Controller
|
||||
'quotes.revisions.user',
|
||||
'workOrder',
|
||||
'attachments',
|
||||
'comments.user'
|
||||
'comments.user',
|
||||
'ratings.user'
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class NotificationController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
{
|
||||
return view('notifications.index', [
|
||||
'notifications' => $request->user()->notifications()->latest()->paginate(30),
|
||||
]);
|
||||
}
|
||||
|
||||
public function markRead(Request $request, string $id): RedirectResponse
|
||||
{
|
||||
$notification = $request->user()->notifications()->whereKey($id)->firstOrFail();
|
||||
$notification->markAsRead();
|
||||
|
||||
return back()->with('status', 'Notification marked read.');
|
||||
}
|
||||
|
||||
public function markAllRead(Request $request): RedirectResponse
|
||||
{
|
||||
$request->user()->unreadNotifications->markAsRead();
|
||||
|
||||
return back()->with('status', 'Notifications marked read.');
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,21 @@ use Illuminate\View\View;
|
||||
|
||||
class ProviderProfileController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$profiles = ProviderProfile::with('user', 'externalImports', 'attachments', 'ratings.user');
|
||||
|
||||
if ($search = $request->string('q')->toString()) {
|
||||
$profiles->where(fn ($query) => $query
|
||||
->where('business_name', 'like', "%{$search}%")
|
||||
->orWhere('headline', 'like', "%{$search}%")
|
||||
->orWhere('service_area', 'like', "%{$search}%")
|
||||
->orWhere('skills', 'like', "%{$search}%")
|
||||
);
|
||||
}
|
||||
|
||||
return view('providers.index', [
|
||||
'profiles' => ProviderProfile::with('user', 'externalImports', 'attachments')->latest()->paginate(20),
|
||||
'profiles' => $profiles->latest()->paginate(20)->withQueryString(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -59,7 +70,7 @@ class ProviderProfileController extends Controller
|
||||
public function show(ProviderProfile $provider): View
|
||||
{
|
||||
return view('providers.show', [
|
||||
'profile' => $provider->load('user', 'externalImports.attachments', 'attachments'),
|
||||
'profile' => $provider->load('user', 'externalImports.attachments', 'attachments', 'ratings.user'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\BuyerProfile;
|
||||
use App\Models\Dispute;
|
||||
use App\Models\JobPost;
|
||||
use App\Models\ProviderProfile;
|
||||
use App\Models\WorkOrder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RatingController extends Controller
|
||||
{
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$data = $request->validate([
|
||||
'rateable_type' => ['required', 'string', 'in:provider_profile,buyer_profile,job_post,work_order,dispute'],
|
||||
'rateable_id' => ['required', 'integer'],
|
||||
'category' => ['required', 'string', 'max:255'],
|
||||
'stars' => ['nullable', 'integer', 'min:1', 'max:5'],
|
||||
'thumbs_up' => ['nullable', 'boolean'],
|
||||
'body' => ['nullable', 'string', 'max:2000'],
|
||||
]);
|
||||
|
||||
abort_if(($data['stars'] ?? null) === null && ! $request->has('thumbs_up'), 422, 'A star rating or thumbs vote is required.');
|
||||
|
||||
$rateable = match ($data['rateable_type']) {
|
||||
'provider_profile' => ProviderProfile::findOrFail($data['rateable_id']),
|
||||
'buyer_profile' => BuyerProfile::findOrFail($data['rateable_id']),
|
||||
'job_post' => JobPost::findOrFail($data['rateable_id']),
|
||||
'work_order' => WorkOrder::findOrFail($data['rateable_id']),
|
||||
'dispute' => Dispute::findOrFail($data['rateable_id']),
|
||||
};
|
||||
|
||||
$this->authorizeRating($request, $rateable);
|
||||
|
||||
$rateable->ratings()->updateOrCreate(
|
||||
[
|
||||
'user_id' => $request->user()->id,
|
||||
'category' => $data['category'],
|
||||
],
|
||||
[
|
||||
'stars' => $data['stars'] ?? null,
|
||||
'thumbs_up' => $request->has('thumbs_up') ? $request->boolean('thumbs_up') : null,
|
||||
'body' => $data['body'] ?? null,
|
||||
]
|
||||
);
|
||||
|
||||
return back()->with('status', 'Rating saved.');
|
||||
}
|
||||
|
||||
private function authorizeRating(Request $request, mixed $rateable): void
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
if ($rateable instanceof ProviderProfile) {
|
||||
abort_if($rateable->user_id === $user->id, 403);
|
||||
abort_unless($user->hasAnyRole(['buyer', 'provider', 'admin']), 403);
|
||||
} elseif ($rateable instanceof BuyerProfile) {
|
||||
abort_if($rateable->user_id === $user->id, 403);
|
||||
abort_unless($user->hasAnyRole(['buyer', 'provider', 'admin']), 403);
|
||||
} elseif ($rateable instanceof JobPost) {
|
||||
abort_unless($user->hasAnyRole(['buyer', 'provider', 'admin']), 403);
|
||||
} elseif ($rateable instanceof WorkOrder) {
|
||||
abort_unless(in_array($user->id, [$rateable->buyer_id, $rateable->provider_id], true) || $user->hasRole('admin'), 403);
|
||||
} elseif ($rateable instanceof Dispute) {
|
||||
abort_unless($user->hasAnyRole(['buyer', 'provider', 'admin']), 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ class WorkOrderController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$orders = WorkOrder::with('jobPost', 'buyer.buyerProfile', 'provider.providerProfile')
|
||||
$orders = WorkOrder::with('jobPost', 'buyer.buyerProfile', 'provider.providerProfile', 'ratings.user')
|
||||
->where(fn ($query) => $query
|
||||
->where('buyer_id', $request->user()->id)
|
||||
->orWhere('provider_id', $request->user()->id)
|
||||
@@ -38,6 +38,7 @@ class WorkOrderController extends Controller
|
||||
'disputes.openedBy',
|
||||
'messages.user',
|
||||
'attachments',
|
||||
'ratings.user',
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user