diff --git a/app/Livewire/Discover/Search.php b/app/Livewire/Discover/Search.php new file mode 100644 index 0000000..ee4637f --- /dev/null +++ b/app/Livewire/Discover/Search.php @@ -0,0 +1,71 @@ +resetPage(); + } + + public function updatingTld(): void + { + $this->resetPage(); + } + + public function render(): View + { + $keyword = trim($this->keyword); + $tld = strtolower(trim(ltrim($this->tld, '.'))); + $hasQuery = $keyword !== '' || $tld !== ''; + + // Without any filter this would just be the full site list — that's what the + // Sites page is for. Discover only returns results once you've asked it something. + if (! $hasQuery) { + $sites = new LengthAwarePaginator([], 0, 25, 1, ['path' => request()->url()]); + } else { + $sites = Site::query() + ->when( + $keyword !== '', + fn ($query) => $query->whereHas( + 'pages', + fn ($pageQuery) => $pageQuery->whereFullText(['title', 'description', 'keywords', 'content'], $keyword) + ) + ) + ->when($tld !== '', fn ($query) => $query->where('domain', 'like', '%.'.$tld)) + ->withCount(['pages as matching_pages_count' => function ($pageQuery) use ($keyword) { + if ($keyword !== '') { + $pageQuery->whereFullText(['title', 'description', 'keywords', 'content'], $keyword); + } + }]) + ->orderByDesc('matching_pages_count') + ->orderBy('domain') + ->paginate(25); + } + + return view('livewire.discover.search', ['sites' => $sites, 'hasQuery' => $hasQuery]); + } +} diff --git a/database/migrations/2026_07_22_211812_add_fulltext_index_to_site_pages_table.php b/database/migrations/2026_07_22_211812_add_fulltext_index_to_site_pages_table.php new file mode 100644 index 0000000..705b7cc --- /dev/null +++ b/database/migrations/2026_07_22_211812_add_fulltext_index_to_site_pages_table.php @@ -0,0 +1,29 @@ +fullText(['title', 'description', 'keywords', 'content']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('site_pages', function (Blueprint $table) { + $table->dropFullText(['title', 'description', 'keywords', 'content']); + }); + } +}; diff --git a/resources/views/components/layouts/app.blade.php b/resources/views/components/layouts/app.blade.php index aeadc57..a2bcd2f 100644 --- a/resources/views/components/layouts/app.blade.php +++ b/resources/views/components/layouts/app.blade.php @@ -11,8 +11,12 @@
+ Find sites by what they sell and where — e.g. keyword "honey", TLD "es". +
+ +| Domain | +Title | +Matching pages | +
|---|---|---|
| + + {{ $site->domain }} + + | +{{ $site->title ?? '—' }} | +{{ $site->matching_pages_count }} | +
| + @if ($hasQuery) + No matching sites. + @else + Enter a keyword or TLD to search. + @endif + | +||