From afa92d8f4afb1373a64fcc79a2372e092c81a95a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Cmit=20Tun=C3=A7?= Date: Mon, 25 May 2026 06:01:35 +0300 Subject: [PATCH] feat: implement premium blog search and filter UI with improved layout and dynamic post loading. --- app/Http/Controllers/BlogController.php | 10 + public/assets/js/theme.js | 20 +- resources/views/blog/index.blade.php | 238 +++++++++++++++++++++--- 3 files changed, 232 insertions(+), 36 deletions(-) diff --git a/app/Http/Controllers/BlogController.php b/app/Http/Controllers/BlogController.php index 5402214..4985442 100644 --- a/app/Http/Controllers/BlogController.php +++ b/app/Http/Controllers/BlogController.php @@ -42,6 +42,16 @@ class BlogController extends Controller $query = $query->whereJsonContains('tags', $request->tag); } + // Search filtresi + if ($query && $request->has('search') && $request->search) { + $search = $request->search; + $query = $query->where(function($q) use ($search) { + $q->where('title', 'like', '%' . $search . '%') + ->orWhere('content', 'like', '%' . $search . '%') + ->orWhere('excerpt', 'like', '%' . $search . '%'); + }); + } + $posts = $query ? $query->latest('published_at')->paginate(12) : collect(); diff --git a/public/assets/js/theme.js b/public/assets/js/theme.js index 7422c5e..6ee5dfa 100644 --- a/public/assets/js/theme.js +++ b/public/assets/js/theme.js @@ -131,6 +131,7 @@ var theme = { if(grids != null) { grids.forEach(g => { var itemgrid = g.querySelector('.isotope'); + if (itemgrid == null) return; var filtersElem = g.querySelector('.isotope-filter'); var buttonGroups = g.querySelectorAll('.isotope-filter'); var iso = new Isotope(itemgrid, { @@ -216,9 +217,11 @@ var theme = { if (top >= offset && top < offset + height) { navLinks.forEach(links => { links.classList.remove('active'); - document.querySelector(`.nav-link.scroll[href*=${id}]`).classList.add('active'); - //[att*=val] Represents an element with the att attribute whose value contains at least one instance of the substring "val". If "val" is the empty string then the selector does not represent anything. }); + let activeLink = document.querySelector(`.nav-link.scroll[href*="${id}"]`); + if (activeLink) { + activeLink.classList.add('active'); + } } }); } @@ -237,11 +240,14 @@ var theme = { e.preventDefault(); this.blur(); const href = this.getAttribute("href"); - const offsetTop = document.querySelector(href).offsetTop; - scroll({ - top: offsetTop, - behavior: "smooth" - }); + const target = document.querySelector(href); + if (target) { + const offsetTop = target.offsetTop; + scroll({ + top: offsetTop, + behavior: "smooth" + }); + } } }, /** diff --git a/resources/views/blog/index.blade.php b/resources/views/blog/index.blade.php index d237594..aae99cf 100644 --- a/resources/views/blog/index.blade.php +++ b/resources/views/blog/index.blade.php @@ -7,7 +7,7 @@ @if(isset($carouselPosts) && $carouselPosts->count() > 0) -
+
@foreach($carouselPosts as $cPost) @@ -21,9 +21,9 @@ $cUrl = route('blog.show', $cPost->slug); @endphp
-
- - {{ $cTitle }} +
+ + {{ $cTitle }}
@if($cCategoryName) @@ -58,7 +58,7 @@
-

+

Merhaba! Biz Trunçgil. Blogumuza hoş geldiniz. Burada web tasarım, yazılım geliştirme ve teknolojik yeniliklere dair ipuçlarını ve deneyimlerimizi paylaşıyoruz.

@@ -71,7 +71,7 @@ // Dynamically select column width based on category count $gridClass = $catCount >= 4 ? 'md:w-6/12 lg:w-3/12 xl:w-3/12' : 'md:w-6/12 lg:w-4/12 xl:w-4/12'; @endphp -
+
@foreach($highlightCategories as $index => $hCat) @php $images = [ @@ -104,26 +104,40 @@
@endif - -
- - -
- - + +
@if(isset($categories) && $categories->count() > 0) -
- +
+ Tümü @foreach($categories as $category) - + {{ $category->name }} @endforeach
@endif + + +
+ + +
+ + +
+
@include('blog.partials.posts')
@@ -219,6 +233,131 @@ @push('styles')