Browse Source

[WHAT] 展覽卡片,展覽列表頁開發

Dev
berlin-tzen 2 years ago
parent
commit
7cead36a39
  1. 194
      FrontEnd/components/exhibition/ExhibitionListCard.vue
  2. 102
      FrontEnd/pages/exhibition/index.vue

194
FrontEnd/components/exhibition/ExhibitionListCard.vue

@ -1,143 +1,123 @@
<template>
<div
class="exhibitionListCard tw-border tw-border-solid tw-border-neutrals-200 tw-rounded-[20px] tw-p-[10px] tw-mb-[20px] md:tw-px-[20px] md:tw-py-[15px] md:tw-grid md:tw-grid-cols-[auto_28px]">
<!-- 手機版save exhibition -->
<div class="tw-absolute tw-cursor-pointer md:tw-hidden" @click="onToggleFavorite">
<div v-if="item.saved">
<nuxt-link :to="localePath('/exhibition/' + item.ExhibitionID)"><img src="~/assets/svg/bookmark.svg"
class="tw-w-[24px] md:tw-w-[28px]" alt="" /></nuxt-link>
</div>
<div v-else>
<nuxt-link :to="localePath('/exhibition/' + item.ExhibitionID)"><img src="~/assets/svg/bookmark_outline.svg"
class="tw-w-[24px] md:tw-w-[28px]" alt="" /></nuxt-link>
</div>
</div>
<div class="tw-mb-[20px]">
<div
class="tw-grid tw-grid-cols-[auto_28px] tw-bg-white tw-border-solid tw-border tw-border-neutrals-200 tw-rounded-[20px] md:tw-p-[20px]">
<div class="tw-grid tw-grid-cols-[102px_auto] tw-gap-[10px] tw-p-[10px] md:tw-grid-cols-[160px_auto]">
<div class="tw-bg-primary-brigh">
<img src="~/assets/svg/bookmark_outline.svg" class="tw-mb-[30px] md:tw-hidden" alt="" />
<!-- 電腦版exhibition status -->
<!-- <div
class="tw-hidden md:tw-block md:tw-absolute tw-border-solid tw-border tw-border-complementary-1 tw-text-complementary-1 tw-bg-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] tw-text-[12px] md:tw-text-[14px]"
>
Ongoing
</div> -->
<div class="tw-grid tw-grid-cols-[102px_auto] tw-gap-[10px] tw-items-center md:tw-grid-cols-[160px_auto]">
<div v-if="item.Logo == null">
<img src="~/assets/svg/noLogo.svg" alt="" />
</div>
<nuxt-link v-else :to="localePath('/exhibition/' + item.ExhibitionID)"><img :src= "item.Logo" class="tw-py-[35px]"
alt="" /></nuxt-link>
<div>
<div class="tw-flex tw-flex-row tw-mb-[8px]">
<div v-if="item.IsRecommend != null"
class="tw-grid tw-grid-cols-[12px_auto] tw-gap-[4px] tw-items-center tw-w-fit tw-border tw-border-solid tw-border-primary-2 tw-bg-primary-1 tw-rounded-[8px] tw-px-[10px] tw-py-[4px] tw-mr-[8px] md:tw-grid-cols-[14px_auto]">
<img src="~/assets/svg/recommend.svg" class="tw-w-[12px] md:tw-w-[14px]" alt="" />
<div class="tw-text-white tw-text-[12px] md:tw-text-[16px]">
Recommend
</div>
</div>
<!-- <div
class="md:tw-hidden tw-border-solid tw-border tw-border-complementary-1 tw-text-complementary-1 tw-bg-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] tw-text-[12px] md:tw-text-[14px]"
>
Ongoing
</div> -->
<!-- exhibition status -->
<div v-if="item.ExhibStatus != null && item.ExhibStatus != '' ">
<div v-if="item.ExhibStatus != null && item.ExhibStatus != ''">
<div v-if="item.ExhibStatus == 'Upcoming'"
class="tw-border-solid tw-border tw-border-primary-1 tw-text-primary-1 tw-bg-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] tw-text-[12px] md:tw-text-[14px]">
class="tw-hidden tw-w-fit tw-body-5 tw-bg-white tw-border tw-border-solid tw-border-primary-1 tw-text-primary-1 tw-rounded-[8px] tw-px-[10px] tw-py-[4px] md:tw-block md:tw-mb-[10px] md:tw-text-[14px]">
{{ item.ExhibStatus ? item.ExhibStatus : "" }}
</div>
<div v-else-if="item.ExhibStatus == 'Ongoing'"
class="tw-border-solid tw-border tw-border-complementary-1 tw-text-complementary-1 tw-bg-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] tw-text-[12px] md:tw-text-[14px]">
class="tw-hidden tw-w-fit tw-body-5 tw-bg-white tw-border tw-border-solid tw-border-complementary-1 tw-text-complementary-1 tw-rounded-[8px] tw-px-[10px] tw-py-[4px] md:tw-block md:tw-mb-[10px] md:tw-text-[14px]">
{{ item.ExhibStatus ? item.ExhibStatus : "" }}
</div>
<div v-else-if="item.ExhibStatus == 'Finished'"
class="tw-border-solid tw-border tw-border-neutrals-500 tw-text-neutrals-500 tw-bg-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] tw-text-[12px] md:tw-text-[14px]">
class="tw-hidden tw-w-fit tw-body-5 tw-bg-white tw-border tw-border-solid tw-border-neutrals-500 tw-text-neutrals-500 tw-rounded-[8px] tw-px-[10px] tw-py-[4px] md:tw-block md:tw-mb-[10px] md:tw-text-[14px]">
{{ item.ExhibStatus ? item.ExhibStatus : "" }}
</div>
<div v-else-if="item.ExhibStatus == 'Cancelled'"
class="tw-border-solid tw-border tw-border-error-default tw-text-error-default tw-bg-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] tw-text-[12px] md:tw-text-[14px]">
class="tw-hidden tw-w-fit tw-body-5 tw-bg-white tw-border tw-border-solid tw-border-error-default tw-text-error-default tw-rounded-[8px] tw-px-[10px] tw-py-[4px] md:tw-block md:tw-mb-[10px] md:tw-text-[14px]">
{{ item.ExhibStatus ? item.ExhibStatus : "" }}
</div>
<div v-else-if="item.ExhibStatus == 'Postponed'"
class="tw-hidden tw-w-fit tw-body-5 tw-bg-error-default tw-border tw-border-solid tw-border-error-default tw-text-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] md:tw-block md:tw-mb-[10px] md:tw-text-[14px]">
{{ item.ExhibStatus ? item.ExhibStatus : "" }}
</div>
<div v-else
class="tw-border-solid tw-border tw-bg-error-default tw-text-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] tw-text-[12px] md:tw-text-[14px]">
class="tw-hidden tw-w-fit tw-body-5 tw-bg-white tw-border tw-border-solid tw-text-white tw-rounded-[8px] tw-px-[10px] tw-py-[4px] md:tw-block md:tw-mb-[10px] md:tw-text-[14px]">
{{ item.ExhibStatus ? item.ExhibStatus : "" }}
</div>
</div>
</div>
<div class="tw-mb-[8px] xl:tw-mb-[10px]">
<nuxt-link :to="localePath('/exhibition/' + item.ExhibitionID)">
<div
class="tw-line-clamp-3 md:tw-line-clamp-2 xl:tw-line-clamp-1 tw-text-base-primary tw-text-[14px] tw-font-medium md:tw-font-bold md:tw-text-[18px]">
{{ item.ExhibitionName }}
</div>
<!-- exhibition logo -->
<div v-if="item.Logo === ''">
<img src="~/assets/svg/noLogo.svg" class="md:tw-w-[160px] md:tw-p-[10px]" alt="" />
</div>
<nuxt-link v-else :to="localePath('/exhibition/' + item.ExhibitionID)"><img :src="item.Logo"
class="tw-py-[35px]" alt="" />
</nuxt-link>
</div>
<div v-if="$i18n.locale == 'zh-tw'" v-show="item.AbbreviatedName != null" class="tw-mb-[8px] xl:tw-mb-[10px]">
<nuxt-link :to="localePath('/exhibition/' + item.ExhibitionID)">
<div
class="tw-line-clamp-3 md:tw-line-clamp-2 xl:tw-line-clamp-1 tw-text-base-primary tw-text-[14px] tw-font-medium md:tw-font-bold md:tw-text-[18px]">
{{ item.AbbreviatedName }}
<div>
<div>
<div class="tw-grid tw-grid-cols-[107px_auto] tw-gap-[10px] tw-mb-[10px] md:tw-justify-between">
<div v-if="item.IsRecommend === 'Y'"
class="tw-w-fit tw-grid tw-grid-cols-[12px_auto] tw-gap-[5px] tw-rounded-[8px] tw-items-center tw-border tw-border-solid tw-border-primary-light tw-bg-primary-1 tw-py-[4px] tw-px-[10px]">
<img src="~/assets/svg/recommend.svg" alt="" />
<div class="tw-body-5 tw-text-white md:tw-text-[14px]">Recommend</div>
</div>
<div
class="tw-w-fit tw-body-5 tw-bg-white tw-border tw-border-solid tw-border-complementary-1 tw-rounded-[8px] tw-text-complementary-1 tw-py-[4px] tw-px-[10px] md:tw-hidden">
{{ item.ExhibStatus }}
</div>
<!-- <img src="~/assets/svg/bookmark_outline.svg" class="tw-hidden md:tw-block" alt="" /> -->
</div>
</nuxt-link>
</div>
<div class="tw-text-[14px] tw-font-normal tw-mb-[8px] md:tw-text-[16px] xl:tw-mb-[4px]">
<nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?region=${item.RegionID}`)">{{
item.RegionName == null ? "" : item.RegionName + "."
}}</nuxt-link>
<nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?country=${item.CountryID}`)">{{
item.CountryName == null ? "" : item.CountryName + "."
}}</nuxt-link>
<nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?city=${item.CityID}`)">{{
item.CityName
== null ? "" : item.CityName
}}</nuxt-link>
</div>
<div class="tw-hidden md:tw-block md:tw-mb-[8px] xl:tw-mb-[10px]">
<div class="tw-flex tw-flex-row tw-items-center">
<div class="tw-text-[14px] tw-text-primary-1 tw-mr-[4px]">
<!-- {{ item.rating }} -->
</div>
<div>
<div class="tw-body-4 tw-font-bold tw-mb-[8px] md:tw-text-[18px]">
{{ item.ExhibitionName }}
</div>
<img src="~/assets/svg/start.svg" class="tw-w-[14px]" alt="" />
<div class="tw-text-[14px] tw-text-neutral-600 tw-ml-[8px]">
<!-- ({{ item.reviewCount ? item.reviewCount : "0" }} reviews) -->
<nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?region=${item.RegionID}`)">{{
item.RegionName == null ? "" : item.RegionName + "."
}}</nuxt-link>
<nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?country=${item.CountryID}`)">{{
item.CountryName == null ? "" : item.CountryName + "."
}}</nuxt-link>
<nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?city=${item.CityID}`)">{{
item.CityName
== null ? "" : item.CityName
}}</nuxt-link>
<!-- star and review-->
<!-- <div class="tw-hidden md:tw-block md:tw-mb-[8px]">
<div class="tw-flex">
<div class="tw-flex tw-items-center tw-mr-[10px]">
<div class="tw-text-primary-1 tw-text-[14px] tw-mr-[5px]">4.6</div>
<img src="~/assets/svg/star.svg" class="tw-w-[15px]" alt="">
</div>
<div class="tw-text-neutrals-600 tw-text-[14px]">
(344 reviews)
</div>
</div>
</div> -->
<div v-if="item.MainCategoryList.length > 0"
class="tw-w-fit tw-p-[5px] tw-body-5 tw-rounded-[10px] tw-bg-[#f6f6f6] tw-text-hint tw-mb-[8px] md:tw-text-[14px] md:tw-px-[10px] md:tw-py-[6px]">
<div v-for="(Category, index) in item.MainCategoryList">
{{ Category.CategoryName }}
</div>
</div>
</div>
</div>
<div>
<div v-if="item.categories != null" class="md:tw-flex md:tw-flex-row md:tw-items-center tw-mb-[8px]">
<div v-for="(item, index) in item.categories" v-show="index < 1" :key="index"
class="tw-bg-[#f6f6f6] tw-w-fit tw-rounded-[10px] tw-px-[10px] tw-py-[5px] tw-text-[14px] tw-mr-[10px]">
<nuxt-link class="tw-text-neutrals-800" :to="localePath('/exhibition?category=' + item.id)">{{
item.name
}}</nuxt-link>
<div class="tw-hidden xl:tw-block tw-h-[62px]">
{{ item.Intro }}
</div>
<div class="tw-text-[12px] tw-text-complementary-1" v-if="item.categories.length > 1">
More
<div class="tw-body-3 tw-text-black md:tw-text-[18px]">
{{ formatDate(item.StartDate) + " - " + formatDate(item.EndDate) }}
</div>
</div>
</div>
<div class="tw-hidden xl:tw-block xl:tw-line-clamp-2 tw-text-neutrals-600 tw-text-[14px] xl:tw-mb-[14px]"
v-if="!!item.Intro">
<div v-html="item.Intro"></div>
</div>
<!-- 電腦版save exhibition -->
<div class="tw-hidden md:tw-cursor-pointer md:tw-block" @click="onToggleFavorite">
<div v-if="item.saved">
<img src="~/assets/svg/bookmark.svg" class="tw-w-[24px] md:tw-w-[28px]" alt="" />
</div>
<div class="tw-text-[16px] tw-text-base-primary md:tw-text-[18px]">
{{ formatDate(item.StartDate) + " - " + formatDate(item.EndDate) }}
<div v-else>
<img src="~/assets/svg/bookmark_outline.svg" class="tw-w-[24px] md:tw-w-[28px]" alt="" />
</div>
</div>
</div>
<!-- 電腦版save exhibition -->
<div class="tw-hidden md:tw-cursor-pointer md:tw-block" @click="onToggleFavorite">
<div v-if="item.saved">
<img src="~/assets/svg/bookmark.svg" class="tw-w-[24px] md:tw-w-[28px]" alt="" />
</div>
<div v-else>
<img src="~/assets/svg/bookmark_outline.svg" class="tw-w-[24px] md:tw-w-[28px]" alt="" />
</div>
</div>
</div>
</template>

