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