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.

255 lines
9.8 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div
  3. 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]">
  4. <!-- 手機版save exhibition -->
  5. <div class="tw-absolute tw-cursor-pointer md:tw-hidden" @click="onToggleFavorite">
  6. <div v-if="item.saved">
  7. <nuxt-link :to="localePath('/exhibition/' + item.ExhibitionID)"><img src="~/assets/svg/bookmark.svg"
  8. class="tw-w-[24px] md:tw-w-[28px]" alt="" /></nuxt-link>
  9. </div>
  10. <div v-else>
  11. <nuxt-link :to="localePath('/exhibition/' + item.ExhibitionID)"><img src="~/assets/svg/bookmark_outline.svg"
  12. class="tw-w-[24px] md:tw-w-[28px]" alt="" /></nuxt-link>
  13. </div>
  14. </div>
  15. <!-- 電腦版exhibition status -->
  16. <!-- <div
  17. 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]"
  18. >
  19. Ongoing
  20. </div> -->
  21. <div class="tw-grid tw-grid-cols-[102px_auto] tw-gap-[10px] tw-items-center md:tw-grid-cols-[160px_auto]">
  22. <div v-if="item.Logo == null">
  23. <img src="~/assets/svg/noLogo.svg" alt="" />
  24. </div>
  25. <nuxt-link v-else :to="localePath('/exhibition/' + item.ExhibitionID)"><img :src= "item.Logo" class="tw-py-[35px]"
  26. alt="" /></nuxt-link>
  27. <div>
  28. <div class="tw-flex tw-flex-row tw-mb-[8px]">
  29. <div v-if="item.IsRecommend != null"
  30. 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]">
  31. <img src="~/assets/svg/recommend.svg" class="tw-w-[12px] md:tw-w-[14px]" alt="" />
  32. <div class="tw-text-white tw-text-[12px] md:tw-text-[16px]">
  33. Recommend
  34. </div>
  35. </div>
  36. <!-- <div
  37. 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]"
  38. >
  39. Ongoing
  40. </div> -->
  41. <!-- exhibition status -->
  42. <div v-if="item.ExhibStatus != null && item.ExhibStatus != '' ">
  43. <div v-if="item.ExhibStatus == 'Upcoming'"
  44. 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]">
  45. {{ item.ExhibStatus ? item.ExhibStatus : "" }}
  46. </div>
  47. <div v-else-if="item.ExhibStatus == 'Ongoing'"
  48. 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]">
  49. {{ item.ExhibStatus ? item.ExhibStatus : "" }}
  50. </div>
  51. <div v-else-if="item.ExhibStatus == 'Finished'"
  52. 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]">
  53. {{ item.ExhibStatus ? item.ExhibStatus : "" }}
  54. </div>
  55. <div v-else-if="item.ExhibStatus == 'Cancelled'"
  56. 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]">
  57. {{ item.ExhibStatus ? item.ExhibStatus : "" }}
  58. </div>
  59. <div v-else
  60. 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]">
  61. {{ item.ExhibStatus ? item.ExhibStatus : "" }}
  62. </div>
  63. </div>
  64. </div>
  65. <div class="tw-mb-[8px] xl:tw-mb-[10px]">
  66. <nuxt-link :to="localePath('/exhibition/' + item.ExhibitionID)">
  67. <div
  68. 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]">
  69. {{ item.ExhibitionName }}
  70. </div>
  71. </nuxt-link>
  72. </div>
  73. <div v-if="$i18n.locale == 'zh-tw'" v-show="item.AbbreviatedName != null" class="tw-mb-[8px] xl:tw-mb-[10px]">
  74. <nuxt-link :to="localePath('/exhibition/' + item.ExhibitionID)">
  75. <div
  76. 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]">
  77. {{ item.AbbreviatedName }}
  78. </div>
  79. </nuxt-link>
  80. </div>
  81. <div class="tw-text-[14px] tw-font-normal tw-mb-[8px] md:tw-text-[16px] xl:tw-mb-[4px]">
  82. <nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?region=${item.RegionID}`)">{{
  83. item.RegionName == null ? "" : item.RegionName + "."
  84. }}</nuxt-link>
  85. <nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?country=${item.CountryID}`)">{{
  86. item.CountryName == null ? "" : item.CountryName + "."
  87. }}</nuxt-link>
  88. <nuxt-link class="tw-text-neutrals-800" :to="localePath(`/exhibition?city=${item.CityID}`)">{{
  89. item.CityName
  90. == null ? "" : item.CityName
  91. }}</nuxt-link>
  92. </div>
  93. <div class="tw-hidden md:tw-block md:tw-mb-[8px] xl:tw-mb-[10px]">
  94. <div class="tw-flex tw-flex-row tw-items-center">
  95. <div class="tw-text-[14px] tw-text-primary-1 tw-mr-[4px]">
  96. <!-- {{ item.rating }} -->
  97. </div>
  98. <img src="~/assets/svg/start.svg" class="tw-w-[14px]" alt="" />
  99. <div class="tw-text-[14px] tw-text-neutral-600 tw-ml-[8px]">
  100. <!-- ({{ item.reviewCount ? item.reviewCount : "0" }} reviews) -->
  101. </div>
  102. </div>
  103. </div>
  104. <div>
  105. <div v-if="item.categories != null" class="md:tw-flex md:tw-flex-row md:tw-items-center tw-mb-[8px]">
  106. <div v-for="(item, index) in item.categories" v-show="index < 1" :key="index"
  107. class="tw-bg-[#f6f6f6] tw-w-fit tw-rounded-[10px] tw-px-[10px] tw-py-[5px] tw-text-[14px] tw-mr-[10px]">
  108. <nuxt-link class="tw-text-neutrals-800" :to="localePath('/exhibition?category=' + item.id)">{{
  109. item.name
  110. }}</nuxt-link>
  111. </div>
  112. <div class="tw-text-[12px] tw-text-complementary-1" v-if="item.categories.length > 1">
  113. More
  114. </div>
  115. </div>
  116. </div>
  117. <div class="tw-hidden xl:tw-block xl:tw-line-clamp-2 tw-text-neutrals-600 tw-text-[14px] xl:tw-mb-[14px]"
  118. v-if="!!item.Intro">
  119. <div v-html="item.Intro"></div>
  120. </div>
  121. <div class="tw-text-[16px] tw-text-base-primary md:tw-text-[18px]">
  122. {{ formatDate(item.StartDate) + " - " + formatDate(item.EndDate) }}
  123. </div>
  124. </div>
  125. </div>
  126. <!-- 電腦版save exhibition -->
  127. <div class="tw-hidden md:tw-cursor-pointer md:tw-block" @click="onToggleFavorite">
  128. <div v-if="item.saved">
  129. <img src="~/assets/svg/bookmark.svg" class="tw-w-[24px] md:tw-w-[28px]" alt="" />
  130. </div>
  131. <div v-else>
  132. <img src="~/assets/svg/bookmark_outline.svg" class="tw-w-[24px] md:tw-w-[28px]" alt="" />
  133. </div>
  134. </div>
  135. </div>
  136. </template>
  137. <script>
  138. import CardStatus from "~/components/exhibition/CardStatus.vue";
  139. import { formatDate, dateCountDown } from "~/utils/assist";
  140. import { ExhibitCardStatus, needLeftTagStatus } from "~/utils/constant";
  141. export default {
  142. name: "ExhibitionListCard",
  143. props: {
  144. item: {
  145. type: Object,
  146. default: () => ({}),
  147. },
  148. },
  149. components: {
  150. CardStatus,
  151. },
  152. data: () => ({
  153. StatusMap: ExhibitCardStatus,
  154. }),
  155. methods: {
  156. formatDate,
  157. dateCountDown,
  158. needLeftTagStatus,
  159. onToggleFavorite(id) {
  160. if (this.$auth.loggedIn) {
  161. // this.$axios
  162. // .put(
  163. // `/member/exhibitions?jwt=${
  164. // this.$auth.$storage.getUniversal("jwt")
  165. // ? this.$auth.$storage.getUniversal("jwt").token
  166. // : ""
  167. // }&exhibition_id=${this.item.id}&delete=${
  168. // this.item.saved ? this.item.saved : false
  169. // }`
  170. // )
  171. // .then((result) => {
  172. // if (result.data.message == "successfully unsaved exhibition") {
  173. // this.item.saved = false;
  174. // } else if (result.data.message == "successfully saved exhibition") {
  175. // this.item.saved = true;
  176. // }
  177. // this.$emit("toggle-favorite", {
  178. // id: this.item.id,
  179. // saved: this.item.saved,
  180. // });
  181. // })
  182. // .catch((err) => {
  183. // console.log(err);
  184. // });
  185. // this.$nextTick(() => {
  186. // this.$forceUpdate();
  187. // });
  188. } else {
  189. this.$router.push(this.localePath("/user"));
  190. }
  191. },
  192. },
  193. };
  194. </script>
  195. <style scoped lang="scss">
  196. .exhibit-card {
  197. max-width: 836px;
  198. &.disabled .card__right {
  199. opacity: 0.5;
  200. }
  201. }
  202. .exhibit-title {
  203. position: relative;
  204. font-weight: bold;
  205. color: #232323;
  206. word-break: break-word;
  207. .bookmark-tag {
  208. position: absolute;
  209. color: $primary-light-orange;
  210. right: 0;
  211. top: 0.5em;
  212. }
  213. }
  214. .status-tag {
  215. position: absolute;
  216. top: 16px;
  217. left: 20px;
  218. }
  219. .recommend-tag {
  220. border: 1px solid $primary-light-orange;
  221. max-width: 108px !important;
  222. img {
  223. width: 11px;
  224. height: 12px;
  225. }
  226. }
  227. .category-tag {
  228. border: 1px solid #f7ede4;
  229. height: 16px;
  230. }
  231. .last-dates {
  232. color: #ef5a5a;
  233. }
  234. a {
  235. text-decoration: none;
  236. }
  237. </style>