102
FrontEnd/pages/exhibition/index.vue

@ -210,6 +210,7 @@ export default {
data: () => ({
page: 1,
perPage: 10,
adList: [],
exhibitionList: [],
datesChecked: [],
statusesChecked: [],
@ -252,6 +253,7 @@ export default {
sortBy: "Show Dates",
}),
async created() {
this.getAdList();
this.getStatusList();
this.getLocationList();
this.getCategoryList();
@ -406,6 +408,17 @@ export default {
}
});
},
getAdList() {
this.ads = [{
image: require('/assets/img/thems/Frame33.png')
},{
image: require('/assets/img/thems/Frame33.png')
},{
image: require('/assets/img/thems/Frame33.png')
}]
},
getStatusList() {
this.$axios
.get(
@ -431,33 +444,6 @@ export default {
console.log(err);
});
},
async getUnsortLocationList() {
await this.$axios
.get(
`/t/exhibitions/locations?lang=${this.$i18n.localeProperties["langQuery"]}&sort=false`
)
.then((result) => {
this.unsortRegionList = result.data.region_name_list;
this.unsortCountryList = result.data.country_name_list;
this.unsortCityList = result.data.city_name_list;
})
.catch((err) => {
console.log(err);
});
},
async getUnsortCategoryList() {
await this.$axios
.get(
`/t/exhibitions/categories?lang=${this.$i18n.localeProperties["langQuery"]}&sort=false`
)
.then((result) => {
this.unsortCategoryList = result.data.category_name_list;
this.unsortSubcategoryList = result.data.subcategory_name_list;
})
.catch((err) => {
console.log(err);
});
},
getCategoryList() {
this.$axios
.get(
@ -572,37 +558,37 @@ export default {
this.exhibitionList = [];
});
},
async getQuery() {
this.locationQueryFilter = "";
this.categoryQueryFilter = "";
this.datesChecked = [];
if (this.$route.query.hasOwnProperty("country")) {
this.locationQueryFilter =
this.unsortCountryList[Number(this.$route.query.country)];
}
if (this.$route.query.hasOwnProperty("city")) {
this.locationQueryFilter =
this.unsortCityList[Number(this.$route.query.city)];
}
if (this.$route.query.hasOwnProperty("region")) {
this.locationQueryFilter =
this.unsortRegionList[Number(this.$route.query.region)];
}
if (this.$route.query.hasOwnProperty("category")) {
this.categoryQueryFilter =
this.unsortCategoryList[Number(this.$route.query.category)];
}
if (this.$route.query.hasOwnProperty("subcategory")) {
this.categoryQueryFilter =
this.unsortSubcategoryList[Number(this.$route.query.subcategory)];
}
if (this.$route.query.hasOwnProperty("startdate")) {
this.datesChecked.push(this.$route.query.startdate);
}
if (this.$route.query.hasOwnProperty("enddate")) {
this.datesChecked.push(this.$route.query.enddate);
}
},
// async getQuery() {
// this.locationQueryFilter = "";
// this.categoryQueryFilter = "";
// this.datesChecked = [];
// if (this.$route.query.hasOwnProperty("country")) {
// this.locationQueryFilter =
// this.unsortCountryList[Number(this.$route.query.country)];
// }
// if (this.$route.query.hasOwnProperty("city")) {
// this.locationQueryFilter =
// this.unsortCityList[Number(this.$route.query.city)];
// }
// if (this.$route.query.hasOwnProperty("region")) {
// this.locationQueryFilter =
// this.unsortRegionList[Number(this.$route.query.region)];
// }
// if (this.$route.query.hasOwnProperty("category")) {
// this.categoryQueryFilter =
// this.unsortCategoryList[Number(this.$route.query.category)];
// }
// if (this.$route.query.hasOwnProperty("subcategory")) {
// this.categoryQueryFilter =
// this.unsortSubcategoryList[Number(this.$route.query.subcategory)];
// }
// if (this.$route.query.hasOwnProperty("startdate")) {
// this.datesChecked.push(this.$route.query.startdate);
// }
// if (this.$route.query.hasOwnProperty("enddate")) {
// this.datesChecked.push(this.$route.query.enddate);
// }
// },
updateSortBy(data) {
this.sortBy = data;
},

Loading…
Cancel
Save