optimzed lives

master
A1Gard 1 day ago
parent 50e5d053fb
commit 189c246488

@ -242,7 +242,7 @@ class ClientController extends Controller
public function search(Request $request) public function search(Request $request)
{ {
if (isGuestMaxAttemptTry('search', 5, 1)) { if (isGuestMaxAttemptTry('search', 10, 1)) {
return abort(403); return abort(403);
} }
@ -273,6 +273,23 @@ class ClientController extends Controller
return view('client.tag', compact('posts', 'products', 'clips', 'title', 'subtitle','noIndex')); return view('client.tag', compact('posts', 'products', 'clips', 'title', 'subtitle','noIndex'));
} }
public function ajaxSearch(Request $request)
{
$q = trim($request->input('q'));
if (mb_strlen($q) < 3) {
return __('Search word is too short');
}
$q = '%' . $q . '%';
$products = Product::where('status', 1)->where(function ($query) use ($q) {
$query->where('name', 'LIKE', $q)
->orWhere('excerpt', 'LIKE', $q)
->orWhere('description', 'LIKE', $q);
})->paginate(5);
return view('components.search-items',compact('products'));
}
public function group($slug) public function group($slug)
{ {

@ -1,4 +1,6 @@
let defSearchText = '';
window.addEventListener('load', function () { window.addEventListener('load', function () {
defSearchText = document.querySelector('#live-search-data').innerHTML;
document.querySelectorAll('.live-card-show')?.forEach(function (el) { document.querySelectorAll('.live-card-show')?.forEach(function (el) {
el.addEventListener('click', async function (e) { el.addEventListener('click', async function (e) {
e.preventDefault(); e.preventDefault();
@ -14,4 +16,49 @@ window.addEventListener('load', function () {
document.querySelector('#live-card-modal').style.display = 'none'; document.querySelector('#live-card-modal').style.display = 'none';
} }
}); });
});
document.querySelectorAll('.live-search')?.forEach(function (el) {
el.addEventListener('focus', function () {
const rect = this.getBoundingClientRect();
const scrollTop = window.scrollY || document.documentElement.scrollTop; // Get the current scroll position
const scrollLeft = window.scrollX || document.documentElement.scrollLeft; // Get the current scroll position
document.querySelector('#live-search-content').style.left = (rect.left + scrollLeft) + 'px'; // Adjust left position
document.querySelector('#live-search-content').style.top = (rect.bottom + scrollTop) + 'px'; // Adjust top position
document.querySelector('#live-search-content').style.width = rect.width + 'px';
document.querySelector('#live-search-content').style.display = 'block';
})
});
document.querySelectorAll('.live-search')?.forEach(function (el) {
el.addEventListener('keyup', async function (e) {
if (e.code == 'Escape'){
document.querySelector('#live-search-content').style.display = 'none';
return;
}else{
document.querySelector('#live-search-content').style.display = 'block';
}
if (this.value.length > 3){
document.querySelector('#search-ajax-loader').style.display = 'inline-block';
const url = this.closest('form').getAttribute('action');
let response = await axios.post(url,{q: this.value});
document.querySelector('#live-search-data').innerHTML = response.data ;
document.querySelector('#search-ajax-loader').style.display = 'none';
}else{
document.querySelector('#live-search-data').innerHTML = defSearchText;
}
})
});
document.querySelectorAll('.live-search')?.forEach(function (el) {
el.addEventListener('blur', function () {
setTimeout(function () {
document.querySelector('#live-search-content').style.display = 'none';
},500);
});
}) })

@ -1,3 +1,13 @@
@keyframes rotate-z {
from {
transform: rotateZ(0deg);
}
to {
transform: rotateZ(360deg);
}
}
#live-card-modal { #live-card-modal {
display: none; display: none;
position: fixed; position: fixed;
@ -26,17 +36,20 @@
border-radius: var(--xshop-border-radius); border-radius: var(--xshop-border-radius);
border: 1px solid var(--xshop-text); border: 1px solid var(--xshop-text);
margin-bottom: .5rem; margin-bottom: .5rem;
.product-card-item { .product-card-item {
padding: 5px; padding: 5px;
display: grid; display: grid;
grid-template-columns: 4fr 8fr; grid-template-columns: 4fr 8fr;
grid-gap: 5px; grid-gap: 5px;
img { img {
width: 100%; width: 100%;
height: 75px; height: 75px;
object-fit: cover; object-fit: cover;
border-radius: var(--xshop-border-radius);
} }
h3 { h3 {
font-size: 18px; font-size: 18px;
margin: .5rem 0; margin: .5rem 0;
@ -46,3 +59,46 @@
} }
} }
} }
#live-search-content {
display: none;
background: var(--xshop-background);
padding: 1rem ;
position: absolute;
z-index: 9999;
top: 50px;
left: 0;
border-radius: var(--xshop-border-radius);
li {
list-style: none;
border-radius: var(--xshop-border-radius);
border: 1px solid var(--xshop-text);
margin-bottom: .5rem;
.product-search-item {
padding: 5px;
display: grid;
grid-template-columns: 4fr 8fr;
grid-gap: 5px;
img {
width: 100%;
height: 75px;
object-fit: cover;
border-radius: var(--xshop-border-radius);
}
h3 {
font-size: 18px;
margin: .5rem 0;
}
}
}
#search-ajax-loader{
animation: rotate-z 1s linear infinite;
display: none;
font-size: 45px;
}
}

@ -1,3 +1,4 @@
@if(isJson(\Cookie::get('card')))
@foreach(\App\Models\Product::whereIn('id', json_decode(\Cookie::get('card'), true)) @foreach(\App\Models\Product::whereIn('id', json_decode(\Cookie::get('card'), true))
->where('status', 1) ->where('status', 1)
->get() as $product) ->get() as $product)
@ -20,3 +21,4 @@
</li> </li>
@endforeach @endforeach
@endif

@ -1,12 +1,4 @@
@keyframes rotate-z {
from {
transform: rotateZ(0deg);
}
to {
transform: rotateZ(360deg);
}
}
.DowntownSlider { .DowntownSlider {
position: relative; position: relative;

@ -23,5 +23,13 @@
</div> </div>
</div> </div>
</div> </div>
<div id="live-search-content">
<div id="live-search-data">
{{__("You need to type at least 4 characters to perform a search...")}}
</div>
<div class="text-center">
<i class="ri-loader-4-line" id="search-ajax-loader"></i>
</div>
</div>
</body> </body>
</html> </html>

@ -442,6 +442,7 @@ Route::middleware([\App\Http\Middleware\VisitorCounter::class])
Route::get('/video/{clip}', [ClientController::class, 'clip'])->name('clip'); Route::get('/video/{clip}', [ClientController::class, 'clip'])->name('clip');
Route::get('/category/{category}', [ClientController::class, 'category'])->name('category'); Route::get('/category/{category}', [ClientController::class, 'category'])->name('category');
Route::get('/gallery/{gallery}', [ClientController::class, 'gallery'])->name('gallery'); Route::get('/gallery/{gallery}', [ClientController::class, 'gallery'])->name('gallery');
Route::post('/search', [ClientController::class, 'ajaxSearch'])->name('search.ajax');
Route::get('/search', [ClientController::class, 'search'])->name('search'); Route::get('/search', [ClientController::class, 'search'])->name('search');
Route::get('attach/download/{attachment}', [ClientController::class, 'attachDl'])->name('attach-dl'); Route::get('attach/download/{attachment}', [ClientController::class, 'attachDl'])->name('attach-dl');
Route::get('pay/{invoice}', [ClientController::class, 'pay'])->name('pay'); Route::get('pay/{invoice}', [ClientController::class, 'pay'])->name('pay');

Loading…
Cancel
Save