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.
 
 

532 lines
16 KiB

<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>