retailer-vue/src/components/retailer/search/SearchProducts.vue

694 lines
23 KiB
Vue

<template>
<div v-resize="OnResize">
<v-container class="px-5 px-sm-3 px-md-3 px-lg-3">
<div :class="isIpad ? 'd-flex flex-column-reverse' : 'pt-lg-5 pb-lg-2'">
<div :class="newUser ? 'pt-lg-6 mt-lg-12' : ''">
<v-row>
<v-col cols="12" lg="9" md="12" sm="12" ref="divOne" class="py-0">
<div v-if="categoryListIdWise">
<BreadcrumbComponent :breadcrumbVal="breadcrumbData" :key="breadcrumbData" />
</div>
</v-col>
</v-row>
</div>
<CategoryHeroContent v-if="!isMobile" :categoryContent="categoryPageContent"></CategoryHeroContent>
</div>
<v-row v-if="isIpadOrMobile && searchResults.page.length">
<v-col cols="12" class="pa-0">
<v-col cols="12" sm="4" >
<span>
<ul class="pl-0" v-for="(value, index) in enabledFilters" :key="index">
<li class="d-flex justify-space-between pb-1" v-if="value.label !='Category'">
<div>
<b>
<span class="text-uppercase">{{ value.label }}</span>
</b>
: {{ value.value }}
</div>
<v-hover v-slot:default="{ hover }">
<v-icon
:color="hover ? 'primary' : ''"
@click.stop="deleteFilter(value,index)"
class="searchproducts-cancel-buttons cursor-pointer transparent-background"
>mdi-close</v-icon>
</v-hover>
</li>
</ul>
</span>
</v-col>
</v-col>
<v-col cols="12" sm="4" class="d-lg-none pt-1 pb-5">
<v-menu
allow-overflow
id="filterSelect"
offset-y
:close-on-content-click="closeFilterMenu"
>
<template v-slot:activator="{ on, attrs }">
<v-select
v-bind="attrs"
v-on="on"
class="word-break fontsize-16 line-height-21 ls-n009 font-weight-400 categorybaseproducts-filter-button select-change-icon"
dense
attach="#filterSelect"
flat
solo
single-line
background-color="transparent"
append-icon="mdi-plus"
label="FILTERS"
color="primary"
@click="setFilterValue"
></v-select>
</template>
<v-list class="categorybaseproducts-filter-options mx-auto">
<v-list-item>
<v-list-item-title class="filter-component-width">
<v-row>
<v-col cols="12">
<v-btn
block
class="text-uppercase ls-0 body pb-1 productpage-button"
outlined
:class="
checkClear ? 'white--text primary' : 'primary--text'
"
tile
depressed
@click="clearFilter()"
>CLEAR</v-btn>
</v-col>
</v-row>
<FilterComponent
@clearAction="actionClear"
:filterList="availalableFilters"
:inProgress="inProgress"
:enabledFilters="enabledFilters"
@applyNewFilter="applyFilter"
></FilterComponent>
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-col>
<v-col lg="10" md="4" sm="4" cols="3" class="pt-0 pb-4 pr-0 pr-sm-2">
<p
class="text-uppercase Whyte-Regular primary--text my-3 mr-1 fontsize-16 ls-n01 font-weight-400 categorypage_fontcolor_greyshade8b searchproducts-sortby"
:class="isIpad ? 'float-right' : 'float-left'"
>Sort by:</p>
</v-col>
<v-col cols="9" lg="2" md="4" sm="4" class="py-0 pt-1 pl-3 pr-3">
<v-select
:items="criteria"
class="word-break fontsize-16 line-height-21 ls-n009 font-weight-400 categorybaseproducts-sortby-button select-change-icon regular-font"
dense
flat
attach
solo
ref="sortAndNextPage"
@change="sortAndNextPage()"
item-text="label"
item-value="value"
background-color="transparent"
v-model="sortBy"
append-icon="mdi-plus"
></v-select>
</v-col>
<v-col md="12" sm="12" cols="12" class="py-0">
<p
class="h3 regular-font mb-1"
v-if="searchPageContent"
>Search results for : '{{ keywords }}'</p>
</v-col>
</v-row>
<CategoryHeroContent v-if="isMobile" :categoryContent="categoryPageContent"></CategoryHeroContent>
<v-row class="d-none d-sm-flex" v-if="!isIpadOrMobile">
<v-col cols="12" lg="3" md="4" sm="4">
<span>
<ul class="pl-0" v-for="(value, index) in enabledFilters" :key="index">
<li class="d-flex justify-space-between pb-1" v-if="value.label !='Category'">
<div>
<b>
<span class="text-uppercase">{{ value.label }}</span>
</b>
: {{ value.value }}
</div>
<v-hover v-slot:default="{ hover }">
<v-icon
:color="hover ? 'primary' : ''"
@click.stop="deleteFilter(value,index)"
class="ccategorybaseproduct-cancel-buttons cursor-pointer"
>mdi-close</v-icon>
</v-hover>
</li>
</ul>
</span>
</v-col>
</v-row>
<v-row v-if="searchResults.page.length">
<v-col lg="3" md="1" sm="1" class="d-none d-lg-block pt-12 pr-md-12">
<v-row justify="center" class="pt-6">
<FilterComponent
:filterList="availalableFilters"
:inProgress="inProgress"
:enabledFilters="enabledFilters"
@applyNewFilter="applyFilter"
/>
</v-row>
</v-col>
<v-col cols="12" lg="9" md="12" sm="12" class="pl-lg-12" ref="divOnesecond">
<v-row>
<v-row v-if="!isIpadOrMobile" align="center" >
<v-col lg="6" md="4" sm="4" cols="4" class="py-0">
<p
class="h3 regular-font mb-1"
v-if="searchPageContent"
>Search results for : '{{ keywords }}'</p>
</v-col>
<v-col lg="2" md="4" sm="4" cols="4" class="py-0">
<p
class="text-uppercase primary--text my-3 mr-2 fontsize-14 body float-right ls-n01 font-weight-400 categorypage_fontcolor_greyshade8b"
>Sort by:</p>
</v-col>
<v-col lg="4" md="3" sm="3" cols="4" class="py-0 pt-1 pl-2 pr-7">
<v-select
:items="criteria"
class="word-break fontsize-16 line-height-21 ls-n009 font-weight-400 categorybaseproducts-sortby-button categorybaseproducts-select-button select-change-icon regular-font"
dense
attach
flat
solo
ref="sortAndNextPage"
@change="sortAndNextPage()"
item-text="label"
item-value="value"
background-color="transparent"
v-model="sortBy"
append-icon="mdi-plus"
></v-select>
</v-col>
</v-row>
</v-row>
<v-row v-if="inProgress">
<v-col
v-for="(i, index) in 9"
v-bind:key="index"
lg="4"
md="4"
sm="4"
cols="12"
class="pr-lg-4 cursor-pointer"
>
<v-skeleton-loader type="card"></v-skeleton-loader>
</v-col>
</v-row>
<v-row v-if="searchResults.page.length > 0">
<v-col
v-for="(product, index) in searchResults.page"
v-bind:key="index"
lg="4"
md="4"
sm="4"
cols="12"
class="pr-lg-4 cursor-pointer pt-lg-6"
@click="gotoProductDetails(product.n)"
>
<v-img
:src="imageBasePathUrl + product.i + imageBaseParams"
width="100%"
:alt="product.n"
:title="product.n"
></v-img>
<v-row>
<v-col cols="7" class="pb-0">
<h1
class="float-left fontsize-14 body ls-n009 fontcolor-black-darken font-weight-300 word-break"
>{{ product.n }}</h1>
</v-col>
<v-col cols="5" class="pb-0">
<p
v-if="product.lp"
class="float-right fontsize-14 body ls-n009 fontcolor-black-darken font-weight-300"
>
From ${{ product.lp }}
{{ product.u }}
</p>
<div
v-else
class="float-right fontsize-14 body ls-n009 fontcolor-black-darken font-weight-300"
>
<div v-if="product.sp">
<s>${{ product.p }}</s> &nbsp;
<p class="red--text mb-0">${{ roundUp(product.sp) }}</p>
/ {{ product.u }}
</div>
<div v-else-if="product.p != 0">
<p>
${{ product.p }} /
{{ product.u }}
</p>
</div>
<div v-else>
<p>TBD</p>
</div>
</div>
</v-col>
</v-row>
</v-col>
</v-row>
<v-row class="pr-5">
<v-col cols="12" sm="6" md="8" lg="8">
<v-col
cols="12"
sm="6"
md="8"
lg="8"
class="pa-0 custom-pagination d-flex flex-column"
>
<v-pagination
v-if="pageSize != 'ALL'"
prev-icon="Previous"
next-icon="Next"
class="categorybaseproducts-pagination-button d-flex justify-flex-start"
v-model="pageNumber"
:length="totalVisiblePages"
elevation="0"
@input="pageViewChange()"
circle
></v-pagination>
</v-col>
</v-col>
<v-col sm="6" md="4" lg="4" class="pt-0 d-none d-sm-block">
<v-row align="center" justify="end">
<p
class="mr-2 text-uppercase fontsize-14 ls-n01 font-weight-400 fontcolor-black-darken pt-6"
>Show:</p>
<v-overflow-btn
class="fontsize-16 body ls-n01 transparent-background fontcolor-black-darken categorybaseproducts-overflow-button"
:items="pageNum"
label="9"
v-model="pageSize"
flat
target="#dropdown-example"
height="36"
@change="pageSizeWiseProduct()"
></v-overflow-btn>
<p
class="ml-2 text-uppercase fontsize-14 ls-n01 font-weight-400 fontcolor-grey-shade8b pt-6"
>Per Page</p>
</v-row>
</v-col>
</v-row>
</v-col>
</v-row>
<v-row v-else class="text-center">
<v-col
lg="12"
md="12"
sm="12"
cols="12">
<v-alert type="error" text class="font-weight-300 body-font h3">{{
noProducts
}}</v-alert>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
/* eslint-disable no-alert, no-console , no-debugger */
//import * as easings from "vuetify/es5/services/goto/easing-patterns";
import BreadcrumbComponent from "@/components/retailer/breadcrumb/Breadcrumb.vue";
import { createHelpers } from "vuex-map-fields";
import { mapState } from "vuex";
import CategoryHeroContent from "@/components/retailer/category/CategoryHeroContent.vue";
import FilterComponent from "@/components/retailer/filter/FilterComponent.vue";
const { mapFields } = createHelpers({
getterType: "catalogBrowser/getField",
mutationType: "catalogBrowser/updateField"
});
export default {
name: "SearchProductsComponent",
components: {
FilterComponent,
CategoryHeroContent,
BreadcrumbComponent
},
props: [
"criteria",
"searchPageContent",
"breadcrumbData",
"categoryPageContent"
],
computed: {
...mapState({
searchResults: state => state.catalogBrowser.searchResults,
enabledFilters: state => state.catalogBrowser.enabledFilters,
searchTerms: state => state.catalogBrowser.searchTerms,
inProgress: state => state.catalogBrowser.inProgress,
totalProducts: state => state.catalogBrowser.totalItems,
availalableFilters: state => state.catalogBrowser.availalableFilters
}),
...mapFields([
"searchTerms",
"searchTerms.pageNumber",
"searchTerms.pageSize",
"searchTerms.keywords",
"searchTerms.sortBy",
"searchTerms.filters"
]),
easingOptions() {
return {
duration: this.duration,
easing: this.easing
};
},
categoryListIdWise: function() {
return this.$store.state.headerCategoryList.categoryListIdWise;
},
imageBasePathUrl() {
return import.meta.env.VITE_APP_IMAGE_PATH_URL;
},
imageBaseParams() {
return import.meta.env.VITE_APP_IMAGE_CATEGORY_PARAMS;
},
isIpadOrMobile: function() {
return this.$vuetify.display.mdAndDown ? true : false;
},
isIpad: function() {
return this.$vuetify.display.smOnly || this.$vuetify.display.mdOnly
? true
: false;
},
isMobile: function() {
return this.$vuetify.display.xs ? true : false;
},
categoryId: function() {
return this.$route.meta.id;
},
newUser() {
if (this.$vuetify.display.smAndDown) return false;
let userVisits = this.$store.state.layout.user.userVisits;
if (userVisits && Number(userVisits) > 1) return false;
else return true;
}
},
watch: {
totalProducts() {
if (this.pageSize != "ALL") {
this.totalVisiblePages = Math.ceil(
this.totalProducts / Number(this.pageSize)
);
// this.updatePageNumber();
}
},
searchResults(){
// googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
},
keywords(){
// googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
},
categoryId(){
// googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
},
pageSize() {
if (this.pageSize != "ALL" && this.totalProducts) {
this.totalVisiblePages = Math.ceil(
this.totalProducts / Number(this.pageSize)
);
}
}
},
data: () => ({
closeFilterMenu: false,
checkClear: false,
easing: "easeInOutCubic",
easings: Object.keys(easings),
duration: 100,
totalVisiblePages: 0,
menu: false,
showDrawarFilter: false,
pageNum: [
{ text: 9, callback: () => 9 },
{ text: 18, callback: () => 18 },
{ text: 27, callback: () => 27 },
{ text: "ALL", callback: () => "ALL" }
],
noProducts: "No products found.",
}),
methods: {
async clearFilter() {
await this.$store.dispatch("catalogBrowser/clearFilter");
this.closeFilterMenu = true;
this.pageNumber=1;
this.$emit("criteriaChanged");
},
async deleteFilter(value,index) {
await this.$store.dispatch("catalogBrowser/deleteSelectedFilter", {
index: index
});
this.pageNumber=1;
this.$emit("criteriaChanged");
// googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
},
setFilterValue() {
this.closeFilterMenu = false;
},
async applyFilter(filterObj) {
await this.$store.dispatch("catalogBrowser/setNewFilter", filterObj);
this.closeFilterMenu = true;
this.pageNumber=1;
this.$emit("criteriaChanged");
// googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
},
async actionClear() {
await this.$store.dispatch("catalogBrowser/clearFilter");
this.closeFilterMenu = true;
},
OnResize() {
setTimeout(() => {
if (this.$vuetify.display.lgAndUp) {
this.showDrawarFilter = false;
}
}, 200);
},
gotoProductDetails(productName) {
// googleAanalyticsEventSelectContent('select_content',product,this.categoryId)
this.$router.push({
name: productName,
query: {
categoryId: this.categoryId,
}
});
},
pageViewChange() {
this.$emit("criteriaChanged");
//googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
},
pageSizeWiseProduct() {
this.updatePageNumber();
this.$emit("criteriaChanged");
// googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
},
sortAndNextPage() {
this.$emit("criteriaChanged");
//googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
},
scrollToTop() {
window.scrollTo(0, 0);
},
updatePageNumber() {
if (this.pageNumber * Number(this.pageSize) > this.totalProducts) {
let quotient = Math.floor(this.totalProducts / Number(this.pageSize));
let remainder = this.totalProducts % Number(this.pageSize);
this.pageNumber = quotient + (remainder == 0 ? 0 : 1);
} else {
//this.pageNumber = Number(this.$route.query.pageNumber);
}
},
roundUp(num) {
var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0];
return with2Decimals;
}
},
created() {
if(this.searchTerms)
{
// googleAanalyticsEventCategoryPage(this.searchResults.page,this.categoryId)
}
if (this.totalProducts)
this.totalVisiblePages = Math.ceil(
this.totalProducts / Number(this.pageSize)
);
}
};
</script>
<style lang="scss" >
.sort-button.theme--light.v-text-field--solo
> .v-input__control
> .v-input__slot {
background: transparent !important;
}
.categorybaseproducts-pagination-button .v-pagination__item--active {
outline: #ffffff !important;
}
.categorybaseproducts-pagination-button .v-pagination__item {
outline: #ffffff !important;
box-shadow: none !important;
padding: 0px !important;
margin: 0px !important;
}
.categorybaseproducts-pagination-button {
justify-content: flex-start;
}
.categorybaseproducts-overflow-button .v-select__slot {
border-left: 1px solid #dcdddd !important;
border-right: 1px solid #dcdddd !important;
max-width: 85px !important;
max-height: 36px !important;
}
.categorybaseproducts-overflow-button {
max-width: 85px !important;
}
.categorybaseproducts-overflow-button .v-select__slot .v-input__append-inner {
max-height: 36px !important;
}
.categorybaseproducts-overflow-button .v-overflow-btn .v-select__slot {
max-height: 36px !important;
}
.categorybaseproducts-overflow-button .v-text-field__details {
display: none;
}
.categorybaseproducts-pagination-button
.v-pagination__navigation.v-pagination__navigation--disabled {
display: none;
}
.categorybaseproducts-pagination-button
.v-pagination__navigation
.v-icon.v-icon {
font-style: normal !important;
color: #1d1d1d !important;
text-transform: uppercase !important;
font-size: 14px;
font-family: "Whyte-Regular", sans-serif;
letter-spacing: -0.1px;
}
.categorybaseproducts-select-button .v-input__control .v-input__slot {
border: thin solid #8b8b8b !important;
}
.categorybaseproducts-select-button:hover .v-input__control .v-input__slot {
border: thin solid #2850da !important;
}
.categorybaseproducts-select-button.v-input--is-label-active.v-input--is-focused
.v-input__control
.v-input__slot {
border: thin solid #2850da !important;
}
.categorybaseproducts-select-button:hover
.v-select__selection.v-select__selection--comma {
color: #2850da !important;
}
.categorybaseproducts-select-button:hover
.v-input__append-inner
.v-input__icon
.v-icon {
color: #2850da !important;
}
.categorybaseproducts-pagination-button .v-pagination__navigation {
outline: #ffffff !important;
box-shadow: none !important;
padding: 0px !important;
//margin: 0px 10px !important;
}
.custom-pagination li:nth-child(1) {
margin-right: 15px !important;
margin-left: 15px;
}
.categorybaseproducts-select-button.v-input--is-label-active.v-input--is-focused
.v-select__selection.v-select__selection--comma {
color: #2850da !important;
}
.categorybaseproducts-sortby-button.theme--light.v-select
.v-select__selection--comma {
color: #2850da !important;
}
.categorybaseproducts-sortby-button .v-text-field__details {
display: none;
}
.categorybaseproducts-sortby-button .v-input__control .v-input__slot {
border: thin solid #2850da !important;
}
.categorybaseproducts-sortby-button:hover .v-input__control .v-input__slot {
border: thin solid #2850da !important;
}
.categorybaseproducts-sortby-button.v-input--is-label-active.v-input--is-focused
.v-input__control
.v-input__slot {
border: thin solid #2850da !important;
}
.categorybaseproducts-sortby-button:hover
.v-select__selection.v-select__selection--comma {
color: #2850da !important;
}
.categorybaseproducts-sortby-button:hover
.v-input__append-inner
.v-input__icon
.v-icon {
color: #2850da !important;
}
.categorybaseproducts-sortby-button
.v-input__append-inner
.v-input__icon
.v-icon {
color: #2850da !important;
}
.categorybaseproducts-sortby-button.v-input--is-label-active.v-input--is-focused
.v-select__selection.v-select__selection--comma {
color: #2850da !important;
}
.categorybaseproducts-sortby-button.v-input--is-label-active.v-input--is-focused.v-text-field.v-text-field--solo
.v-input__append-inner,
.v-text-field.v-text-field--solo .v-input__prepend-inner {
-ms-flex-item-align: center;
align-self: center;
padding-top: 5px;
border-left: 1px solid #2850da;
padding-left: 10px;
height: 34px;
}
.categorybaseproducts-select-button.v-input--is-label-active.v-input--is-focused.v-text-field.v-text-field--solo
.v-input__append-inner,
.v-text-field.v-text-field--solo .v-input__prepend-inner {
-ms-flex-item-align: center;
align-self: center;
padding-top: 5px;
border-left: 1px solid #2850da;
padding-left: 10px;
height: 34px;
}
.searchproducts-cancel-buttons.v-icon.v-icon::after {
opacity: 0 !important;
}
.categorybaseproducts-sortby-button .v-text-field__details {
display: none;
}
.categorybaseproducts-overflow-button .v-text-field__details {
display: none;
}
.categorybaseproducts-filter-button .v-text-field__details {
display: none;
}
.filter-component-width .v-expansion-panels {
display: inline-block;
}
// .v-text-field__details {
// display: none;
// }
</style>
<style src="./SearchProducts.scss" lang="scss" scoped />