|
|
<template> <div class="saveService xl:tw-max-w-[1246px] xl:tw-mx-auto"> <div class="xl:tw-flex xl:tw-justify-between xl:tw-items-start"> <userSidebar :userData="userData" :firstName="firstName" :lastName="lastName" class="tw-hidden xl:tw-block" > </userSidebar> <!-- <div class="xl:tw-hidden"></div> --> <div class="tw-bg-white xl:tw-p-[30px] xl:tw-rounded-[20px] xl:tw-min-w-[900px] xl:tw-max-w-[900px]" > <div class="tw-text-[20px] tw-font-bold tw-text-base-primary tw-mb-[20px] md:t24 md:tw-mb-[30px]" > <two-dots class="tw-mr-[30px]"></two-dots >{{ $t("userProfile.savedServices") }} </div> <section class="tw-mb-[80px] md:tw-mb-[30px] xl:tw-flex xl:tw-flex-row"> <div class="tw-mb-[20px] md:tw-mb-[30px] xl:tw-mr-[55px]"> <div class="tw-head-body tw-text-base-primary tw-mb-[10px] md:tw-text-[16px]" > Filter </div> <div class="md:tw-flex md:tw-flex-row"> <div class="tw-mb-[20px] md:tw-mb-0"> <select v-model="countrySelect" class="tw-w-[160px] tw-border tw-border-solid tw-border-neutrals-200 tw-rounded-[10px] tw-px-[15px] tw-py-[9px] tw-head-body tw-text-neutrals-500 tw-outline-none focus:tw-border-primary-1 md:tw-mr-[20px] md:tw-text-[16px]" > <option :value="0">All Countries</option> <option v-for="(item, index) in countryOptions" :key="index" :value="item.id" > {{ item.name }} </option> </select> <select v-model="citySelect" class="tw-w-[160px] tw-border tw-border-solid tw-border-neutrals-200 tw-rounded-[10px] tw-px-[15px] tw-py-[9px] tw-head-body tw-text-neutrals-500 tw-outline-none focus:tw-border-primary-1 md:tw-mr-[20px] md:tw-text-[16px]" > <option :value="0">All Cities</option> <option v-for="(item, index) in cityOptions" :key="index" :value="item.id" > {{ item.name }} </option> </select> </div> <select v-model="categorySelect" class="tw-w-[160px] tw-border tw-border-solid tw-border-neutrals-200 tw-rounded-[10px] tw-px-[15px] tw-py-[9px] tw-head-body tw-text-neutrals-500 tw-outline-none focus:tw-border-primary-1 md:tw-text-[16px]" > <option :value="0">All Categories</option> <option v-for="(item, index) in categoryOptions" :key="index" :value="item.id" > {{ item.name }} </option> </select> </div> </div> <div> <div class="tw-head-body tw-text-base-primary tw-mb-[10px] md:tw-text-[16px]" > Sort by </div> <select class="orangearrow tw-text-primary-1 tw-w-[260px] tw-border tw-border-solid tw-border-neutrals-200 tw-rounded-[10px] tw-px-[15px] tw-py-[9px] tw-head-body tw-outline-none focus:tw-border-primary-1 md:tw-text-[16px]" v-model="sortSelect" > <option v-for="(item, index) in sortBy" :key="index" :value="item.id" > {{ item.name }} </option> <!-- <option selected>Date : Newest to Oldest</option> <option>Date : Oldest to Newest</option> --> </select> </div> </section> <section class="tw-flex tw-flex-col tw-items-center tw-mb-[42px] md:tw-mb-[60px] xl:tw-mb-0" v-if="renderList.length === 0" > <img src="~/assets/svg/noServiceYet.svg" class="tw-max-w-[160px] md:tw-max-w-[210px] tw-mt-[60px]" alt="" /> <div class="tw-text-[16px] tw-text-neutrals-800 tw-mb-[50px] md:tw-text-[18px] md:tw-mb-[60px]" > No Services yet ... </div> <button class="tw-text-[16px] tw-bg-primary-1 tw-text-white tw-px-[16px] tw-py-[10px] tw-rounded-[12px]" > Explore with ShowEasy </button> </section> <section v-else> <ServiceListCard class="tw-mb-[20px]" v-for="(item, index) in renderList" :key="index" :service="item" @remove-relation="updateServiceList()" > </ServiceListCard> </section> <section class="tw-flex tw-justify-end tw-py-2 tw-px-[10px] tw-mb-5 md:tw-mb-[30px]" > <pagination :pageLength="pageLength" @update="updateCurrentPage" ></pagination> </section> <div v-if="expiredList.length > 0" class="tw-border-[1px] tw-border-b-[0px] tw-border-solid tw-border-neutral-200 tw-mb-[30px] tw-hidden xl:tw-block" ></div> <section class="tw-pt-[30px]" v-if="expiredList.length > 0"> <div class="tw-px-5 tw-py-[11px] tw-flex tw-justify-between tw-align-middle" > <div class="tw-body-2 tw-font-bold"> {{ $t("Expired") }} </div> <button class="tw-text-[18px] tw-bg-white tw-text-secondary-default tw-w-fit" @click="deleteAllExpiredService" > {{ $t("Delete all") }} </button> </div> <ServiceListCard class="tw-mt-[20px] tw-opacity-70" v-for="(item, index) in expiredList" :key="index" :service="item" @remove-relation="updateServiceList()" > </ServiceListCard> </section> </div> </div> </div> </template> <script> import TwoDots from "@/components/TwoDots"; import userSidebar from "@/components/user/userSidebar.vue"; import ServiceListCard from "@/components/service/ServiceListCard"; import pagination from "@/components/newComponent/pagination/pagination.vue"; export default { name: "saveService", layout: "profile", components: { TwoDots, userSidebar, ServiceListCard, pagination, }, data() { return { userData: {}, countries: [], cities: [], categories: [], countryOptions: [], cityOptions: [], categoryOptions: [], serviceList: [], expiredList: [], categoryNameList: [], countryNameList: [], cityNameList: [], categorySelect: 0, countrySelect: 0, citySelect: 0, sortSelect: 0, firstName: "", lastName: "", sortBy: [ { name: "Date : Newest to Oldest", id: 0, }, { name: "Date : Oldest to Newest", id: 1, }, ], currentPage: 1, perPageItems: 6, }; }, async created() { //this.$store.dispatch("updatePicture");
if (process.browser) { window.addEventListener("resize", this.handleResize); } this.handleResize(); // await this.fetchUserData();
// await this.fetchSortCountry();
// await this.getCategoryList();
// await this.fetchSavedService();
// await this.mapCountryOptions(this.serviceList, this.countries);
// await this.mapCityOptions(this.serviceList, this.cities);
// await this.mapCategoryOptions(this.serviceList, this.categories);
}, mounted() { this.$nextTick(() => { window.addEventListener("resize", this.onResize); }); }, destroyed() { if (process.browser) { window.removeEventListener("resize", this.handleResize); } }, computed: { windowWidth() { if (process.client) { this.width = window.innerWidth; } return this.width; }, serviceFilter() { const countryList = this.filterByCountry( this.serviceList, this.countrySelect ); const cityList = this.filterByCity(countryList, this.citySelect); const categoryList = this.filterByCategory(cityList, this.categorySelect); const sortList = this.sortServiceList(categoryList, this.sortSelect); return sortList; }, pageLength() { return Math.ceil(this.result / this.perPageItems); }, result() { return this.serviceFilter.length; }, renderList() { return this.sliceRenderList(this.serviceFilter); }, }, methods: { reloadPage() { this.tabs = "editPersonalInfo"; }, handleResize() { if (process.browser) { this.width = window.innerWidth; } }, async fetchSortCountry() { await this.$axios .get( `t/exhibitions/locations?lang=${this.$i18n.localeProperties["langQuery"]}&sort=False` ) .then((res) => { this.countries = res.data.country_ori; this.cities = res.data.city_ori; this.countryNameList = res.data.country_name_list; this.cityNameList = res.data.city_name_list; }) .catch((err) => { console.log(err); }); }, async fetchUserData() { await this.$axios .get( `/member/users/${ this.$auth.$storage.getUniversal("jwt").user_id }?jwt=${this.$auth.$storage.getUniversal("jwt").token}`
) .then((res) => { this.userData = res.data; this.firstName = res.data.first_name; this.lastName = res.data.last_name; }) .catch((err) => { console.log(err); }); }, async fetchSavedService() { await this.$axios .get( `/member/services?jwt=${ this.$auth.$storage.getUniversal("jwt").token }&lang_code=${this.$i18n.localeProperties["langQuery"]}`
) .then((result) => { this.serviceList = result.data.services; this.serviceList.forEach(function (item) { item.liked = true; item.isUserProfile = true; }); this.serviceList = this.mapServiceLocationName( this.serviceList, this.countryNameList, this.cityNameList ); this.serviceList = this.mapServiceCategoryName( this.serviceList, this.categoryNameList ); this.expiredList = this.getExpiredService(this.serviceList); const expiredIds = this.expiredList.map((item) => item.id); this.serviceList = this.serviceList.filter( (item) => !expiredIds.includes(item.id) ); }) .catch((err) => { this.serviceList = []; console.log(err); }); }, async mapCountryOptions(services, countries) { const countryIds = services.map((item) => item.country); this.countryOptions = countries.filter((item) => { return countryIds.includes(item.id); }); }, async mapCityOptions(services, cities) { const cityIds = services.map((item) => item.city); this.cityOptions = cities.filter((item) => { return cityIds.includes(item.id); }); }, async mapCategoryOptions(services, categories) { const categoryIds = services.map((item) => item.category); this.categoryOptions = categories.filter((item) => { return categoryIds.includes(item.id); }); }, async getCategoryList() { await this.$axios .get( `/service/category?lang_code=${this.$i18n.localeProperties["langQuery"]}` ) .then((result) => { this.categories = result.data.map((item) => { return { id: item.id, name: item.language_text[0].text, }; }); result.data.forEach((item) => { this.categoryNameList[item.id] = item.language_text[0].text; }); return result.data; }) .catch((err) => { console.log(err); }); }, mapServiceCategoryName(data, categoryList) { data = data.map((item) => { Number(item.category) > 0 ? (item.categoryName = categoryList[item.category]) : (item.categoryName = ""); return item; }); return data; }, 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; }, sortServiceList(data, sort) { switch (sort) { case 0: function NewToOld(a, b) { if ( a.launch_date.replace(/-/g, "") < b.launch_date.replace(/-/g, "") ) return 1; if ( a.launch_date.replace(/-/g, "") > b.launch_date.replace(/-/g, "") ) return -1; return 0; } return data.sort(NewToOld); case 1: function OldToNew(a, b) { if ( a.launch_date.replace(/-/g, "") > b.launch_date.replace(/-/g, "") ) return 1; if ( a.launch_date.replace(/-/g, "") < b.launch_date.replace(/-/g, "") ) return -1; return 0; } return data.sort(OldToNew); default: return data; } }, filterByCategory(data, category) { if (Number(category) < 1) { return data; } else { return data.filter( (item) => Number(item.category) === Number(category) ); } }, filterByCity(data, city) { if (Number(city) < 1) { return data; } else { return data.filter((item) => Number(item.city) === Number(city)); } }, filterByCountry(data, country) { if (Number(country) < 1) { return data; } else { return data.filter((item) => Number(item.country) === Number(country)); } }, updateCurrentPage(value) { this.currentPage = value; }, sliceRenderList(data) { return data.slice( (this.currentPage - 1) * this.perPageItems, this.currentPage * this.perPageItems ); }, getExpiredService(data) { const result = data.filter((item) => { const isItemExpired = this.calculateLaunchDays( item.launch_date, item.launch_days ); return isItemExpired; }); return result; }, calculateLaunchDays(launchDate, launchDays) { const dateObj = new Date(); const year = dateObj.getFullYear(); const month = dateObj.getMonth() + 1; const date = dateObj.getDate(); const todayStr = `${year}-${month}-${date}`;
const daySeconds = 1000 * 60 * 60 * 24; const today = new Date(todayStr); const launch = new Date(launchDate); const result = parseInt(Math.abs(today - launch) / daySeconds); if (launchDate.replace(/-/g, "") > todayStr.replace(/-/g, "")) return true; if (result > launchDays) { return true; } else { return false; } }, updateServiceList() { this.$nextTick(() => { this.fetchSavedService(); }); }, async deleteAllExpiredService() { const requests = []; this.expiredList.forEach((item) => { const axiosObj = this.$axios({ url: `${process.env.BASE_URL}member/services/${item.id}?jwt=${ this.$auth.$storage.getUniversal("jwt").token }`,
method: "delete", }); requests.push(axiosObj); }); Promise.all(requests) .then((res) => { console.log(res); this.expiredList = []; }) .catch((err) => { console.log(err); }); }, }, }; </script>
<style scoped lang="scss"> select { background-image: url("~/assets/svg/dropdownarrow.svg"); width: auto; height: auto; background-position: right 12px center; background-repeat: no-repeat; }
.orangearrow { background-image: url("~/assets/svg/orangeArrow.svg"); } </style>
|