search and filtering
This commit is contained in:
@@ -16,15 +16,27 @@ class ProductController extends Controller
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Product::with(['user', 'category'])
|
||||
->approved()
|
||||
->latest();
|
||||
$validated = $request->validate([
|
||||
'search' => 'nullable|string|max:255',
|
||||
'category' => 'nullable|integer|exists:categories,id',
|
||||
'status' => 'nullable|string|in:pending,approved,rejected',
|
||||
'date_range' => 'nullable|string|in:today,week,month,year',
|
||||
'sort' => 'nullable|string|in:newest,oldest,popular',
|
||||
]);
|
||||
|
||||
if ($request->has('category')) {
|
||||
$query->where('category_id', $request->category);
|
||||
}
|
||||
// Build the query with all filters and search
|
||||
$query = Product::query()
|
||||
->with(['user', 'category'])
|
||||
->approved() // Only show approved products on the public index
|
||||
->search($request->search)
|
||||
->byCategory($request->category)
|
||||
->dateRange($request->date_range)
|
||||
->sortBy($request->sort);
|
||||
|
||||
$products = $query->paginate(12);
|
||||
// Paginate results with query parameters preserved
|
||||
$products = $query->paginate(12)->appends($request->query());
|
||||
|
||||
// Get all categories for the filter dropdown
|
||||
$categories = Category::all();
|
||||
|
||||
return view('products.index', compact('products', 'categories'));
|
||||
|
||||
@@ -139,6 +139,76 @@ class Product extends Model
|
||||
return $query->where('status', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to search products by title and description.
|
||||
*/
|
||||
public function scopeSearch(Builder $query, ?string $search): Builder
|
||||
{
|
||||
if (empty($search)) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
return $query->where(function ($subQuery) use ($search) {
|
||||
$subQuery->where('title', 'like', '%' . $search . '%')
|
||||
->orWhere('description', 'like', '%' . $search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to filter by category.
|
||||
*/
|
||||
public function scopeByCategory(Builder $query, ?int $categoryId): Builder
|
||||
{
|
||||
if (empty($categoryId)) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
return $query->where('category_id', $categoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to filter by date range.
|
||||
*/
|
||||
public function scopeDateRange(Builder $query, ?string $range): Builder
|
||||
{
|
||||
if (empty($range)) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
return match($range) {
|
||||
'today' => $query->whereDate('created_at', today()),
|
||||
'week' => $query->where('created_at', '>=', now()->subWeek()),
|
||||
'month' => $query->where('created_at', '>=', now()->subMonth()),
|
||||
'year' => $query->where('created_at', '>=', now()->subYear()),
|
||||
default => $query,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to sort products by popularity (upvotes count).
|
||||
*/
|
||||
public function scopePopular(Builder $query): Builder
|
||||
{
|
||||
return $query->withCount('upvotes')->orderBy('upvotes_count', 'desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to sort products.
|
||||
*/
|
||||
public function scopeSortBy(Builder $query, ?string $sort): Builder
|
||||
{
|
||||
if (empty($sort)) {
|
||||
return $query->latest();
|
||||
}
|
||||
|
||||
return match($sort) {
|
||||
'popular' => $query->withCount('upvotes')->orderBy('upvotes_count', 'desc'),
|
||||
'oldest' => $query->oldest(),
|
||||
'newest' => $query->latest(),
|
||||
default => $query->latest(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product's thumbnail URL.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user