category and category products through ajax

This commit is contained in:
shubhammehrotra.symfony@webkul.com 2020-01-31 20:01:36 +05:30
parent e578d7d1db
commit be3b8e34a7
17 changed files with 2516 additions and 457 deletions

View File

@ -2181,6 +2181,27 @@
display: none;
}
.sidebar .sub-categories .category {
padding: 5px 0 4px 15px;
}
.sidebar .sub-categories .category + .nested {
color: rgba(0, 0, 0, 0.83);
}
.sidebar .sub-categories .category + .nested li a {
padding-top: 0;
}
.sidebar .sub-categories .category + .nested li a .category-title {
font-weight: 500;
padding-left: 28px;
}
.sidebar .sub-categories .category .category-title {
vertical-align: top;
}
.category-list-container {
z-index: 10;
padding: 0px !important;
@ -2201,11 +2222,11 @@
position: relative;
}
.category-list-container li {
.category-list-container li a {
padding: 7px 0 5px 15px;
}
.category-list-container li:hover {
.category-list-container li:hover > a {
background: #ECECEC;
}
@ -2508,8 +2529,8 @@
}
.full-content-wrapper p > .container-fluid {
margin-bottom: 60px;
padding: 0 !important;
margin-bottom: 60px !important;
}
.full-content-wrapper p > .container-fluid > .row {
@ -2663,6 +2684,11 @@
content: "\E907";
}
.carousel-products + .recently-viewed {
top: -40px;
position: relative;
}
/* @author Shubham Mehrotra */
body {
display: none;

File diff suppressed because one or more lines are too long

View File

@ -1143,9 +1143,11 @@ $(document).ready(function () {
__WEBPACK_IMPORTED_MODULE_0_vue___default.a.mixin({
data: function data() {
return {
'baseUrl': document.querySelector("script[src$='velocity.js']").getAttribute('baseurl'),
'navContainer': false,
'responsiveSidebarTemplate': '',
'responsiveSidebarKey': Math.random()
'responsiveSidebarKey': Math.random(),
'sharedRootCategories': []
};
},
@ -1266,8 +1268,9 @@ $(document).ready(function () {
mounted: function mounted() {
document.body.style.display = "block";
this.$validator.localize(document.documentElement.lang);
this.loadCategories();
},
methods: {
@ -1340,6 +1343,16 @@ $(document).ready(function () {
showModal: function showModal(id) {
this.$set(this.modalIds, id, true);
},
loadCategories: function loadCategories() {
var _this3 = this;
this.$http.get(this.baseUrl + '/categories').then(function (response) {
_this3.sharedRootCategories = response.data.categories;
}).catch(function (error) {
console.log('failed to load categories');
});
}
}
});
@ -35993,26 +36006,55 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['id', 'url', 'addClass', 'parentSlug', 'categories', 'mainSidebar', 'categoryCount'],
props: ['id', 'addClass', 'parentSlug', 'mainSidebar', 'categoryCount'],
data: function data() {
var slicedCategories = this.categories;
var categoryCount = this.categoryCount ? this.categoryCount : 9;
if (slicedCategories && slicedCategories.length > categoryCount) {
slicedCategories = this.categories.slice(0, categoryCount);
}
if (this.parentSlug) slicedCategories['parentSlug'] = this.parentSlug;
return {
slicedCategories: slicedCategories,
slicedCategories: [],
sidebarLevel: Math.floor(Math.random() * 1000)
};
},
watch: {
'$root.sharedRootCategories': function $rootSharedRootCategories(categories) {
this.formatCategories(categories);
}
},
methods: {
remainBar: function remainBar(id) {
var sidebar = $('#' + id);
@ -36026,6 +36068,19 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
sidebarContainer.show();
}
}
},
formatCategories: function formatCategories(categories) {
var slicedCategories = categories;
var categoryCount = this.categoryCount ? this.categoryCount : 9;
if (slicedCategories && slicedCategories.length > categoryCount) {
slicedCategories = categories.slice(0, categoryCount);
}
if (this.parentSlug) slicedCategories['parentSlug'] = this.parentSlug;
this.slicedCategories = slicedCategories;
}
}
});
@ -36054,11 +36109,11 @@ var render = function() {
_c(
"ul",
{ attrs: { type: "none" } },
_vm._l(_vm.slicedCategories, function(category, index) {
_vm._l(_vm.slicedCategories, function(category, categoryIndex) {
return _c(
"li",
{
key: index,
key: categoryIndex,
staticClass: "category-content cursor-pointer",
attrs: { id: "category-" + category.id },
on: {
@ -36074,17 +36129,10 @@ var render = function() {
_c(
"a",
{
staticClass: "category unset",
class: category.children.length > 0 ? "fw6" : "",
attrs: {
href:
_vm.url +
"/" +
(_vm.slicedCategories.parentSlug
? _vm.slicedCategories.parentSlug + "/"
: "") +
category["translations"][0].slug
}
class:
"category unset " +
(category.children.length > 0 ? "fw6" : ""),
attrs: { href: _vm.$root.baseUrl + "/" + category.slug }
},
[
_c(
@ -36113,7 +36161,7 @@ var render = function() {
? _c("img", {
attrs: {
src:
_vm.url +
_vm.$root.baseUrl +
"/storage/" +
category.category_icon_path
}
@ -36157,22 +36205,178 @@ var render = function() {
{
class:
"sub-categories sub-category-" +
(_vm.sidebarLevel + index)
(_vm.sidebarLevel + categoryIndex)
},
[
_c("sidebar-component", {
attrs: {
url: _vm.url,
categories: category.children,
id:
"sidebar-level-" + (_vm.sidebarLevel + index),
"parent-slug": category.parentSlug
? category.parentSlug
: category["translations"][0].slug
}
})
],
1
_c(
"nav",
{
staticClass: "sidebar",
attrs: {
id:
"sidebar-level-" +
(_vm.sidebarLevel + categoryIndex)
},
on: {
mouseover: function($event) {
return _vm.remainBar(
"sidebar-level-" +
(_vm.sidebarLevel + categoryIndex)
)
}
}
},
[
_c(
"ul",
{ attrs: { type: "none" } },
_vm._l(category.children, function(
subCategory,
subCategoryIndex
) {
return _c(
"li",
{
key:
subCategoryIndex + "-" + categoryIndex
},
[
_c(
"a",
{
class:
"category unset " +
(subCategory.children.length > 0
? "fw6"
: ""),
attrs: {
href:
_vm.$root.baseUrl +
"/" +
category.slug +
"/" +
subCategory.slug
}
},
[
_c(
"div",
{
staticClass: "category-icon",
on: {
mouseout: function($event) {
return _vm.toggleSidebar(
_vm.id,
$event,
"mouseout"
)
},
mouseover: function($event) {
return _vm.toggleSidebar(
_vm.id,
$event,
"mouseover"
)
}
}
},
[
subCategory.category_icon_path
? _c("img", {
attrs: {
src:
_vm.$root.baseUrl +
"/storage/" +
subCategory.category_icon_path
}
})
: _vm._e()
]
),
_vm._v(" "),
_c(
"span",
{ staticClass: "category-title" },
[
_vm._v(
_vm._s(subCategory["name"])
)
]
)
]
),
_vm._v(" "),
_c(
"ul",
{
staticClass: "nested",
attrs: { type: "none" }
},
_vm._l(subCategory.children, function(
childSubCategory,
childSubCategoryIndex
) {
return _c(
"li",
{
key:
childSubCategoryIndex +
"-" +
subCategoryIndex +
"-" +
categoryIndex
},
[
_c(
"a",
{
class:
"category unset " +
(subCategory.children
.length > 0
? "fw6"
: ""),
attrs: {
href:
_vm.$root.baseUrl +
"/" +
category.slug +
"/" +
subCategory.slug +
"/" +
childSubCategory.slug
}
},
[
_c(
"span",
{
staticClass:
"category-title"
},
[
_vm._v(
_vm._s(
childSubCategory.name
)
)
]
)
]
)
]
)
}),
0
)
]
)
}),
0
)
]
)
]
)
])
: _vm._e()
@ -36318,15 +36522,10 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
//
//
//
//
// compile add to cart html (it contains wishlist component)
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['list', 'productImg', 'productUrl', 'priceHtml', 'addToCartHtml', 'productName', 'totalReviews', 'avgRating', 'firstReviewText'],
data: function data() {
return {};
}
props: ['list', 'product']
});
/***/ }),
@ -36345,8 +36544,13 @@ var render = function() {
_c("div", { staticClass: "product-image" }, [
_c(
"a",
{ attrs: { title: _vm.productName, href: _vm.productUrl } },
[_c("img", { attrs: { src: _vm.productImg } })]
{
attrs: {
title: _vm.product.name,
href: _vm.baseUrl + "/" + _vm.product.slug
}
},
[_c("img", { attrs: { src: _vm.product.image } })]
)
]),
_vm._v(" "),
@ -36357,11 +36561,14 @@ var render = function() {
"a",
{
staticClass: "unset",
attrs: { href: _vm.productUrl, title: _vm.productName }
attrs: {
href: _vm.baseUrl + "/" + _vm.product.slug,
title: _vm.product.name
}
},
[
_c("span", { staticClass: "fs16" }, [
_vm._v(_vm._s(_vm.productName))
_vm._v(_vm._s(_vm.product.name))
])
]
)
@ -36369,18 +36576,20 @@ var render = function() {
_vm._v(" "),
_c("div", {
staticClass: "product-price",
domProps: { innerHTML: _vm._s(_vm.priceHtml) }
domProps: { innerHTML: _vm._s(_vm.product.priceHTML) }
}),
_vm._v(" "),
_vm.totalReviews && _vm.totalReviews > 0
_vm.product.totalReviews && _vm.product.totalReviews > 0
? _c(
"div",
{ staticClass: "product-rating" },
[
_c("star-ratings", { attrs: { ratings: _vm.avgRating } }),
_c("star-ratings", {
attrs: { ratings: _vm.product.avgRating }
}),
_vm._v(" "),
_c("span", [
_vm._v(_vm._s(_vm.totalReviews) + " Ratings")
_vm._v(_vm._s(_vm.product.totalReviews) + " Ratings")
])
],
1
@ -36388,13 +36597,15 @@ var render = function() {
: _c("div", { staticClass: "product-rating" }, [
_c("span", {
staticClass: "fs14",
domProps: { textContent: _vm._s(_vm.firstReviewText) }
domProps: {
textContent: _vm._s(_vm.product.firstReviewText)
}
})
]),
_vm._v(" "),
_c("div", {
staticClass: "cart-wish-wrap row mt5",
domProps: { innerHTML: _vm._s(_vm.addToCartHtml) }
domProps: { innerHTML: _vm._s(_vm.product.addToCartHtml) }
})
])
])
@ -36405,15 +36616,18 @@ var render = function() {
"a",
{
staticClass: "product-image-container",
attrs: { href: _vm.productUrl, title: _vm.productName }
attrs: {
href: _vm.baseUrl + "/" + _vm.product.slug,
title: _vm.product.name
}
},
[
_c("img", {
staticClass: "card-img-top",
attrs: {
loading: "lazy",
src: _vm.productImg,
alt: _vm.productName
src: _vm.product.image,
alt: _vm.product.name
}
})
]
@ -36425,11 +36639,14 @@ var render = function() {
"a",
{
staticClass: "unset",
attrs: { href: _vm.productUrl, title: _vm.productName }
attrs: {
title: _vm.product.name,
href: _vm.baseUrl + "/" + _vm.product.slug
}
},
[
_c("span", { staticClass: "fs16" }, [
_vm._v(_vm._s(_vm.productName))
_vm._v(_vm._s(_vm.product.name))
])
]
)
@ -36437,18 +36654,20 @@ var render = function() {
_vm._v(" "),
_c("div", {
staticClass: "product-price fs16",
domProps: { innerHTML: _vm._s(_vm.priceHtml) }
domProps: { innerHTML: _vm._s(_vm.product.priceHTML) }
}),
_vm._v(" "),
_vm.totalReviews && _vm.totalReviews > 0
_vm.product.totalReviews && _vm.product.totalReviews > 0
? _c(
"div",
{ staticClass: "product-rating col-12 no-padding" },
[
_c("star-ratings", { attrs: { ratings: _vm.avgRating } }),
_c("star-ratings", {
attrs: { ratings: _vm.product.avgRating }
}),
_vm._v(" "),
_c("span", { staticClass: "align-top" }, [
_vm._v(_vm._s(_vm.totalReviews) + " Ratings")
_vm._v(_vm._s(_vm.product.totalReviews) + " Ratings")
])
],
1
@ -36456,13 +36675,13 @@ var render = function() {
: _c("div", { staticClass: "product-rating col-12 no-padding" }, [
_c("span", {
staticClass: "fs14",
domProps: { textContent: _vm._s(_vm.firstReviewText) }
domProps: { textContent: _vm._s(_vm.product.firstReviewText) }
})
]),
_vm._v(" "),
_c("div", {
staticClass: "cart-wish-wrap row col-12 no-padding ml0",
domProps: { innerHTML: _vm._s(_vm.addToCartHtml) }
domProps: { innerHTML: _vm._s(_vm.product.addToCartHtml) }
})
])
])

View File

@ -101,4 +101,83 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
return $response;
}
public function categoryDetails()
{
$categoryDetails = app('Webkul\Category\Repositories\CategoryRepository')->findByPath(request()->get('category-slug'));
if ($categoryDetails) {
$list = false;
$customizedProducts = [];
$products = $this->productRepository->getAll($categoryDetails->id);
foreach ($products as $product) {
$productImage = app('Webkul\Product\Helpers\ProductImage')->getProductBaseImage($product)['medium_image_url'];
$reviewHelper = app('Webkul\Product\Helpers\Review');
$totalReviews = $reviewHelper->getTotalReviews($product);
$avgRatings = ceil($reviewHelper->getAverageRating($product));
array_push($customizedProducts, [
'list' => false,
'name' => $product->name,
'image' => $productImage,
'slug' => $product->url_key,
'priceHTML' => view('shop::products.price', ['product' => $product])->render(),
'totalReviews' => $totalReviews,
'avgRating' => $avgRatings,
'firstReviewText' => trans('velocity::app.products.be-first-review'),
'addToCartHtml' => view('shop::products.add-to-cart', [
'product' => $product,
'addWishlistClass' => !(isset($list) && $list) ? 'col-lg-4 col-md-4 col-sm-12 offset-lg-4 pr0' : '',
'addToCartBtnClass' => !(isset($list) && $list) ? $addToCartBtnClass ?? '' : ''
])->render(),
]);
}
$response = [
'status' => true,
'list' => $list,
'categoryDetails' => $categoryDetails,
'categoryProducts' => $customizedProducts,
];
}
return $response ?? [
'status' => false,
];
}
public function fetchCategories()
{
$formattedCategories = [];
$categories = app('Webkul\Category\Repositories\CategoryRepository')->getVisibleCategoryTree(core()->getCurrentChannel()->root_category_id);
foreach ($categories as $category) {
array_push($formattedCategories, $this->getCategoryFilteredData($category));
}
return [
'status' => true,
'categories' => $formattedCategories,
];
}
private function getCategoryFilteredData($category)
{
$formattedChildCategory = [];
foreach ($category->children as $child) {
array_push($formattedChildCategory, $this->getCategoryFilteredData($child));
}
return [
'id' => $category->id,
'slug' => $category->slug,
'name' => $category->name,
'children' => $formattedChildCategory,
'category_icon_path' => $category->category_icon_path,
];
}
}

View File

@ -8,5 +8,9 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
Route::get('/categorysearch', 'ShopController@search')->defaults('_config', [
'view' => 'shop::search.search'
])->name('velocity.search.index');
Route::get('/categories', 'ShopController@fetchCategories')->name('velocity.categoriest');
Route::get('/category-details', 'ShopController@categoryDetails')->name('velocity.category.details');
});
});

View File

@ -1,42 +1,41 @@
<template>
<!-- @WIP -->
<div class="col-12 lg-card-container list-card product-card row" v-if="list">
<div class="product-image">
<a :title="productName" :href="productUrl">
<img :src="productImg" />
<a :title="product.name" :href="`${baseUrl}/${product.slug}`">
<img :src="product.image" />
</a>
</div>
<div class="product-information">
<div>
<div class="product-name">
<a :href="productUrl" :title="productName" class="unset">
<span class="fs16">{{ productName }}</span>
<a :href="`${baseUrl}/${product.slug}`" :title="product.name" class="unset">
<span class="fs16">{{ product.name }}</span>
</a>
</div>
<div class="product-price" v-html="priceHtml"></div>
<div class="product-price" v-html="product.priceHTML"></div>
<div class="product-rating" v-if="totalReviews && totalReviews > 0">
<star-ratings :ratings="avgRating"></star-ratings>
<span>{{ totalReviews }} Ratings</span>
<div class="product-rating" v-if="product.totalReviews && product.totalReviews > 0">
<star-ratings :ratings="product.avgRating"></star-ratings>
<span>{{ product.totalReviews }} Ratings</span>
</div>
<div class="product-rating" v-else>
<span class="fs14" v-text="firstReviewText"></span>
<span class="fs14" v-text="product.firstReviewText"></span>
</div>
<div class="cart-wish-wrap row mt5" v-html="addToCartHtml"></div>
<div class="cart-wish-wrap row mt5" v-html="product.addToCartHtml"></div>
</div>
</div>
</div>
<div class="card grid-card product-card-new" v-else>
<a :href="productUrl" :title="productName" class="product-image-container">
<a :href="`${baseUrl}/${product.slug}`" :title="product.name" class="product-image-container">
<img
loading="lazy"
:src="productImg"
:alt="productName"
:src="product.image"
:alt="product.name"
class="card-img-top">
<!-- <quick-view-btn details="{{ $product }}"></quick-view-btn> -->
@ -46,25 +45,25 @@
<div class="product-name col-12 no-padding">
<a
class="unset"
:href="productUrl"
:title="productName">
:title="product.name"
:href="`${baseUrl}/${product.slug}`">
<span class="fs16">{{ productName }}</span>
<span class="fs16">{{ product.name }}</span>
</a>
</div>
<div class="product-price fs16" v-html="priceHtml"></div>
<div class="product-price fs16" v-html="product.priceHTML"></div>
<div class="product-rating col-12 no-padding" v-if="totalReviews && totalReviews > 0">
<star-ratings :ratings="avgRating"></star-ratings>
<span class="align-top">{{ totalReviews }} Ratings</span>
<div class="product-rating col-12 no-padding" v-if="product.totalReviews && product.totalReviews > 0">
<star-ratings :ratings="product.avgRating"></star-ratings>
<span class="align-top">{{ product.totalReviews }} Ratings</span>
</div>
<div class="product-rating col-12 no-padding" v-else>
<span class="fs14" v-text="firstReviewText"></span>
<span class="fs14" v-text="product.firstReviewText"></span>
</div>
<div class="cart-wish-wrap row col-12 no-padding ml0" v-html="addToCartHtml"></div>
<div class="cart-wish-wrap row col-12 no-padding ml0" v-html="product.addToCartHtml"></div>
</div>
</div>
</template>
@ -74,19 +73,7 @@
export default {
props: [
'list',
'productImg',
'productUrl',
'priceHtml',
'addToCartHtml',
'productName',
'totalReviews',
'avgRating',
'firstReviewText',
'product',
],
data: function () {
return {
}
}
}
</script>

View File

@ -8,18 +8,16 @@
<ul type="none">
<li
:key="index"
:key="categoryIndex"
:id="`category-${category.id}`"
class="category-content cursor-pointer"
v-for="(category, index) in slicedCategories"
v-for="(category, categoryIndex) in slicedCategories"
@mouseout="toggleSidebar(id, $event, 'mouseout')"
@mouseover="toggleSidebar(id, $event, 'mouseover')">
<a
class="category unset"
:class="(category.children.length > 0) ? 'fw6' : ''"
:href="`${url}/${slicedCategories.parentSlug ? slicedCategories.parentSlug + '/' : ''}${category['translations'][0].slug}`">
:class="`category unset ${(category.children.length > 0) ? 'fw6' : ''}`"
:href="`${$root.baseUrl}/${category.slug}`">
<div
class="category-icon"
@ -28,7 +26,7 @@
<img
v-if="category.category_icon_path"
:src="`${url}/storage/${category.category_icon_path}`" />
:src="`${$root.baseUrl}/storage/${category.category_icon_path}`" />
</div>
<span class="category-title">{{ category['name'] }}</span>
<i
@ -43,13 +41,47 @@
class="sub-category-container"
v-if="category.children.length && category.children.length > 0">
<div :class="`sub-categories sub-category-${sidebarLevel+index}`">
<sidebar-component
:url="url"
:categories="category.children"
:id="`sidebar-level-${sidebarLevel+index}`"
:parent-slug="category.parentSlug ? category.parentSlug : category['translations'][0].slug">
</sidebar-component>
<div :class="`sub-categories sub-category-${sidebarLevel+categoryIndex}`">
<nav
class="sidebar"
@mouseover="remainBar(`sidebar-level-${sidebarLevel+categoryIndex}`)"
:id="`sidebar-level-${sidebarLevel+categoryIndex}`">
<ul type="none">
<li
:key="`${subCategoryIndex}-${categoryIndex}`"
v-for="(subCategory, subCategoryIndex) in category.children">
<a
:class="`category unset ${(subCategory.children.length > 0) ? 'fw6' : ''}`"
:href="`${$root.baseUrl}/${category.slug}/${subCategory.slug}`">
<div
class="category-icon"
@mouseout="toggleSidebar(id, $event, 'mouseout')"
@mouseover="toggleSidebar(id, $event, 'mouseover')">
<img
v-if="subCategory.category_icon_path"
:src="`${$root.baseUrl}/storage/${subCategory.category_icon_path}`" />
</div>
<span class="category-title">{{ subCategory['name'] }}</span>
</a>
<ul type="none" class="nested">
<li
:key="`${childSubCategoryIndex}-${subCategoryIndex}-${categoryIndex}`"
v-for="(childSubCategory, childSubCategoryIndex) in subCategory.children">
<a
:class="`category unset ${(subCategory.children.length > 0) ? 'fw6' : ''}`"
:href="`${$root.baseUrl}/${category.slug}/${subCategory.slug}/${childSubCategory.slug}`">
<span class="category-title">{{ childSubCategory.name }}</span>
</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</li>
@ -61,33 +93,25 @@
export default {
props: [
'id',
'url',
'addClass',
'parentSlug',
'categories',
'mainSidebar',
'categoryCount'
],
data: function () {
let slicedCategories = this.categories;
let categoryCount = this.categoryCount ? this.categoryCount : 9;
if (slicedCategories
&& slicedCategories.length > categoryCount
) {
slicedCategories = this.categories.slice(0, categoryCount);
}
if (this.parentSlug)
slicedCategories['parentSlug'] = this.parentSlug;
return {
slicedCategories,
slicedCategories: [],
sidebarLevel: Math.floor(Math.random() * 1000),
}
},
watch: {
'$root.sharedRootCategories': function (categories) {
this.formatCategories(categories);
}
},
methods: {
remainBar: function (id) {
let sidebar = $(`#${id}`);
@ -103,6 +127,23 @@
}
},
formatCategories: function (categories) {
let slicedCategories = categories;
let categoryCount = this.categoryCount ? this.categoryCount : 9;
if (
slicedCategories
&& slicedCategories.length > categoryCount
) {
slicedCategories = categories.slice(0, categoryCount);
}
if (this.parentSlug)
slicedCategories['parentSlug'] = this.parentSlug;
this.slicedCategories = slicedCategories;
}
}
}
</script>

View File

@ -50,9 +50,11 @@ $(document).ready(function () {
Vue.mixin({
data: function () {
return {
'baseUrl': document.querySelector("script[src$='velocity.js']").getAttribute('baseurl'),
'navContainer': false,
'responsiveSidebarTemplate': '',
'responsiveSidebarKey': Math.random(),
'sharedRootCategories': [],
}
},
@ -141,7 +143,7 @@ $(document).ready(function () {
});
},
isMobile() {
isMobile: function () {
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
return true
} else {
@ -157,7 +159,7 @@ $(document).ready(function () {
data: function () {
return {
modalIds: {}
modalIds: {},
}
},
@ -173,8 +175,9 @@ $(document).ready(function () {
mounted: function () {
document.body.style.display = "block";
this.$validator.localize(document.documentElement.lang);
this.loadCategories();
},
methods: {
@ -245,6 +248,16 @@ $(document).ready(function () {
showModal: function (id) {
this.$set(this.modalIds, id, true);
},
loadCategories: function () {
this.$http.get(`${this.baseUrl}/categories`)
.then(response => {
this.sharedRootCategories = response.data.categories;
})
.catch(error => {
console.log('failed to load categories');
})
}
}
});
});

View File

@ -1539,6 +1539,29 @@
.sub-categories {
display: none;
.category {
padding: 5px 0 4px 15px;
+ .nested {
color: $font-color;
li {
a {
padding-top: 0;
.category-title {
font-weight: 500;
padding-left: 28px;
}
}
}
}
.category-title {
vertical-align: top;
}
}
}
}
@ -1563,15 +1586,15 @@
}
li {
padding: 7px 0 5px 15px;
}
a {
padding: 7px 0 5px 15px;
}
li:hover {
background: $border-light;
}
.sub-category-container {
// position: relative;
&:hover {
> a {
background: $border-light;
}
}
}
.sub-categories {
@ -1899,8 +1922,8 @@
p {
> .container-fluid {
margin-bottom: 60px;
padding: 0 !important;
margin-bottom: 60px !important;
> .row {
padding: 0 15px !important;
@ -2063,3 +2086,10 @@
}
}
}
.carousel-products {
+ .recently-viewed {
top: -40px;
position: relative;
}
}

View File

@ -103,20 +103,21 @@
{{ __('velocity::app.header.all-categories') }}
</option>
@foreach ($categories as $category)
<option
selected="selected"
value="{{ $category->id }}"
v-if="({{ $category->id }} == searchedQuery.category)">
{{ $category->name }}
</option>
<template
:key="index"
v-for="(category, index) in $root.sharedRootCategories">
<option
v-else
value="{{ $category->id }}">
{{ $category->name }}
selected="selected"
:value="category.id"
v-if="(category.id == searchedQuery.category)">
@{{ category.name }}
</option>
@endforeach
<option :value="category.id" v-else>
@{{ category.name }}
</option>
</template>
</select>
<div class="select-icon-container">
@ -207,7 +208,7 @@
<li
:key="index"
v-for="(content, index) in headerContent">
<a :href="`${url}/${content.page_link}`" class="unset" v-text="content.title"></a>
<a :href="`${$root.baseUrl}/${content.page_link}`" class="unset" v-text="content.title"></a>
</li>
</ul>
@ -215,13 +216,13 @@
<li v-for="(category, index) in JSON.parse(categories)">
<a
class="unset"
:href="`${url}/${category['translations'][0].url_path}`">
:href="`${$root.baseUrl}/${category.slug}`">
<div class="category-logo">
<img
class="category-icon"
v-if="category.category_icon_path"
:src="`${url}/storage/${category.category_icon_path}`" />
:src="`${$root.baseUrl}/storage/${category.category_icon_path}`" />
</div>
<span v-text="category.name"></span>
</a>
@ -347,13 +348,13 @@
<a
class="unset"
:href="`${url}/${nestedSubCategory['translations'][0].url_path}`">
:href="`${$root.baseUrl}/${nestedSubCategory.slug}`">
<div class="category-logo">
<img
class="category-icon"
v-if="nestedSubCategory.category_icon_path"
:src="`${url}/storage/${nestedSubCategory.category_icon_path}`" />
:src="`${$root.baseUrl}/storage/${nestedSubCategory.category_icon_path}`" />
</div>
<span>@{{ nestedSubCategory.name }}</span>
</a>
@ -368,13 +369,13 @@
v-for="(thirdLevelCategory, index) in nestedSubCategory.children">
<a
class="unset"
:href="`${url}/${nestedSubCategory['translations'][0].url_path}`">
:href="`${$root.baseUrl}/${nestedSubCategory.slug}`">
<div class="category-logo">
<img
class="category-icon"
v-if="thirdLevelCategory.category_icon_path"
:src="`${url}/storage/${thirdLevelCategory.category_icon_path}`" />
:src="`${$root.baseUrl}/storage/${thirdLevelCategory.category_icon_path}`" />
</div>
<span>@{{ thirdLevelCategory.name }}</span>
</a>
@ -454,7 +455,7 @@
</div>
<div class="right-vc-header col-4">
<a :href="`${url}/customer/account/wishlist`" class="unset">
<a :href="`${$root.baseUrl}/customer/account/wishlist`" class="unset">
<i class="material-icons">favorite_border</i>
</a>
@ -502,8 +503,8 @@
<ul type="none" class="no-margin">
<li v-for="(content, index) in headerContent" :key="index">
<a
v-text="content.custom_title"
:href="`${url}/${content['page_link']}`"
v-text="content.title"
:href="`${$root.baseUrl}/${content['page_link']}`"
v-if="(content['content_type'] == 'link')"
:target="content['link_target'] ? '_blank' : '_self'">
</a>
@ -662,10 +663,7 @@
Vue.component('content-header', {
template: '#content-header-template',
props: [
'url',
'heading',
'isEnabled',
'categories',
'headerContent',
],
@ -723,7 +721,7 @@
} else {
event.preventDefault();
let categories = JSON.parse(this.categories);
let categories = this.sharedRootCategories;
this.rootCategories = false;
this.subCategory = categories[index];
}

View File

@ -1,93 +1,54 @@
@inject ('productRepository', 'Webkul\Product\Repositories\ProductRepository')
@php
$categoryDetails = app('Webkul\Category\Repositories\CategoryRepository')->findByPath($category);
@endphp
@if ($categoryDetails)
@php
$products = $productRepository->getAll($categoryDetails->id);
@endphp
@if ($products->count())
<div class="container-fluid remove-padding-margin">
<card-list-header
view-all="{{ route('shop.productOrCategory.index', $categoryDetails->slug) }}"
heading="{{ $categoryDetails->name }}">
</card-list-header>
<div class="carousel-products vc-full-screen">
<carousel-component
slides-per-page="6"
navigation-enabled="hide"
pagination-enabled="hide"
:slides-count="{{ sizeof($products) }}"
id="{{ $categoryDetails->name }}-carousel">
@foreach ($products as $index => $product)
<slide slot="slide-{{ $index }}">
@include ('shop::products.list.card', ['product' => $product])
</slide>
@endforeach
</carousel-component>
</div>
<div class="carousel-products vc-small-screen">
<carousel-component
slides-per-page="2"
navigation-enabled="hide"
pagination-enabled="hide"
:slides-count="{{ sizeof($products) }}"
id="{{ $categoryDetails->name }}-carousel">
@foreach ($products as $index => $product)
<slide slot="slide-{{ $index }}">
@include ('shop::products.list.card', ['product' => $product])
</slide>
@endforeach
</carousel-component>
</div>
</div>
@endif
@endif
<category-products
category-slug="{{ $category }}"
></category-products>
@push('scripts')
{{-- <script type="text/x-template" id="category-products-template">
<div class="container-fluid remove-padding-margin">
<script type="text/x-template" id="category-products-template">
<div class="container-fluid remove-padding-margin" v-if="isCategory">
<card-list-header
view-all="{{ route('shop.productOrCategory.index', $categoryDetails->slug) }}"
heading="{{ $categoryDetails->name }}">
:view-all="`${this.baseUrl}/${categoryDetails.slug}`"
:heading="categoryDetails.name">
</card-list-header>
<div class="carousel-products vc-full-screen">
<div class="carousel-products vc-full-screen" v-if="!isMobile()">
<carousel-component
slides-per-page="6"
navigation-enabled="hide"
pagination-enabled="hide"
:slides-count="{{ sizeof($products) }}"
id="{{ $categoryDetails->name }}-carousel">
:slides-count="categoryProducts.length"
:id="`${categoryDetails.name}-carousel`">
@foreach ($products as $index => $product)
<slide slot="slide-{{ $index }}">
@include ('shop::products.list.card', ['product' => $product])
<slide
:key="index"
:slot="`slide-${index}`"
v-for="(product, index) in categoryProducts">
<product-card
:list="list"
:product="product">
</product-card>
</slide>
@endforeach
</carousel-component>
</div>
<div class="carousel-products vc-small-screen">
<div class="carousel-products vc-small-screen" v-else>
<carousel-component
slides-per-page="2"
navigation-enabled="hide"
pagination-enabled="hide"
:slides-count="{{ sizeof($products) }}"
id="{{ $categoryDetails->name }}-carousel">
:slides-count="categoryProducts.length"
:id="`${categoryDetails.name}-carousel`">
@foreach ($products as $index => $product)
<slide slot="slide-{{ $index }}">
@include ('shop::products.list.card', ['product' => $product])
</slide>
@endforeach
<slide
:key="index"
:slot="`slide-${index}`"
v-for="(product, index) in categoryProducts">
<product-card
:list="list"
:product="product">
</product-card>
</slide>
</carousel-component>
</div>
</div>
@ -95,11 +56,39 @@
<script type="text/javascript">
(() => {
debugger
"{{ $categoryDetails->name }}"
Vue.component('category-products', {
template: '#category-products-template',
props: [
'categorySlug'
],
data: function () {
return {
isCategory: false,
heading: 'customer',
}
},
mounted: function () {
this.getCategoryDetails();
},
methods: {
'getCategoryDetails': function () {
this.$http.get(`${this.baseUrl}/category-details?category-slug=${this.categorySlug}`)
.then(response => {
if (response.data.status) {
this.list = response.data.list;
this.categoryDetails = response.data.categoryDetails;
this.categoryProducts = response.data.categoryProducts;
this.isCategory = true;
}
})
.catch(error => {});
}
}
})
})()
</script> --}}
</script>
@endpush

View File

@ -1,4 +1,5 @@
@extends('shop::layouts.master')
@inject ('productImageHelper', 'Webkul\Product\Helpers\ProductImage')
@inject ('productRatingHelper', 'Webkul\Product\Helpers\Review')
@ -61,4 +62,5 @@
{{ view_render_event('bagisto.shop.home.content.after') }}
</div>
@endsection
@endsection

View File

@ -4,9 +4,9 @@
@include('shop::layouts.footer.newsletter-subscription')
@include('shop::layouts.footer.footer-links')
@if ($categories)
{{-- @include('shop::layouts.footer.top-brands') --}}
@endif
{{-- @if ($categories)
@include('shop::layouts.footer.top-brands')
@endif --}}
@include('shop::layouts.footer.copy-right')
</div>

View File

@ -1,161 +0,0 @@
{!! view_render_event('bagisto.shop.layout.header.category.before') !!}
<?php
$categories = [];
foreach (
app('Webkul\Category\Repositories\CategoryRepository')
->getVisibleCategoryTree(
core()->getCurrentChannel()->root_category_id
)
as $category
) {
if ($category->slug) {
array_push($categories, $category);
}
}
?>
{!! view_render_event('bagisto.shop.layout.header.category.after') !!}
@push('scripts')
<script type="text/x-template" id="category-item-template">
<li
class="category-list"
v-if="parent < 10"
@mouseover="isShow = true"
@mouseleave="isShow = false">
<a :href="url+'/categories/'+this.item['translations'][0].slug">
@{{ name }}&emsp;
<i class="material-icons" v-if="haveChildren && item.parent_id != null">chevron_right</i>
</a>
<div class="child-container" v-if="haveChildren && isShow">
<ul class="child-category" v-for="(child, index) in item.children">
<li class="category-list">
<a :href="url+'/categories/'+child.translations[0].slug">
@{{ child.name }}&emsp;
</a>
</li>
</ul>
</div>
</li>
<li class="category-list" v-else-if="parent == 10">
<a :href="url+'/categories/'+this.item['translations'][0].slug">
{{ __('velocity::app.menu-navbar.text-more') }}&emsp;
<i class="material-icons">chevron_right</i>
</a>
</li>
</script>
<script type="text/x-template" id="category-nav-template">
<ul class="category-dropdown nav navbar-nav">
<category-item
v-for="(item, index) in items"
:key="index"
:url="url"
:item="item"
:parent="index">
</category-item>
</ul>
</script>
<script type="text/javascript">
Vue.component('category-nav', {
template: '#category-nav-template',
props: {
categories: {
type: [Array, String, Object],
required: false,
default: (function () {
return [];
})
},
url: String
},
data: function() {
return {
items_count:0
};
},
computed: {
items: function() {
return JSON.parse(this.categories)
}
},
});
Vue.component('category-item', {
template: '#category-item-template',
props: {
item: Object,
url: String,
parent: Number,
},
data: function() {
return {
isShow: false,
items_count:0,
};
},
computed: {
haveChildren: function() {
if (this.item.children.length) {
return true;
} else {
return false;
}
},
name: function() {
if (this.item.translations && this.item.translations.length) {
this.item.translations.forEach(function(translation) {
if (translation.locale == document.documentElement.lang)
return translation.name;
});
}
return this.item.name;
}
},
});
//Hide show category dropdown
$(document).ready(function() {
$('.category-dropdown').addClass('hide');
$(".list-icon").on("click",function (){
var clicks = $(this).closest('.list-icon').data('clicks');
if (clicks == null) {
$('.category-dropdown').removeClass('hide');
$('.category-dropdown').addClass('show');
} else if (clicks) {
$('.category-dropdown').removeClass('show');
$('.category-dropdown').addClass('hide');
} else {
$('.category-dropdown').removeClass('hide');
$('.category-dropdown').addClass('show');
}
$(this).closest('.list-icon').data("clicks", !clicks);
});
});
</script>
@endpush

View File

@ -15,7 +15,7 @@
<link rel="stylesheet" href="{{ asset('themes/velocity/assets/css/google-font.css') }}" />
@if (core()->getCurrentLocale()->direction == 'rtl')
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-rtl/3.4.0/css/bootstrap-flipped.css" rel="stylesheet">
<link href="{{ asset('themes/velocity/assets/css/bootstrap-flipped.css') }}" rel="stylesheet">
@endif
@ -25,10 +25,21 @@
<link rel="icon" sizes="16x16" href="{{ asset('themes/velocity/assets/images/favicon.png') }}" />
@endif
<script src="{{ asset('themes/velocity/assets/js/jquery.min.js') }}"></script>
{{-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script> --}}
<script type="text/javascript" src="{{ asset('themes/velocity/assets/js/velocity.js') }}"></script>
<script type="text/javascript" src="{{ asset('themes/velocity/assets/js/jquery.ez-plus.js') }}"></script>
<script
type="text/javascript"
src="{{ asset('themes/velocity/assets/js/jquery.min.js') }}">
</script>
<script
type="text/javascript"
baseUrl='{{ url()->to('/') }}'
src="{{ asset('themes/velocity/assets/js/velocity.js') }}">
</script>
<script
type="text/javascript"
src="{{ asset('themes/velocity/assets/js/jquery.ez-plus.js') }}">
</script>
@yield('head')
@ -45,16 +56,6 @@
<body @if (core()->getCurrentLocale()->direction == 'rtl') class="rtl" @endif>
{!! view_render_event('bagisto.shop.layout.body.before') !!}
@php
$categories = [];
foreach (app('Webkul\Category\Repositories\CategoryRepository')->getVisibleCategoryTree(core()->getCurrentChannel()->root_category_id) as $category) {
if ($category->slug)
array_push($categories, $category);
}
@endphp
@include('shop::UI.particals')
<div id="app">
@ -64,9 +65,7 @@
@section('body-header')
@include('shop::layouts.top-nav.index')
@include('shop::layouts.header.index', [
'categories' => $categories
])
@include('shop::layouts.header.index')
<div class="main-content-wrapper col-12 no-padding">
@php
@ -75,8 +74,6 @@
<content-header
url="{{ url()->to('/') }}"
is-enabled="{{ sizeof($categories) }}"
categories="{{ json_encode($categories) }}"
:header-content="{{ json_encode($velocityContent) }}"
heading= "{{ __('velocity::app.menu-navbar.text-category') }}"
></content-header>
@ -87,7 +84,6 @@
main-sidebar=true
id="sidebar-level-0"
url="{{ url()->to('/') }}"
:categories="{{ json_encode($categories) }}"
category-count="{{ $velocityMetaData ? $velocityMetaData->sidebar_category_count : 10 }}"
add-class="category-list-container pt10">
</sidebar-component>

View File

@ -16,24 +16,6 @@
@endphp
{!! view_render_event('bagisto.shop.products.list.card.before', ['product' => $product]) !!}
{{-- @TODO:- make product card a vue component and get all the details through xhr --}}
{{-- <product-card
price-html="{{ view('shop::products.price', ['product' => $product])->render() }}"
add-to-cart-html="{{ view('shop::products.add-to-cart', [
'product' => $product,
'addWishlistClass' => !(isset($list) && $list) ? 'col-lg-4 col-md-4 col-sm-12 offset-lg-4 pr0' : '',
'addToCartBtnClass' => !(isset($list) && $list) ? $addToCartBtnClass ?? '' : ''
])->render() }}"
total-reviews="{{ $totalReviews }}"
avg-rating="{{ $avgRatings }}"
list="{{ (isset($list) && $list) }}"
product-name="{{ $product->name }}"
first-review-text="{{ __('velocity::app.products.be-first-review') }}"
product-img="{{ $productBaseImage['medium_image_url'] }}"
product-url="{{ route('shop.productOrCategory.index', $product->url_key) }}">
</product-card> --}}
@if (isset($list) && $list)
<div class="col-12 lg-card-container list-card product-card row">
<div class="product-image">

View File

@ -24,13 +24,13 @@
v-for="(product, index) in recentlyViewed">
<div class="col-4 product-image-container mr15">
<a :href="`${baseURL}/${product.urlKey}`" class="unset">
<a :href="`${baseUrl}/${product.urlKey}`" class="unset">
<div class="product-image" :style="`background-image: url(${product.image})`"></div>
</a>
</div>
<div class="col-8 no-padding card-body align-vertical-top">
<a :href="`${baseURL}/${product.urlKey}`" class="unset no-padding">
<a :href="`${baseUrl}/${product.urlKey}`" class="unset no-padding">
<div class="product-name">
<span class="fs16 text-nowrap">@{{ product.name }}</span>
</div>
@ -67,7 +67,6 @@
data: function () {
return {
baseURL: '{{ url()->to('/') }}',
recentlyViewed: (() => {
let storedRecentlyViewed = window.localStorage.recentlyViewed;
if (storedRecentlyViewed) {
@ -89,11 +88,9 @@
},
created: function () {
// @TODO:- current product and recentlyViewed
for (slug in this.recentlyViewed) {
if (slug) {
this.$http(`${this.baseURL}/product-details/${slug}`)
this.$http(`${this.baseUrl}/product-details/${slug}`)
.then(response => {
if (response.data.status) {
this.$set(this.recentlyViewed, response.data.details.urlKey, response.data.details);