optimzed lives

master
A1Gard 1 day ago
parent 50e5d053fb
commit 189c246488

@ -242,7 +242,7 @@ class ClientController extends Controller
public function search(Request $request)
{
if (isGuestMaxAttemptTry('search', 5, 1)) {
if (isGuestMaxAttemptTry('search', 10, 1)) {
return abort(403);
}
@ -273,7 +273,24 @@ class ClientController extends Controller
return view('client.tag', compact('posts', 'products', 'clips', 'title', 'subtitle','noIndex'));
}
public function group($slug)
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)
{
$group = Group::where('slug', $slug)->firstOrFail();
@ -906,6 +923,6 @@ class ClientController extends Controller
}
public function cardItems(){
}
}

@ -1,4 +1,6 @@
let defSearchText = '';
window.addEventListener('load', function () {
defSearchText = document.querySelector('#live-search-data').innerHTML;
document.querySelectorAll('.live-card-show')?.forEach(function (el) {
el.addEventListener('click', async function (e) {
e.preventDefault();
@ -9,9 +11,54 @@ window.addEventListener('load', function () {
});
});
document.querySelector('#live-card-modal').addEventListener('click',function (e) {
if (e.target == this){
document.querySelector('#live-card-modal').addEventListener('click', function (e) {
if (e.target == this) {
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,4 +1,14 @@
#live-card-modal{
@keyframes rotate-z {
from {
transform: rotateZ(0deg);
}
to {
transform: rotateZ(360deg);
}
}
#live-card-modal {
display: none;
position: fixed;
top: 0;
@ -9,7 +19,7 @@
backdrop-filter: blur(7px);
z-index: 9999;
#live-card-container{
#live-card-container {
background: var(--xshop-background);
width: 300px;
padding: 1rem;
@ -17,32 +27,78 @@
overflow-y: auto;
max-width: 85%;
#live-card-list{
#live-card-list {
margin: 0;
list-style: none;
padding: 1rem 0;
li{
li {
border-radius: var(--xshop-border-radius);
border: 1px solid var(--xshop-text);
margin-bottom: .5rem;
.product-card-item{
.product-card-item {
padding: 5px;
display: grid;
grid-template-columns: 4fr 8fr;
grid-gap: 5px;
img{
img {
width: 100%;
height: 75px;
object-fit: cover;
border-radius: var(--xshop-border-radius);
}
h3{
h3 {
font-size: 18px;
margin: .5rem 0 ;
margin: .5rem 0;
}
}
}
}
}
}
#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,6 +1,7 @@
@foreach(\App\Models\Product::whereIn('id', json_decode(\Cookie::get('card'), true))
->where('status', 1)
->get() as $product)
@if(isJson(\Cookie::get('card')))
@foreach(\App\Models\Product::whereIn('id', json_decode(\Cookie::get('card'), true))
->where('status', 1)
->get() as $product)
<li>
<div class="product-card-item">
<img src="{{$product->imgUrl()}}" alt="{{$product->name}}">
@ -19,4 +20,5 @@
</div>
</li>
@endforeach
@endforeach
@endif

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

@ -1,27 +1,35 @@
</div>
@yield('custom-foot')
<input type="hidden" id="api-display-url" value="{{route('v1.visitor.display')}}">
<input type="hidden" id="api-fav-toggle" value="{{route('client.product-fav-toggle','')}}/">
<input type="hidden" id="api-compare-toggle" value="{{route('client.product-compare-toggle','')}}/">
</div>
@yield('custom-foot')
<input type="hidden" id="api-display-url" value="{{route('v1.visitor.display')}}">
<input type="hidden" id="api-fav-toggle" value="{{route('client.product-fav-toggle','')}}/">
<input type="hidden" id="api-compare-toggle" value="{{route('client.product-compare-toggle','')}}/">
@if(auth()->check() && (auth()->user()->hasRole('developer') || auth()->user()->hasRole('admin')))
<a id="do-edit" data-bs-custom-class="custom-tooltip"
data-bs-toggle="tooltip" data-bs-placement="auto"
title="{{__("Customize theme")}}">
<i class="ri-settings-2-line"></i>
</a>
<input type="hidden" id="live-url" value="{{route('admin.setting.live','')}}/">
@endif
<div id="live-card-modal">
<div id="live-card-container">
<a href="{{ route('client.card') }}" class="btn btn-outline-primary d-block">
<i class="ri-shopping-bag-2-line"></i>
{{__("Go to card")}}
</a>
<div id="live-card-list">
@include('components.card-items')
@if(auth()->check() && (auth()->user()->hasRole('developer') || auth()->user()->hasRole('admin')))
<a id="do-edit" data-bs-custom-class="custom-tooltip"
data-bs-toggle="tooltip" data-bs-placement="auto"
title="{{__("Customize theme")}}">
<i class="ri-settings-2-line"></i>
</a>
<input type="hidden" id="live-url" value="{{route('admin.setting.live','')}}/">
@endif
<div id="live-card-modal">
<div id="live-card-container">
<a href="{{ route('client.card') }}" class="btn btn-outline-primary d-block">
<i class="ri-shopping-bag-2-line"></i>
{{__("Go to card")}}
</a>
<div id="live-card-list">
@include('components.card-items')
</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>
</div>
</body>
</html>

@ -442,6 +442,7 @@ Route::middleware([\App\Http\Middleware\VisitorCounter::class])
Route::get('/video/{clip}', [ClientController::class, 'clip'])->name('clip');
Route::get('/category/{category}', [ClientController::class, 'category'])->name('category');
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('attach/download/{attachment}', [ClientController::class, 'attachDl'])->name('attach-dl');
Route::get('pay/{invoice}', [ClientController::class, 'pay'])->name('pay');

Loading…
Cancel
Save