I’m building a Laravel application (like ProductHunt) and need help implementing **Search & Filtering** for products. Here’s what I need:

---

### **1. Database & Model Setup**
- Assume the `products` table already exists with the following fields:
  - `title` (string)
  - `description` (text)
  - `status` (string: 'pending', 'approved', 'rejected')
  - `category_id` (foreign key)
  - `created_at` (timestamp)
- Ensure the `Product` model has relationships for `category` and `user`.

---

### **2. Search Functionality**
#### **A. Basic Search**
- Implement a search feature to find products by `title` and `description`.
- Use Laravel’s query builder to search for partial matches (e.g., `WHERE title LIKE %search_term% OR description LIKE %search_term%`).
- Add a search form to the homepage (`products.index`):
  - Input field for the search term.
  - Submit button to trigger the search.
  - Display search results in the same view.

#### **B. Advanced Search (Optional)**
- Use **Laravel Scout** with **Algolia** or **Meilisearch** for full-text search (if basic search is insufficient).
- Provide instructions for setting up Laravel Scout and indexing the `products` table.

---

### **3. Filtering Functionality**
#### **A. Category Filtering**
- Add a dropdown or checkboxes to filter products by `category_id`.
- Modify the query to include:
  ```php
  \$products = Product::query()
      ->when(request('category'), function (\$query) {
          \$query->where('category_id', request('category'));
      })
      ->get();
  ```

#### **B. Status Filtering**

Add filters for product status (e.g., 'approved', 'pending').
Example query:

```php
\$products = Product::query()
    ->when(request('status'), function (\$query) {
        \$query->where('status', request('status'));
    })
    ->get();
```

#### **C. Date Filtering**

Add filters for products created within a specific time range (e.g., 'Last Week', 'Last Month', 'All Time').
Example query:

```php
\$products = Product::query()
    ->when(request('date_range'), function (\$query) {
        \$query->where('created_at', '>=', now()->subDays(request('date_range')));
    })
    ->get();
```

#### **D. Popularity Filtering**

Add a filter to sort products by upvote count (e.g., 'Most Popular').
Example query:

```php
\$products = Product::withCount('upvotes')
    ->when(request('sort') === 'popular', function (\$query) {
        \$query->orderBy('upvotes_count', 'desc');
    })
    ->get();
```

### **4. Combined Search & Filtering**

Combine search and filtering in a single query:

```php
\$products = Product::query()
    ->when(request('search'), function (\$query) {
        \$query->where(function (\$subQuery) {
            \$subQuery->where('title', 'like', '%' . request('search') . '%')
                ->orWhere('description', 'like', '%' . request('search') . '%');
        });
    })
    ->when(request('category'), function (\$query) {
        \$query->where('category_id', request('category'));
    })
    ->when(request('status'), function (\$query) {
        \$query->where('status', request('status'));
    })
    ->when(request('sort') === 'popular', function (\$query) {
        \$query->withCount('upvotes')->orderBy('upvotes_count', 'desc');
    })
    ->paginate(10);
```

### **5. Frontend Implementation**
#### **A. Search & Filter Form**

Create a Blade view (products.index) with:

Search input field (bound to request('search')).
Category dropdown (populated from the categories table).
Status filter (radio buttons or dropdown).
Date range filter (dropdown with options: 'Last Week', 'Last Month', 'All Time').
Sorting options (e.g., 'Newest', 'Most Popular').

#### **B. Example Blade Snippet**

```html
<form method="GET" action="{{ route('products.index') }}" class="mb-4">
    <div class="flex gap-4 items-end">
        <div class="flex-1">
            <label for="search" class="block text-sm font-medium text-gray-700">Search</label>
            <input
                type="text"
                name="search"
                id="search"
                value="{{ request('search') }}"
                class="mt-1 block w-full rounded-md border-gray-300 shadow-sm"
                placeholder="Search products..."
            >
        </div>

        <div>
            <label for="category" class="block text-sm font-medium text-gray-700">Category</label>
            <select name="category" id="category" class="mt-1 block rounded-md border-gray-300 shadow-sm">
                <option value="">All Categories</option>
                @foreach(\$categories as \$category)
                    <option value="{{ \$category->id }}" {{ request('category') == \$category->id ? 'selected' : '' }}>
                        {{ \$category->name }}
                    </option>
                @endforeach
            </select>
        </div>

        <div>
            <label for="sort" class="block text-sm font-medium text-gray-700">Sort By</label>
            <select name="sort" id="sort" class="mt-1 block rounded-md border-gray-300 shadow-sm">
                <option value="newest" {{ request('sort') === 'newest' ? 'selected' : '' }}>Newest</option>
                <option value="popular" {{ request('sort') === 'popular' ? 'selected' : '' }}>Most Popular</option>
            </select>
        </div>

        <button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover\:bg-blue-700">
            Apply Filters
        </button>
    </div>
</form>
```

#### **C. Displaying Results**

Loop through the paginated results and display each product:

```php
@forelse(\$products as \$product)
    <div class="border rounded-lg p-4 mb-4">
        <h3 class="font-bold text-lg">{{ \$product->title }}</h3>
        <p class="text-gray-600">{{ Str::limit(\$product->description, 100) }}</p>
        <div class="flex items-center gap-2 mt-2">
            <span class="text-sm text-gray-500">{{ \$product->category->name }}</span>
            <span class="text-sm text-gray-500">{{ \$product->upvotes_count }} upvotes</span>
        </div>
    </div>
@empty
    <p class="text-gray-500">No products found.</p>
@endforelse

{{ \$products->appends(request()->query())->links() }}
```

### **6. Pagination**

Use Laravel’s built-in pagination:

```php
\$products = \$products->paginate(10)->appends(request()->query());
```
Display pagination links in the Blade view (as shown above).

### **7. Testing**

Write tests for:

Search functionality (partial matches for title/description).
Category filtering.
Status filtering.
Date range filtering.
Popularity sorting.
Pagination.


### **8. Example Code Snippets**
Include the following in your response:

Combined search & filtering query (as shown above).
Blade view for the search/filter form.
Blade view for displaying results and pagination.
Controller method for handling the search/filter request.
Test cases for search and filtering.

### **Notes:**

Use Laravel’s query builder for basic search/filtering.
Use Laravel Scout for advanced full-text search (optional).
Assume Tailwind CSS for styling.
Ensure filters are preserved during pagination (use appends(request()->query())).
Optimize queries with withCount('upvotes') to avoid N+1 issues.
