You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
502 lines
16 KiB
502 lines
16 KiB
<template>
|
|
<div
|
|
class="tw-px-[30px] tw-mt-[30px] tw-mb-[60px] md:tw-mb-[100px] xl:tw-px-[60px] xl:tw-max-w-screen-xl xl:tw-mx-auto xl:tw-grid xl:tw-grid-cols-[380px_auto] xl:tw-gap-[30px]">
|
|
<section class="xl:tw-col-span-2 tw-mb-[36px] md:tw-mb-[24px] lg:tw-mb-[34px]">
|
|
<Breadcrumbs></Breadcrumbs>
|
|
<sort :results="result" :sortType="sortType" :sortBy="sortBy" @change="updateSortBy($event)"
|
|
@filter="$modal.show(`sidebar-filter-modal`)"></sort>
|
|
</section>
|
|
<section class="tw-grid tw-grid-cols-1 tw-gap-[30px] tw-auto-rows-min">
|
|
<div v-if="$vuetify.breakpoint.xl">
|
|
<oneLevel :label="'Categories'" :list="categoryList" :queryItem="categoryQueryFilter"
|
|
@update="updateCategoryFilter"></oneLevel>
|
|
</div>
|
|
<div v-if="$vuetify.breakpoint.xl">
|
|
<multipleLevel :label="'Location'" :placeholder="$t('Find country/city ...')" :list="locationList"
|
|
:queryItem="locationQueryFilter" @update="updateLocationFilter"></multipleLevel>
|
|
</div>
|
|
<div v-if="$vuetify.breakpoint.xl">
|
|
<price :max="maxPrice" :currentValue="priceRangeFilter" @update="updatePriceRange"></price>
|
|
</div>
|
|
<div v-if="$vuetify.breakpoint.xl">
|
|
<!-- <rating @update="updateRatingRange"></rating> -->
|
|
</div>
|
|
</section>
|
|
<section class="">
|
|
<ServiceListCard class="tw-mb-[30px]" v-for="(item, index) in renderList" :key="index" :service="item">
|
|
</ServiceListCard>
|
|
<div class="tw-mt-[34px] tw-flex tw-justify-end">
|
|
<pagination :pageLength="pageLength" @update="updateCurrentPage"></pagination>
|
|
</div>
|
|
</section>
|
|
<div v-if="!$vuetify.breakpoint.xl">
|
|
<sidebarFilterModal :max="maxPrice" :locationList="locationList" :categoryList="categoryList"
|
|
:locationChecked="locationNameFilter" :categoryChecked="categoryFilter" :priceChecked="priceRangeFilter"
|
|
@updatePriceRange="updatePriceRange" @updateCategoryFilter="updateCategoryFilter"
|
|
@updateLocationFilter="updateLocationFilter"></sidebarFilterModal>
|
|
</div>
|
|
<loading :isLoading="isPageLoading"></loading>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import Breadcrumbs from "@/components/Breadcrumbs";
|
|
import sort from "@/components/newComponent/sort/sort";
|
|
import oneLevel from "@/components/newComponent/filter/oneLevel";
|
|
import multipleLevel from "@/components/newComponent/filter/multipleLevel";
|
|
import price from "@/components/newComponent/filter/price";
|
|
import rating from "@/components/newComponent/filter/rating.vue";
|
|
import pagination from "@/components/newComponent/pagination/pagination.vue";
|
|
import sidebarFilterModal from "@/components/newComponent/modal/sidebarFilterModal.vue";
|
|
import ServiceListCard from "@/components/service/ServiceListCard";
|
|
import loading from "@/components/newComponent/loading/loading.vue";
|
|
|
|
export default {
|
|
name: "ServiceList",
|
|
auth: false,
|
|
components: {
|
|
Breadcrumbs,
|
|
sort,
|
|
oneLevel,
|
|
multipleLevel,
|
|
price,
|
|
rating,
|
|
sidebarFilterModal,
|
|
ServiceListCard,
|
|
pagination,
|
|
loading,
|
|
},
|
|
meta: {
|
|
pageName: "Service List",
|
|
},
|
|
data() {
|
|
return {
|
|
serviceList: [],
|
|
sortType: [
|
|
// { name: "Ratings", value: "Ratings" },
|
|
// { name: "ShowEasy Recommended", value: "ShowEasy Recommended" },
|
|
{ name: "Popularity", value: "Popularity" },
|
|
{ name: "Price (Low to High)", value: "Price" },
|
|
{ name: "Recently Added", value: "Recently Added" },
|
|
],
|
|
locationList: [],
|
|
categoryList: [],
|
|
regionNameList: [],
|
|
countryNameList: [],
|
|
cityNameList: [],
|
|
categoryNameList: [],
|
|
subcategoryNameList: [],
|
|
sortBy: "Ratings",
|
|
maxPrice: 100,
|
|
priceRangeFilter: [],
|
|
ratingRangeFilter: [0, 5],
|
|
locationNameFilter: [],
|
|
categoryFilter: [],
|
|
userSavedServices: [],
|
|
perPageItems: 10,
|
|
currentPage: 1,
|
|
locationQueryFilter: "",
|
|
categoryQueryFilter: "",
|
|
isPageLoading: false,
|
|
};
|
|
},
|
|
async created() {
|
|
this.isPageLoading = true;
|
|
// await this.getLocationList();
|
|
// await this.getUnSortLocationList();
|
|
// await this.getCategoryList();
|
|
// await this.getUnSortCategoryList();
|
|
// await this.getUserSavedService();
|
|
// await this.getServiceList();
|
|
await this.getPriceRange();
|
|
await this.getQuery();
|
|
},
|
|
mounted() { },
|
|
computed: {
|
|
serviceFilter() {
|
|
var vm = this;
|
|
if (Array.isArray(vm.serviceList)) {
|
|
const priceList = vm.filterByPrice(
|
|
vm.serviceList,
|
|
vm.priceRangeFilter[0],
|
|
vm.priceRangeFilter[1]
|
|
);
|
|
const locationList = vm.filterByLocation(
|
|
priceList,
|
|
vm.locationNameFilter
|
|
);
|
|
const categoryList = vm.filterByCategory(
|
|
locationList,
|
|
vm.categoryFilter
|
|
);
|
|
const sortedList = vm.sortServiceList(categoryList);
|
|
return sortedList;
|
|
} else {
|
|
return [];
|
|
}
|
|
},
|
|
result() {
|
|
return this.serviceFilter.length;
|
|
},
|
|
pageLength() {
|
|
return Math.ceil(this.result / this.perPageItems);
|
|
},
|
|
renderList() {
|
|
return this.sliceRenderList(this.serviceFilter);
|
|
},
|
|
currency() {
|
|
return this.$store.getters.getCurrency;
|
|
},
|
|
},
|
|
watch: {
|
|
currency: {
|
|
handler: async function (newVal, oldVal) {
|
|
if (newVal !== oldVal) {
|
|
await this.getServiceList();
|
|
this.serviceList = await this.mapServiceLocationName(
|
|
this.serviceList,
|
|
this.countryNameList,
|
|
this.cityNameList
|
|
);
|
|
this.serviceList = await this.mapServiceCategoryName(
|
|
this.serviceList,
|
|
this.categoryNameList
|
|
);
|
|
await this.getPriceRange();
|
|
}
|
|
},
|
|
},
|
|
$route: {
|
|
handler: function () {
|
|
this.getQuery();
|
|
},
|
|
},
|
|
},
|
|
methods: {
|
|
async getServiceList() {
|
|
let keyword = "";
|
|
let category = "";
|
|
let subcatg = "";
|
|
if (this.$route.query.q) {
|
|
keyword = "&keyword=" + this.$route.query.q;
|
|
}
|
|
if (this.$route.query.category) {
|
|
category = "&category=" + this.$route.query.category;
|
|
}
|
|
if (this.$route.query.subcatg) {
|
|
subcatg = "&subcatg=" + this.$route.query.subcatg;
|
|
}
|
|
if (this.$route.query.category) {
|
|
category = "&category=" + this.$route.query.category;
|
|
}
|
|
if (this.$route.query.subcatg) {
|
|
subcatg = "&subcatg=" + this.$route.query.subcatg;
|
|
}
|
|
await this.$axios
|
|
.get(
|
|
`${process.env.SERVICE_CONSOLE}/user-services/list?lang_code=${this.$i18n.localeProperties["langQuery"]}¤cy=${this.currency}${keyword}${category}${subcatg}`
|
|
)
|
|
.then((result) => {
|
|
this.serviceList = result.data;
|
|
this.serviceList = this.mapServiceLocationName(
|
|
this.serviceList,
|
|
this.countryNameList,
|
|
this.cityNameList
|
|
);
|
|
this.serviceList = this.mapServiceCategoryName(
|
|
this.serviceList,
|
|
this.categoryNameList
|
|
);
|
|
this.serviceList = this.mapSavedService(
|
|
this.serviceList,
|
|
this.userSavedServices
|
|
);
|
|
this.isPageLoading = false;
|
|
return result.data;
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
});
|
|
},
|
|
async getUserSavedService() {
|
|
if (this.$auth.loggedIn) {
|
|
await this.$axios
|
|
.get(
|
|
`member/services?jwt=${this.$auth.$storage.getUniversal("jwt").token
|
|
}&lang_code=${this.$i18n.localeProperties["langQuery"]}`
|
|
)
|
|
.then((res) => {
|
|
this.userSavedServices = res.data.service_ids;
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
});
|
|
}
|
|
},
|
|
async getCategoryList() {
|
|
await this.$axios
|
|
.get(
|
|
`/service/category?lang_code=${this.$i18n.localeProperties["langQuery"]}`
|
|
)
|
|
.then((result) => {
|
|
var vm = this;
|
|
const lang = vm.$i18n.localeProperties.langQuery;
|
|
vm.categoryList = result.data.map((item) => {
|
|
return {
|
|
id: item.id,
|
|
title: item.language_text[0].text,
|
|
key: item.language_text[0].text,
|
|
};
|
|
});
|
|
|
|
// vm.categoryList = result.data.sort_results;
|
|
// vm.categoryList = vm.categoryList.map((item) => {
|
|
// item.subcategories_list = item.subcategories_list.map(
|
|
// (children) => {
|
|
// return {
|
|
// title: children.subcategory_name,
|
|
// key: children.subcategory_name,
|
|
// };
|
|
// }
|
|
// );
|
|
// return {
|
|
// title: item.category_name,
|
|
// key: item.category_name,
|
|
// children: item.subcategories_list,
|
|
// };
|
|
// });
|
|
return result.data;
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
});
|
|
},
|
|
async getLocationList() {
|
|
await this.$axios
|
|
.get(
|
|
`/t/exhibitions/locations?lang=${this.$i18n.localeProperties["langQuery"]}&sort=true`
|
|
)
|
|
.then((result) => {
|
|
var vm = this;
|
|
vm.locationList = result.data.sort_results;
|
|
vm.locationList = vm.locationList.map((item) => {
|
|
item.country_list = item.country_list.map((country) => {
|
|
country.city_list = country.city_list.map((city) => {
|
|
return {
|
|
title: city.city_name,
|
|
key: city.city_name,
|
|
};
|
|
});
|
|
return {
|
|
title: country.country_name,
|
|
key: country.country_name,
|
|
children: country.city_list,
|
|
};
|
|
});
|
|
return {
|
|
title: item.region_name,
|
|
key: item.region_name,
|
|
children: item.country_list,
|
|
};
|
|
});
|
|
return result.data;
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
});
|
|
},
|
|
async getUnSortLocationList() {
|
|
await this.$axios
|
|
.get(
|
|
`/t/exhibitions/locations?lang=${this.$i18n.localeProperties["langQuery"]}&sort=false`
|
|
)
|
|
.then((result) => {
|
|
this.countryNameList = result.data.country_name_list;
|
|
this.cityNameList = result.data.city_name_list;
|
|
this.regionNameList = result.data.region_name_list;
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
});
|
|
},
|
|
async getUnSortCategoryList() {
|
|
this.categoryNameList[0] = null;
|
|
for (const item of this.categoryList) {
|
|
this.categoryNameList[item.id] = item.title;
|
|
}
|
|
// await this.$axios
|
|
// .get(
|
|
// `/t/exhibitions/categories?lang=${this.$i18n.localeProperties["langQuery"]}&sort=false`
|
|
// )
|
|
// .then((result) => {
|
|
// this.categoryNameList = result.data.category_name_list;
|
|
// this.subcategoryNameList = result.data.subcategory_name_list;
|
|
// })
|
|
// .catch((err) => {
|
|
// console.log(err);
|
|
// });
|
|
},
|
|
updateSortBy(data) {
|
|
this.sortBy = data;
|
|
},
|
|
sortServiceList(data) {
|
|
switch (this.sortBy) {
|
|
case "Ratings":
|
|
function Ratings(a, b) {
|
|
if (Number(a.rating) < Number(b.rating)) return 1;
|
|
if (Number(a.rating) > Number(b.rating)) return -1;
|
|
return 0;
|
|
}
|
|
return data.sort(Ratings);
|
|
case "ShowEasy Recommended":
|
|
return data;
|
|
case "Popularity":
|
|
function Views(a, b) {
|
|
if (Number(a.view_counts) < Number(b.view_counts)) return 1;
|
|
if (Number(a.view_counts) > Number(b.view_counts)) return -1;
|
|
return 0;
|
|
}
|
|
return data.sort(Views);
|
|
case "Price":
|
|
function Price(a, b) {
|
|
if (Number(a.price) < Number(b.price)) return -1;
|
|
if (Number(a.price) > Number(b.price)) return 1;
|
|
return 0;
|
|
}
|
|
return data.sort(Price);
|
|
case "Recently Added":
|
|
function Date(a, b) {
|
|
if (
|
|
a.launch_dates[0].replace(/-/g, "") <
|
|
b.launch_dates[0].replace(/-/g, "")
|
|
)
|
|
return 1;
|
|
if (
|
|
a.launch_dates[0].replace(/-/g, "") >
|
|
b.launch_dates[0].replace(/-/g, "")
|
|
)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
return data.sort(Date);
|
|
default:
|
|
return data;
|
|
}
|
|
},
|
|
mapSavedService(data, savedList) {
|
|
return data.map((item) => {
|
|
item.liked = false;
|
|
if (savedList.includes(item.id)) {
|
|
item.liked = true;
|
|
}
|
|
return item;
|
|
});
|
|
},
|
|
mapServiceLocationName(data, countryList, cityList) {
|
|
data = data.map((item) => {
|
|
Number(item.country) > 0
|
|
? (item.countryName = countryList[item.country])
|
|
: (item.countryName = "");
|
|
return item;
|
|
});
|
|
data = data.map((item) => {
|
|
Number(item.city) > 0
|
|
? (item.cityName = cityList[item.city])
|
|
: (item.cityName = "");
|
|
return item;
|
|
});
|
|
return data;
|
|
},
|
|
mapServiceCategoryName(data, categoryList) {
|
|
data = data.map((item) => {
|
|
Number(item.category) > 0
|
|
? (item.categoryName = categoryList[item.category])
|
|
: (item.categoryName = "");
|
|
return item;
|
|
});
|
|
return data;
|
|
},
|
|
async getPriceRange() {
|
|
let max = 0;
|
|
this.serviceList.forEach((element) => {
|
|
if (element.price > max) {
|
|
max = element.price;
|
|
}
|
|
});
|
|
this.maxPrice = max;
|
|
this.priceRangeFilter = [0, max];
|
|
},
|
|
filterByPrice(data, min, max) {
|
|
return data.filter((item) => item.price >= min && item.price <= max);
|
|
},
|
|
updatePriceRange(value) {
|
|
this.priceRangeFilter = [...value];
|
|
},
|
|
filterByRating(data, min, max) {
|
|
return data.filter((item) => item.price >= min && item.price <= max);
|
|
},
|
|
updateRatingRange(value) {
|
|
console.log(value);
|
|
},
|
|
filterByLocation(data, locations) {
|
|
if (locations.length < 1) {
|
|
return data;
|
|
} else {
|
|
return data.filter(
|
|
(item) =>
|
|
locations.includes(item.cityName) ||
|
|
locations.includes(item.countryName)
|
|
);
|
|
}
|
|
},
|
|
updateLocationFilter(value) {
|
|
this.locationNameFilter = value;
|
|
},
|
|
filterByCategory(data, categories) {
|
|
if (categories.length < 1) {
|
|
return data;
|
|
} else {
|
|
return data.filter((item) => categories.includes(item.categoryName));
|
|
}
|
|
},
|
|
updateCategoryFilter(value) {
|
|
this.categoryFilter = value;
|
|
},
|
|
updateCurrentPage(value) {
|
|
this.currentPage = value;
|
|
},
|
|
sliceRenderList(data) {
|
|
return data.slice(
|
|
(this.currentPage - 1) * this.perPageItems,
|
|
this.currentPage * this.perPageItems
|
|
);
|
|
},
|
|
async getQuery() {
|
|
this.locationQueryFilter = "";
|
|
this.categoryQueryFilter = "";
|
|
if (this.$route.query.hasOwnProperty("country")) {
|
|
this.locationQueryFilter =
|
|
this.countryNameList[Number(this.$route.query.country)];
|
|
}
|
|
if (this.$route.query.hasOwnProperty("city")) {
|
|
this.locationQueryFilter =
|
|
this.cityNameList[Number(this.$route.query.city)];
|
|
}
|
|
// if (this.$route.query.hasOwnProperty("region")) {
|
|
// this.locationQueryFilter =
|
|
// this.regionNameList[Number(this.$route.query.region)];
|
|
// }
|
|
if (this.$route.query.hasOwnProperty("category")) {
|
|
this.categoryQueryFilter =
|
|
this.categoryNameList[Number(this.$route.query.category)];
|
|
}
|
|
// if (this.$route.query.hasOwnProperty("subcategory")) {
|
|
// this.categoryQueryFilter =
|
|
// this.unsortSubcategoryList[Number(this.$route.query.subcategory)];
|
|
// }
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
|
|
</style>
|