144 lines
5.4 KiB
PHP
144 lines
5.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Client;
|
|
use App\Models\ContentBrief;
|
|
use App\Models\Event;
|
|
use App\Models\Invoice;
|
|
use App\Models\RateCard;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
|
|
class SearchController extends Controller
|
|
{
|
|
public function index(Request $request): View
|
|
{
|
|
$q = trim($request->get('q', ''));
|
|
$results = $q ? $this->search($q) : [];
|
|
|
|
return view('search.index', compact('q', 'results'));
|
|
}
|
|
|
|
/** Quick AJAX endpoint — returns grouped results for the dropdown */
|
|
public function quick(Request $request): JsonResponse
|
|
{
|
|
$q = trim($request->get('q', ''));
|
|
|
|
if (strlen($q) < 2) {
|
|
return response()->json([]);
|
|
}
|
|
|
|
return response()->json($this->search($q, limit: 5));
|
|
}
|
|
|
|
private function search(string $q, int $limit = 20): array
|
|
{
|
|
$groups = [];
|
|
$like = "%{$q}%";
|
|
|
|
// ── Clients ──────────────────────────────────────────────
|
|
$clients = Client::where('name', 'LIKE', $like)
|
|
->orWhere('email', 'LIKE', $like)
|
|
->orWhere('company', 'LIKE', $like)
|
|
->orWhere('ig_handle', 'LIKE', $like)
|
|
->orWhere('tiktok_handle', 'LIKE', $like)
|
|
->limit($limit)->get();
|
|
|
|
if ($clients->isNotEmpty()) {
|
|
$groups[] = [
|
|
'type' => 'clients',
|
|
'label' => '👥 Clients',
|
|
'items' => $clients->map(fn ($c) => [
|
|
'icon' => '👥',
|
|
'title' => $c->name,
|
|
'subtitle' => collect([$c->company, $c->email])->filter()->implode(' · '),
|
|
'url' => route('clients.show', $c),
|
|
])->values()->all(),
|
|
];
|
|
}
|
|
|
|
// ── Events ───────────────────────────────────────────────
|
|
$events = Event::with('client')
|
|
->where('title', 'LIKE', $like)
|
|
->orWhere('description', 'LIKE', $like)
|
|
->orWhere('location', 'LIKE', $like)
|
|
->limit($limit)->get();
|
|
|
|
if ($events->isNotEmpty()) {
|
|
$groups[] = [
|
|
'type' => 'events',
|
|
'label' => '📅 Events',
|
|
'items' => $events->map(fn ($e) => [
|
|
'icon' => '📅',
|
|
'title' => $e->title,
|
|
'subtitle' => $e->start_time->format('d M Y') . ($e->client ? ' · ' . $e->client->name : ''),
|
|
'url' => route('schedule.index'),
|
|
])->values()->all(),
|
|
];
|
|
}
|
|
|
|
// ── Invoices ─────────────────────────────────────────────
|
|
$invoices = Invoice::with('client')
|
|
->where('invoice_number', 'LIKE', $like)
|
|
->orWhere('title', 'LIKE', $like)
|
|
->limit($limit)->get();
|
|
|
|
if ($invoices->isNotEmpty()) {
|
|
$groups[] = [
|
|
'type' => 'invoices',
|
|
'label' => '🧾 Invoices',
|
|
'items' => $invoices->map(fn ($i) => [
|
|
'icon' => '🧾',
|
|
'title' => $i->invoice_number . ($i->title ? ' — ' . $i->title : ''),
|
|
'subtitle' => ($i->client?->name ?? '') . ' · ' . ($i->formatted_total ?? ''),
|
|
'url' => route('invoices.show', $i),
|
|
])->values()->all(),
|
|
];
|
|
}
|
|
|
|
// ── Content Briefs ───────────────────────────────────────
|
|
$content = ContentBrief::with('client')
|
|
->where('title', 'LIKE', $like)
|
|
->orWhere('description', 'LIKE', $like)
|
|
->orWhere('platform', 'LIKE', $like)
|
|
->limit($limit)->get();
|
|
|
|
if ($content->isNotEmpty()) {
|
|
$groups[] = [
|
|
'type' => 'content',
|
|
'label' => '🎬 Content',
|
|
'items' => $content->map(fn ($c) => [
|
|
'icon' => $c->platform_icon ?? '🎬',
|
|
'title' => $c->title,
|
|
'subtitle' => ucfirst($c->platform) . ($c->client ? ' · ' . $c->client->name : ''),
|
|
'url' => route('content.show', $c),
|
|
])->values()->all(),
|
|
];
|
|
}
|
|
|
|
// ── Rate Cards ───────────────────────────────────────────
|
|
$rateCards = RateCard::where('service_name', 'LIKE', $like)
|
|
->orWhere('description', 'LIKE', $like)
|
|
->limit($limit)->get();
|
|
|
|
if ($rateCards->isNotEmpty()) {
|
|
$groups[] = [
|
|
'type' => 'rate-cards',
|
|
'label' => '💰 Rate Cards',
|
|
'items' => $rateCards->map(fn ($r) => [
|
|
'icon' => '💰',
|
|
'title' => $r->service_name,
|
|
'subtitle' => $r->description ?? '',
|
|
'url' => route('rate-cards.edit', $r),
|
|
])->values()->all(),
|
|
];
|
|
}
|
|
|
|
return $groups;
|
|
}
|
|
}
|