search
This commit is contained in:
parent
c71b7ff5c2
commit
c7eba16c5f
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Items;
|
||||||
|
use App\Models\StoreCategory;
|
||||||
|
use App\Models\Gender;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class SearchController extends Controller
|
||||||
|
{
|
||||||
|
public function search(Request $request)
|
||||||
|
{
|
||||||
|
$query = $request->get('q');
|
||||||
|
|
||||||
|
if (empty($query) || strlen($query) < 2) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'results' => [],
|
||||||
|
'message' => 'Please enter at least 2 characters'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search products
|
||||||
|
$products = Items::where('is_publish', true)
|
||||||
|
->where('deleted_at', null)
|
||||||
|
->where(function($q) use ($query) {
|
||||||
|
$q->where('name', 'ILIKE', "%{$query}%")
|
||||||
|
->orWhere('number', 'ILIKE', "%{$query}%")
|
||||||
|
->orWhere('description', 'ILIKE', "%{$query}%");
|
||||||
|
})
|
||||||
|
->select('id', 'name', 'number', 'slug')
|
||||||
|
->limit(8)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Search categories
|
||||||
|
$categories = StoreCategory::where('name', 'ILIKE', "%{$query}%")
|
||||||
|
->select('id', 'name')
|
||||||
|
->limit(3)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Search genders
|
||||||
|
$genders = Gender::where('name', 'ILIKE', "%{$query}%")
|
||||||
|
->select('id', 'name')
|
||||||
|
->limit(3)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Format results
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
if ($products->isNotEmpty()) {
|
||||||
|
$results['products'] = $products->map(function($product) {
|
||||||
|
$price = $product->display_price;
|
||||||
|
return [
|
||||||
|
'id' => $product->id,
|
||||||
|
'name' => $product->name,
|
||||||
|
'number' => $product->number,
|
||||||
|
'slug' => $product->slug ?? $product->id,
|
||||||
|
'type' => 'product',
|
||||||
|
'route' => route('product.detail', $product->slug)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($categories->isNotEmpty()) {
|
||||||
|
$results['categories'] = $categories->map(function($category) {
|
||||||
|
return [
|
||||||
|
'id' => $category->id,
|
||||||
|
'name' => $category->name,
|
||||||
|
'slug' => $category->slug,
|
||||||
|
'type' => 'category',
|
||||||
|
'route' => route('product.index',['filter[category]'=>$category->id])
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($genders->isNotEmpty()) {
|
||||||
|
$results['genders'] = $genders->map(function($gender) {
|
||||||
|
return [
|
||||||
|
'id' => $gender->id,
|
||||||
|
'name' => $gender->name,
|
||||||
|
'slug' => $gender->slug,
|
||||||
|
'type' => 'gender',
|
||||||
|
'route' => route('product.index',['filter[gender]'=>$gender->id])
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'results' => $results,
|
||||||
|
'query' => $query
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -39,21 +39,29 @@ class ProductRepository
|
||||||
|
|
||||||
$where_ids = [];
|
$where_ids = [];
|
||||||
if ($price_range_start && $price_range_end) {
|
if ($price_range_start && $price_range_end) {
|
||||||
$params_filter = [];
|
$params_filter = [
|
||||||
$params_filter['location_id'] = $location_id;
|
'location_id' => $location_id,
|
||||||
$params_filter['price_range_start'] = $price_range_start;
|
'price_range_start' => $price_range_start,
|
||||||
$params_filter['price_range_end'] = $price_range_end;
|
'price_range_end' => $price_range_end,
|
||||||
|
];
|
||||||
|
|
||||||
$where_ids = collect($this->getProductList($params_filter))->pluck('id')->toArray();
|
$where_ids = collect($this->getProductList($params_filter))
|
||||||
|
->pluck('id')
|
||||||
|
->unique()
|
||||||
|
->values()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
if (! empty($sorting_ids) && count($sorting_ids) > 0) {
|
// Jika sudah ada sorting_ids → ikuti urutannya
|
||||||
$where_ids = array_values(
|
if (!empty($sorting_ids)) {
|
||||||
array_intersect($sorting_ids, $where_ids)
|
$sorting_ids = array_values(array_intersect($sorting_ids, $where_ids));
|
||||||
);
|
} else {
|
||||||
|
// kalau belum ada sorting, pakai hasil filter
|
||||||
|
$sorting_ids = $where_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$builder = Items::select('items.*', 'percent')
|
$builder = Items::select('items.*', 'percent')
|
||||||
->leftJoin('item_dimension', 'item_dimension.no', 'items.number')
|
->leftJoin('item_dimension', 'item_dimension.no', 'items.number')
|
||||||
->leftJoin(DB::raw("(select distinct on (item_id) item_id, percent, discounts.created_at,
|
->leftJoin(DB::raw("(select distinct on (item_id) item_id, percent, discounts.created_at,
|
||||||
|
|
@ -73,20 +81,18 @@ class ProductRepository
|
||||||
$query->orderBy('percent', 'desc');
|
$query->orderBy('percent', 'desc');
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (! empty($sorting_ids) && count($sorting_ids) > 0) {
|
if (!empty($sorting_ids)) {
|
||||||
|
|
||||||
$caseStatements = [];
|
$cases = collect($sorting_ids)->map(function ($id, $index) {
|
||||||
foreach ($sorting_ids as $index => $id) {
|
return "WHEN items.id = {$id} THEN {$index}";
|
||||||
$caseStatements[] = "WHEN items.id = {$id} THEN " . ($index + 1);
|
})->implode(' ');
|
||||||
}
|
|
||||||
$caseStatements[] = "ELSE 999";
|
|
||||||
|
|
||||||
$query->orderByRaw("
|
$query->orderByRaw("
|
||||||
CASE
|
CASE
|
||||||
" . implode("\n ", $caseStatements) . "
|
{$cases}
|
||||||
END ASC
|
ELSE 999999
|
||||||
|
END
|
||||||
");
|
");
|
||||||
|
|
||||||
} elseif ($sort == 'new') {
|
} elseif ($sort == 'new') {
|
||||||
$query->orderByRaw("case when category1 in ('CLUBS','CLUB','COMPONENT HEAD') and brand = 'PXG' then 1 else 2 end ASC");
|
$query->orderByRaw("case when category1 in ('CLUBS','CLUB','COMPONENT HEAD') and brand = 'PXG' then 1 else 2 end ASC");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -113,8 +119,8 @@ class ProductRepository
|
||||||
->when($event, function ($query) use ($event) {
|
->when($event, function ($query) use ($event) {
|
||||||
$query->where('d.event', $event);
|
$query->where('d.event', $event);
|
||||||
})
|
})
|
||||||
->when($where_ids, function ($query) use ($where_ids) {
|
->when($sorting_ids, function ($query) use ($sorting_ids) {
|
||||||
$query->whereIn('items.id', $where_ids);
|
$query->whereIn('items.id', $sorting_ids);
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($category_id) {
|
if ($category_id) {
|
||||||
|
|
@ -159,6 +165,7 @@ class ProductRepository
|
||||||
$order_by = 'ORDER BY items.created_at DESC NULLS LAST';
|
$order_by = 'ORDER BY items.created_at DESC NULLS LAST';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$location_id = $params['location_id'] ?? null;
|
$location_id = $params['location_id'] ?? null;
|
||||||
|
|
||||||
// =========================
|
// =========================
|
||||||
|
|
@ -210,13 +217,13 @@ class ProductRepository
|
||||||
AND (d.valid_at IS NULL OR d.valid_at <= NOW())
|
AND (d.valid_at IS NULL OR d.valid_at <= NOW())
|
||||||
AND (d.expired_at IS NULL OR d.expired_at >= NOW())
|
AND (d.expired_at IS NULL OR d.expired_at >= NOW())
|
||||||
AND (
|
AND (
|
||||||
(22 IS NOT NULL AND (d.location_id = 22 OR d.location_id IS NULL))
|
($location_id IS NOT NULL AND (d.location_id = $location_id OR d.location_id IS NULL))
|
||||||
OR (22 IS NULL AND d.location_id IS NULL)
|
OR ($location_id IS NULL AND d.location_id IS NULL)
|
||||||
)
|
)
|
||||||
ORDER BY
|
ORDER BY
|
||||||
di.item_reference_id,
|
di.item_reference_id,
|
||||||
CASE
|
CASE
|
||||||
WHEN d.location_id = 22 THEN 1
|
WHEN d.location_id = $location_id THEN 1
|
||||||
ELSE 2
|
ELSE 2
|
||||||
END,
|
END,
|
||||||
d.created_at DESC
|
d.created_at DESC
|
||||||
|
|
@ -237,13 +244,13 @@ class ProductRepository
|
||||||
AND (d.valid_at IS NULL OR d.valid_at <= NOW())
|
AND (d.valid_at IS NULL OR d.valid_at <= NOW())
|
||||||
AND (d.expired_at IS NULL OR d.expired_at >= NOW())
|
AND (d.expired_at IS NULL OR d.expired_at >= NOW())
|
||||||
AND (
|
AND (
|
||||||
(22 IS NOT NULL AND (d.location_id = 22 OR d.location_id IS NULL))
|
($location_id IS NOT NULL AND (d.location_id = $location_id OR d.location_id IS NULL))
|
||||||
OR (22 IS NULL AND d.location_id IS NULL)
|
OR ($location_id IS NULL AND d.location_id IS NULL)
|
||||||
)
|
)
|
||||||
ORDER BY
|
ORDER BY
|
||||||
di.item_reference_id,
|
di.item_reference_id,
|
||||||
CASE
|
CASE
|
||||||
WHEN d.location_id = 22 THEN 1
|
WHEN d.location_id = $location_id THEN 1
|
||||||
ELSE 2
|
ELSE 2
|
||||||
END,
|
END,
|
||||||
d.created_at DESC
|
d.created_at DESC
|
||||||
|
|
|
||||||
|
|
@ -130,25 +130,18 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{-- search box --}}
|
||||||
<div class="offcanvas offcanvas-top" id="searchBox" data-bs-backdrop="static" tabindex="-1">
|
<div class="offcanvas offcanvas-top" id="searchBox" data-bs-backdrop="static" tabindex="-1">
|
||||||
<div class="offcanvas-header border-bottom p-0 py-lg-1">
|
<div class="offcanvas-header border-bottom p-0 py-lg-1">
|
||||||
<form class="container d-flex align-items-center">
|
<form class="container d-flex align-items-center">
|
||||||
<input type="search" class="form-control form-control-lg fs-lg border-0 rounded-0 py-3 ps-0"
|
<input type="search" id="searchInput" class="form-control form-control-lg fs-lg border-0 rounded-0 py-3 ps-0"
|
||||||
placeholder="Search the products" data-autofocus="offcanvas">
|
placeholder="Search the products" data-autofocus="offcanvas">
|
||||||
<button type="reset" class="btn-close fs-lg" data-bs-dismiss="offcanvas"
|
<button type="reset" class="btn-close fs-lg" data-bs-dismiss="offcanvas"
|
||||||
aria-label="Close"></button>
|
aria-label="Close"></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="offcanvas-body px-0">
|
<div class="offcanvas-body px-0 show_result" id="searchResults">
|
||||||
<div class="container text-center">
|
<!-- Search results will be loaded here -->
|
||||||
<svg class="text-body-tertiary opacity-60 mb-4" xmlns="http://www.w3.org/2000/svg" width="60"
|
|
||||||
viewBox="0 0 512 512" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M340.115,361.412l-16.98-16.98c-34.237,29.36-78.733,47.098-127.371,47.098C87.647,391.529,0,303.883,0,195.765S87.647,0,195.765,0s195.765,87.647,195.765,195.765c0,48.638-17.738,93.134-47.097,127.371l16.98,16.98l11.94-11.94c5.881-5.881,15.415-5.881,21.296,0l112.941,112.941c5.881,5.881,5.881,15.416,0,21.296l-45.176,45.176c-5.881,5.881-15.415,5.881-21.296,0L328.176,394.648c-5.881-5.881-5.881-15.416,0-21.296L340.115,361.412z M195.765,361.412c91.484,0,165.647-74.163,165.647-165.647S287.249,30.118,195.765,30.118S30.118,104.28,30.118,195.765S104.28,361.412,195.765,361.412z M360.12,384l91.645,91.645l23.88-23.88L384,360.12L360.12,384z M233.034,233.033c5.881-5.881,15.415-5.881,21.296,0c5.881,5.881,5.881,15.416,0,21.296c-32.345,32.345-84.786,32.345-117.131,0c-5.881-5.881-5.881-15.415,0-21.296c5.881-5.881,15.416-5.881,21.296,0C179.079,253.616,212.45,253.616,233.034,233.033zM135.529,180.706c-12.475,0-22.588-10.113-22.588-22.588c0-12.475,10.113-22.588,22.588-22.588c12.475,0,22.588,10.113,22.588,22.588C158.118,170.593,148.005,180.706,135.529,180.706z M256,180.706c-12.475,0-22.588-10.113-22.588-22.588c0-12.475,10.113-22.588,22.588-22.588s22.588,10.113,22.588,22.588C278.588,170.593,268.475,180.706,256,180.706z" />
|
|
||||||
</svg>
|
|
||||||
<h6 class="mb-2">Your search results will appear here</h6>
|
|
||||||
<p class="fs-sm mb-0">Start typing in the search field above to see instant search results.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -362,3 +355,174 @@
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const searchInput = document.getElementById('searchInput');
|
||||||
|
const searchResults = document.getElementById('searchResults');
|
||||||
|
let searchTimeout;
|
||||||
|
|
||||||
|
if (searchInput && searchResults) {
|
||||||
|
// Show default state initially
|
||||||
|
showDefaultSearch();
|
||||||
|
|
||||||
|
// Handle search input with debouncing
|
||||||
|
searchInput.addEventListener('input', function() {
|
||||||
|
clearTimeout(searchTimeout);
|
||||||
|
const query = this.value.trim();
|
||||||
|
|
||||||
|
if (query.length < 2) {
|
||||||
|
showDefaultSearch();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debounce search
|
||||||
|
searchTimeout = setTimeout(() => {
|
||||||
|
performSearch(query);
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear search when input is cleared
|
||||||
|
searchInput.addEventListener('reset', function() {
|
||||||
|
showDefaultSearch();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showDefaultSearch() {
|
||||||
|
searchResults.innerHTML = `
|
||||||
|
<div class="container text-center py-5">
|
||||||
|
<svg class="text-body-tertiary opacity-60 mb-4" xmlns="http://www.w3.org/2000/svg" width="60"
|
||||||
|
viewBox="0 0 512 512" fill="currentColor">
|
||||||
|
<path d="M340.115,361.412l-16.98-16.98c-34.237,29.36-78.733,47.098-127.371,47.098C87.647,391.529,0,303.883,0,195.765S87.647,0,195.765,0s195.765,87.647,195.765,195.765c0,48.638-17.738,93.134-47.097,127.371l16.98,16.98l11.94-11.94c5.881-5.881,15.415-5.881,21.296,0l112.941,112.941c5.881,5.881,5.881,15.416,0,21.296l-45.176,45.176c-5.881,5.881-15.415,5.881-21.296,0L328.176,394.648c-5.881-5.881-5.881-15.416,0-21.296L340.115,361.412z M195.765,361.412c91.484,0,165.647-74.163,165.647-165.647S287.249,30.118,195.765,30.118S30.118,104.28,30.118,195.765S104.28,361.412,195.765,361.412z M360.12,384l91.645,91.645l23.88-23.88L384,360.12L360.12,384z M233.034,233.033c5.881-5.881,15.415-5.881,21.296,0c5.881,5.881,5.881,15.416,0,21.296c-32.345,32.345-84.786,32.345-117.131,0c-5.881-5.881-5.881-15.415,0-21.296c5.881-5.881,15.416-5.881,21.296,0C179.079,253.616,212.45,253.616,233.034,233.033zM135.529,180.706c-12.475,0-22.588-10.113-22.588-22.588c0-12.475,10.113-22.588,22.588-22.588c12.475,0,22.588,10.113,22.588,22.588C158.118,170.593,148.005,180.706,135.529,180.706z M256,180.706c-12.475,0-22.588-10.113-22.588-22.588c0-12.475,10.113-22.588,22.588-22.588s22.588,10.113,22.588,22.588C278.588,170.593,268.475,180.706,256,180.706z" />
|
||||||
|
</svg>
|
||||||
|
<h6 class="mb-2">Your search results will appear here</h6>
|
||||||
|
<p class="fs-sm mb-0">Start typing in the search field above to see instant search results.</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function performSearch(query) {
|
||||||
|
// Show loading state
|
||||||
|
searchResults.innerHTML = `
|
||||||
|
<div class="container text-center py-5">
|
||||||
|
<div class="spinner-border text-primary" role="status">
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div>
|
||||||
|
<p class="mt-3 mb-0">Searching...</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
fetch(`{{ route('search.ajax') }}?q=${encodeURIComponent(query)}`, {
|
||||||
|
headers: {
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
displaySearchResults(data.results, data.query);
|
||||||
|
} else {
|
||||||
|
showError('Search failed. Please try again.');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Search error:', error);
|
||||||
|
showError('Search failed. Please try again.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function displaySearchResults(results, query) {
|
||||||
|
let html = '<div class="container py-4">';
|
||||||
|
|
||||||
|
// Products section
|
||||||
|
if (results.products && results.products.length > 0) {
|
||||||
|
html += `
|
||||||
|
<div class="mb-4">
|
||||||
|
<h6 class="text-uppercase fs-xs fw-bold mb-3">Products</h6>
|
||||||
|
<div class="row g-3">
|
||||||
|
`;
|
||||||
|
|
||||||
|
results.products.forEach(product => {
|
||||||
|
html += `
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<a href="${product.route}" class="text-decoration-none">
|
||||||
|
<div class="card border-0 shadow-sm">
|
||||||
|
<div class="card-body p-3">
|
||||||
|
<h6 class="card-title mb-1 text-truncate">${product.name}</h6>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += '</div></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Categories section
|
||||||
|
if (results.categories && results.categories.length > 0) {
|
||||||
|
html += `
|
||||||
|
<div class="mb-4">
|
||||||
|
<h6 class="text-uppercase fs-xs fw-bold mb-3">Categories</h6>
|
||||||
|
<div class="d-flex flex-wrap gap-2">
|
||||||
|
`;
|
||||||
|
|
||||||
|
results.categories.forEach(category => {
|
||||||
|
html += `
|
||||||
|
<a href="${category.route}"
|
||||||
|
class="btn btn-outline-secondary btn-sm">
|
||||||
|
${category.name}
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += '</div></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Genders section
|
||||||
|
if (results.genders && results.genders.length > 0) {
|
||||||
|
html += `
|
||||||
|
<div class="mb-4">
|
||||||
|
<h6 class="text-uppercase fs-xs fw-bold mb-3">Genders</h6>
|
||||||
|
<div class="d-flex flex-wrap gap-2">
|
||||||
|
`;
|
||||||
|
|
||||||
|
results.genders.forEach(gender => {
|
||||||
|
html += `
|
||||||
|
<a href="${gender.route}"
|
||||||
|
class="btn btn-outline-secondary btn-sm">
|
||||||
|
${gender.name}
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += '</div></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// No results
|
||||||
|
if (Object.keys(results).length === 0) {
|
||||||
|
html += `
|
||||||
|
<div class="text-center py-5">
|
||||||
|
<p class="text-muted mb-0">No results found for "${query}"</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
searchResults.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showError(message) {
|
||||||
|
searchResults.innerHTML = `
|
||||||
|
<div class="container text-center py-5">
|
||||||
|
<div class="text-danger mb-3">
|
||||||
|
<i class="ci-alert-circle fs-1"></i>
|
||||||
|
</div>
|
||||||
|
<p class="text-muted mb-0">${message}</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@extends('layouts.landing', ['title' => 'Fashion Store - Catalog'])
|
@extends('layouts.landing', ['title' => 'Store - Catalog'])
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<x-layout.header />
|
<x-layout.header />
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use App\Http\Controllers\RoutingController;
|
||||||
use App\Http\Controllers\LocationController;
|
use App\Http\Controllers\LocationController;
|
||||||
use App\Http\Controllers\LocaleController;
|
use App\Http\Controllers\LocaleController;
|
||||||
use App\Http\Controllers\ProductController;
|
use App\Http\Controllers\ProductController;
|
||||||
|
use App\Http\Controllers\SearchController;
|
||||||
|
|
||||||
Route::group(['prefix' => '/dummy'], function () {
|
Route::group(['prefix' => '/dummy'], function () {
|
||||||
Route::get('', [RoutingController::class, 'index'])->name('root');
|
Route::get('', [RoutingController::class, 'index'])->name('root');
|
||||||
|
|
@ -28,3 +29,6 @@ Route::get('/products/ajax',[ProductController::class, 'ajax'])->name('product.a
|
||||||
Route::get('/products/ajax/categories',[ProductController::class, 'categories'])->name('product.ajax.categories');
|
Route::get('/products/ajax/categories',[ProductController::class, 'categories'])->name('product.ajax.categories');
|
||||||
Route::get('/products/ajax/genders',[ProductController::class, 'genders'])->name('product.ajax.genders');
|
Route::get('/products/ajax/genders',[ProductController::class, 'genders'])->name('product.ajax.genders');
|
||||||
Route::get('/product/{slug}',[ProductController::class, 'detail'])->name('product.detail');
|
Route::get('/product/{slug}',[ProductController::class, 'detail'])->name('product.detail');
|
||||||
|
|
||||||
|
// Search routes
|
||||||
|
Route::get('/search', [SearchController::class, 'search'])->name('search.ajax');
|
||||||
Loading…
Reference in New Issue