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.

810 lines
29 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
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="service-content tw-mb-[60px] tw-grid tw-grid-cols-1 tw-gap-[30px] md:tw-mb-[100px] xl:tw-px-[60px] xl:tw-max-w-screen-xl xl:tw-mx-auto xl:tw-grid-cols-[auto_364px]">
  4. <mobileFixTopBar ref="stickySwiper" :fixBar="fixBar" :currStep="currStep" :list="fixBarList"></mobileFixTopBar>
  5. <section class="step sercion-1 tw-w-full md:tw-px-[30px] xl:tw-px-0 xl:tw-col-span-2">
  6. <div class="tw-mt-[20px] md:tw-mb-[11px] md:tw-mt-[40px]">
  7. <Breadcrumbs></Breadcrumbs>
  8. </div>
  9. <div v-if="content.banners.length" class="tw-w-full">
  10. <slideshow :banners="content.banners"></slideshow>
  11. </div>
  12. </section>
  13. <section class="sercion-2 tw-px-[30px] md:tw-px-[30px] xl:tw-px-0 xl:tw-col-start-1 xl:tw-row-start-2">
  14. <h1 class="t16 tw-mb-[18px] md:t24">{{ content.name }}</h1>
  15. <div v-if="content.supplier"
  16. class="supplier tw-flex tw-items-center tw-mb-[20px] tw-text-base-primary t14 md:tw-mb-[30px] md:t16 md:tw-font-normal">
  17. <img :src="content.supplier.logo" class="tw-max-w-[40px] md:tw-max-w-[80px]" />
  18. <div class="t14 tw-font-normal tw-ml-[10px] md:t18 md:tw-font-normal">
  19. {{ content.supplier.brand }}
  20. </div>
  21. </div>
  22. <div class="editor-styleguide tw-text-base-primary" v-html="content.highlights"></div>
  23. </section>
  24. <section
  25. class="sercion-3 tw-grid tw-grid-cols-1 tw-gap-[30px] md:tw-gap-[40px] md:tw-px-[30px] xl:tw-px-0 xl:tw-col-start-1 xl:tw-row-start-3">
  26. <div ref="packageOptions" id="packageOptions" class="step">
  27. <div class="tw-px-[30px] md:tw-px-0">
  28. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20">
  29. {{ $t("Package Options") }}
  30. </h2>
  31. <p>{{ $t("Select date and package options") }}</p>
  32. </div>
  33. <div class="tw-w-full tw-bg-neutrals-100 tw-p-[20px] md:tw-p-[30px]">
  34. <div class="">
  35. <div class="group tw-mb-[40px]" v-if="content.dateStatus == 'active'">
  36. <h3 class="t14 tw-font-bold tw-mb-[20px] md:t16">
  37. {{ $t("Select Date") }}
  38. </h3>
  39. <selectDate :start="content.start" :end="content.end" @selected="selectDates = $event"></selectDate>
  40. </div>
  41. <div class="group tw-mb-[40px]" v-if="content.timeStatus == 'active'">
  42. <h3 class="t14 tw-font-bold tw-mb-[20px] md:t16">
  43. {{ $t("Time") }}
  44. </h3>
  45. <timeButtonGroup v-if="content.times.length > 0" :list="content.times" @selected="selectTime = $event">
  46. </timeButtonGroup>
  47. </div>
  48. <div class="group tw-mb-[20px]">
  49. <h3 class="t14 tw-font-bold tw-mb-[20px] md:t16">
  50. {{ $t("Package Type") }}
  51. </h3>
  52. <typeGroup :packages="content.packages" @type="changeType($event)"></typeGroup>
  53. </div>
  54. <template v-for="(item, index) in content.packages">
  55. <div :key="index" v-if="index === activePackage" class="">
  56. <div v-if="content.packages[index].is_customize == 1">
  57. <div class="group tw-mb-[20px]">
  58. <h3 class="t14 tw-font-bold tw-mb-[20px] md:t16">
  59. {{ item.plan_title }}
  60. </h3>
  61. </div>
  62. <buttonGroup :list="item.choices" @choicesIdx="choicesIdx($event)"></buttonGroup>
  63. <customSelectGroup ref="customSelectGroup" :label="'Specification'" :packages="item.specifications"
  64. :choices="item.choices" :choicesIndex="choicesIndex" @totalPrice="customPlanPrice = $event">
  65. </customSelectGroup>
  66. </div>
  67. <div v-else>
  68. <selectGroup :label="'Specification'" :packages="item.specifications"
  69. @totalPrice="totalPrice = $event"></selectGroup>
  70. </div>
  71. </div>
  72. </template>
  73. <!-- <div v-show="content.additionalServices.length > 0" class="group tw-mb-[20px]">
  74. <additionalGroup :label="'Additional Services'" :packages="content.additionalServices"
  75. @totalPrice="additionTotalPrice = $event"></additionalGroup>
  76. </div> -->
  77. <div class="md:tw-flex md:tw-justify-between md:tw-items-center">
  78. <div class="tw-flex tw-justify-between tw-items-start md:tw-w-full md:tw-basis-10/12">
  79. <div class="tw-flex tw-flex-col tw-justify-center">
  80. <div class="tw-flex tw-items-center tw-mb-[8px] md:tw-mb-0">
  81. <div class="tw-body-4 tw-text-neutrals-900 tw-mr-[10px] md:t24">
  82. ${{ finalPrice }} {{ currency }}
  83. </div>
  84. <!-- <div
  85. class="tw-body-4 tw-text-base-hint tw-line-through md:t20 md:tw-font-medium"
  86. >
  87. ${{ totalPrice.toLocaleString() }}
  88. </div> -->
  89. </div>
  90. <div class="tw-hidden tw-body-4 tw-text-neutrals-600 md:tw-hidden">
  91. Deposit fee: $5 {{ currency }} (10%)
  92. </div>
  93. </div>
  94. <like></like>
  95. </div>
  96. <button
  97. class="tw-transition tw-btn-md tw-text-white tw-border tw-border-solid tw-border-primary-default tw-bg-primary-default tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl md:tw-mt-0 md:tw-ml-[36px] md:tw-w-auto md:tw-basis-2/12 disabled:tw-bg-neutral-100 disabled:tw-text-base-disable disabled:tw-border-neutral-200"
  98. @click="bookNow" :disabled="btnDisabled">
  99. {{ $t("Book Now") }}
  100. </button>
  101. </div>
  102. </div>
  103. </div>
  104. </div>
  105. <div id="serviceDetails" class="serviceDetails step">
  106. <div class="tw-px-[30px] md:tw-px-0">
  107. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  108. {{ $t("Service Details") }}
  109. </h2>
  110. <div v-if="content.details.length < 800">
  111. <div ref="details" class="editor-styleguide tw-text-base-primary t14 md:t16 md:tw-font-normal"
  112. v-html="content.details"></div>
  113. </div>
  114. <div v-else>
  115. <div :class="[
  116. button.details ? 'seeMore-hide' : 'seeMore-show',
  117. 'editor-styleguide tw-text-base-primary tw-transition t14 md:t16 md:tw-font-normal',
  118. ]" ref="details" v-html="content.details"></div>
  119. <button v-show="seeMore.details" :class="[
  120. 'seeMore tw-transition tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3 xl:hover:tw-bg-transparent xl:tw-border-none',
  121. button.details ? '' : 'open',
  122. ]" @click="opendetail()">
  123. {{ $t(seeMoreDetailsText) }}
  124. </button>
  125. </div>
  126. </div>
  127. </div>
  128. <div id="cancellationPolicy" class="cancellationPolicy step tw-px-[30px] md:tw-px-0">
  129. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  130. {{ $t("Cancellation Policy") }}
  131. </h2>
  132. <div v-if="content.cancellation_policy.length < 800">
  133. <div ref="cancellation_policy" class="editor-styleguide tw-text-base-primary t14 md:t16 md:tw-font-normal"
  134. v-html="content.cancellation_policy">
  135. </div>
  136. </div>
  137. <div v-else>
  138. <div :class="[
  139. button.cancellation_policy ? 'seeMore-hide' : 'seeMore-show',
  140. 'editor-styleguide tw-text-base-primary tw-transition t14 md:t16 md:tw-font-normal',
  141. ]" ref="cancellation_policy" v-html="content.cancellation_policy"></div>
  142. <button v-show="seeMore.cancellation_policy" :class="[
  143. 'seeMore tw-transition tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3 xl:hover:tw-bg-transparent xl:tw-border-none',
  144. button.cancellation_policy ? '' : 'open',
  145. ]" @click="openCancellationPolicy()">
  146. {{ $t(seeMoreCancellationPolicyText) }}
  147. </button>
  148. </div>
  149. </div>
  150. <div id="faq" ref="faq" class="step tw-px-[30px] md:tw-px-0">
  151. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  152. {{ $t("FAQ") }}
  153. </h2>
  154. <faq :faq="content.faq" class="tw-z-[8]"></faq>
  155. </div>
  156. <div id="contactUs" class="step tw-px-[30px] md:tw-px-0">
  157. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  158. {{ $t("Contact Us") }}
  159. </h2>
  160. <div class="tw-body-3 tw-text-base-primary tw-mb-[20px]">
  161. 886-2-2725-5000
  162. </div>
  163. <div class="tw-body-3 tw-text-base-primary">info@showeasy.com</div>
  164. </div>
  165. <div :class="[
  166. 'tw-bg-white tw-flex tw-flex-cols tw-justify-between tw-items-center tw-px-[30px] tw-py-[16px] tw-w-full',
  167. fixBar
  168. ? 'tw-fixed tw-left-[0px] tw-bottom-[0px] tw-z-[8] tw-shadow-[1px_0px_2px_rgba(0,0,0,0.25)]'
  169. : 'tw-hidden',
  170. ]">
  171. <div :class="[
  172. 'tw-flex tw-flex-col tw-justify-between tw-items-start tw-grow md:tw-w-full md:tw-flex-row md:tw-items-center',
  173. ]">
  174. <div class="tw-flex tw-items-center tw-mb-[12px] md:tw-mb-0">
  175. <div class="t16 tw-text-neutrals-900 tw-mr-[10px] md:t20 md:tw-mr-0">
  176. ${{ finalPrice }} {{ currency }}
  177. </div>
  178. </div>
  179. <div class="tw-flex tw-justify-center tw-items-center tw-w-full md:tw-w-fit">
  180. <like></like>
  181. <button
  182. class="tw-transition tw-whitespace-nowrap tw-body-4 tw-text-white tw-border tw-border-solid tw-border-primary-default tw-bg-primary-default tw-ml-[22px] tw-px-[24px] tw-py-[8.5px] tw-rounded-xl tw-w-full md:tw-body-2 md:tw-min-w-[130px] md:tw-max-w-[130px] md:tw-mt-0 disabled:tw-bg-neutral-100 disabled:tw-text-base-disable disabled:tw-border-neutral-200"
  183. @click="bookNow" :disabled="btnDisabled">
  184. {{ $t("Book Now") }}
  185. </button>
  186. </div>
  187. </div>
  188. </div>
  189. </section>
  190. <section
  191. class="sercion-4 tw-px-[30px] tw-grid tw-grid-cols-1 tw-gap-[40px] tw-z-[8] md:tw-px-[30px] xl:tw-px-0 xl:tw-col-start-1 xl:tw-row-start-4">
  192. <detailsModal :detail="content.details"></detailsModal>
  193. <cancellationPolicyModal :cancellationPolicy="content.cancellation_policy"></cancellationPolicyModal>
  194. </section>
  195. <section class="sercion-5 tw-hidden md:tw-px-[30px] xl:tw-px-0 xl:tw-block xl:tw-row-start-2 xl:tw-row-end-5">
  196. <div class="tw-mb-[40px]">
  197. <sidebarSelectOption :totalPrice="finalPrice" :currency="currency" :confirmationTime="content.confirmationTime">
  198. </sidebarSelectOption>
  199. </div>
  200. <sideBarMenu :fixBarList="fixBarList" :currStep="currStep"></sideBarMenu>
  201. </section>
  202. <!-- <section class="step sercion-6 tw-pl-[30px] tw-w-full xl:tw-px-0 xl:tw-col-span-2">
  203. <h2 class="title-icon-left t16 md:t20 xl:tw-font-bold">
  204. {{ $t("You might like ...") }}
  205. </h2>
  206. <youMightLikeslideshow :list="list" :countrycode="countrycode" :regionName="regionName"></youMightLikeslideshow>
  207. </section> -->
  208. </div>
  209. </template>
  210. <script>
  211. import Breadcrumbs from "@/components/Breadcrumbs";
  212. import slideshow from "@/components/swiper/serviceContent.vue";
  213. import detailsModal from "@/components/service/contentModal/DetailsModal.vue";
  214. import cancellationPolicyModal from "@/components/service/contentModal/cancellationPolicyModal.vue";
  215. import selectDate from "@/components/service/content/selectDate.vue";
  216. import typeGroup from "@/components/service/content/typeGroup.vue";
  217. import selectGroup from "@/components/service/content/selectGroup.vue";
  218. import customSelectGroup from "@/components/service/content/customSelectGroup.vue";
  219. import additionalGroup from "@/components/service/content/additionalGroup.vue";
  220. import faq from "@/components/service/content/faq.vue";
  221. import sidebarSelectOption from "@/components/service/content/sidebarSelectOption.vue";
  222. import sideBarMenu from "@/components/service/content/sideBarMenu.vue";
  223. import Swiper from "swiper/bundle";
  224. import { scrollama } from "scrollama";
  225. // import youMightLikeslideshow from "@/components/swiper/youMightLike.vue";
  226. import mobileFixTopBar from "@/components/swiper/mobileFixTopBar.vue";
  227. import timeButtonGroup from "@/components/service/content/timeButtonGroup";
  228. import buttonGroup from "@/components/service/content/buttonGroup.vue";
  229. import like from "@/components/newComponent/like/like.vue";
  230. export default {
  231. auth: false,
  232. components: {
  233. Swiper,
  234. scrollama,
  235. Breadcrumbs,
  236. slideshow,
  237. detailsModal,
  238. cancellationPolicyModal,
  239. selectDate,
  240. typeGroup,
  241. timeButtonGroup,
  242. buttonGroup,
  243. selectGroup,
  244. customSelectGroup,
  245. additionalGroup,
  246. faq,
  247. sidebarSelectOption,
  248. sideBarMenu,
  249. // youMightLikeslideshow,
  250. mobileFixTopBar,
  251. like,
  252. },
  253. data() {
  254. return {
  255. apiUrl: process.env.SERVICE_CONSOLE,
  256. btnDisabled: process.env.ENV == 'production',
  257. currStep: null,
  258. stickySwiper: null,
  259. content: {
  260. banners: [],
  261. country: null,
  262. city: null,
  263. name: "",
  264. highlights: '',
  265. details: '',
  266. cancellation_policy: "",
  267. saved: false,
  268. confirmation_time: 24,
  269. supplier: {
  270. logo: require('/assets/img/Footer.png'),
  271. brand: 'ShowEasy'
  272. },
  273. available_sections: null,
  274. timeStatus: 'active',
  275. dateStatus: 'active',
  276. times: [{
  277. start_time: '2023-02-06',
  278. end_time: '2023-03-06',
  279. },{
  280. start_time: '2023-02-06',
  281. end_time: '2023-03-06',
  282. },{
  283. start_time: '2023-02-06',
  284. end_time: '2023-03-06',
  285. }],
  286. start: '2023-02-06',
  287. end: '2023-06-06',
  288. faq: [],
  289. confirmationTime: '',
  290. packages: [{
  291. package_id: '1',
  292. name: '嘉義',
  293. is_customize: 1,
  294. choices:[{title: '接機服務',text: 'qweqweq'},{title: '送機服務',text: '13123'}],
  295. plan_title: '接送機服務',
  296. specifications: [{
  297. title: '賓士7人座車',
  298. }]
  299. },{
  300. package_id: '1',
  301. name: '臺南',
  302. is_customize: 1,
  303. choices:[{title: '接機服務',text: 'qweqweq'},{title: '送機服務',text: '13123'}],
  304. plan_title: '接送機服務',
  305. specifications: [{
  306. title: '賓士7人座車',
  307. }]
  308. }],
  309. additionalServices: [
  310. {
  311. name: '司機英文服務'
  312. },{
  313. name: '兒童安全座椅'
  314. },{
  315. name: '增加一個停靠點'
  316. },{
  317. name: '協助飯店入住(每個人,限接機)'
  318. }
  319. ],
  320. },
  321. list: [],
  322. choicesIndex: 0,
  323. countrycode: [],
  324. regionName: [],
  325. elementHeight: {
  326. details: null,
  327. cancellation_policy: null,
  328. faq: null,
  329. },
  330. seeMore: {
  331. details: true,
  332. cancellation_policy: true,
  333. },
  334. button: {
  335. details: true,
  336. cancellation_policy: true,
  337. },
  338. offset: {
  339. packageOptions: 0,
  340. faq: 0,
  341. },
  342. contentId: "",
  343. packageId: "",
  344. packageName: "",
  345. window: {
  346. width: 0,
  347. },
  348. fixBar: false,
  349. fixBarList: [
  350. { id: "packageOptions", title: "Package Options", show: true },
  351. { id: "serviceDetails", title: "Service Details", show: true },
  352. { id: "cancellationPolicy", title: "Cancellation Policy", show: true },
  353. { id: "faq", title: "FAQ", show: true },
  354. { id: "contactUs", title: "Contact Us", show: true },
  355. ],
  356. activePackage: 0,
  357. totalPrice: [],
  358. additionTotalPrice: [],
  359. customPlanPrice: [],
  360. selectDates: '',
  361. selectTime: {
  362. start_time: '2023-02-06',
  363. end_time: '2023-03-06',
  364. },
  365. };
  366. },
  367. async created() {
  368. await this.getBanners();
  369. await this.getServiceData();
  370. // await this.getFaq();
  371. await this.getPackages();
  372. // await this.getAdditionalServices();
  373. // await this.addViewCount();
  374. // await this.getYouMightLikeData();
  375. // await this.getRegionName();
  376. // await this.getCountryCode();
  377. if (process.browser) {
  378. window.addEventListener("resize", this.handleResize);
  379. }
  380. this.handleResize();
  381. },
  382. mounted() {
  383. let vm = this;
  384. vm.contentId = vm.$route.params.id;
  385. vm.offset.packageOptions = vm.$refs.packageOptions.offsetTop;
  386. vm.offset.faq = vm.$refs.faq.offsetTop;
  387. vm.$nextTick(function () {
  388. // instantiate the scrollama
  389. const scrollama = require("scrollama");
  390. const scroller = scrollama();
  391. // setup the instance, pass callback functions
  392. scroller
  393. .setup({
  394. step: ".service-content .step",
  395. offset: 0.6,
  396. })
  397. .onStepEnter((response) => {
  398. // { element, index, direction }
  399. vm.currStep = response.element.id;
  400. let fb_messenger = document.querySelector(".fb_dialog_content");
  401. if (response.index > 3) {
  402. vm.$refs.stickySwiper.slideTo(4);
  403. } else {
  404. vm.$refs.stickySwiper.slideTo(0);
  405. }
  406. if (response.index >= 1 && response.index < 6) {
  407. vm.fixBar = true;
  408. if (fb_messenger) {
  409. fb_messenger.classList.add("hasBar");
  410. }
  411. } else {
  412. vm.fixBar = false;
  413. if (fb_messenger) {
  414. fb_messenger.classList.remove("hasBar");
  415. }
  416. }
  417. })
  418. .onStepExit((response) => {
  419. // { element, index, direction }
  420. vm.currStep = response.element.id;
  421. let fb_messenger = document.querySelector(".fb_dialog_content");
  422. if (response.index >= 1 && response.index < 6) {
  423. vm.fixBar = true;
  424. if (fb_messenger) {
  425. fb_messenger.classList.add("hasBar");
  426. }
  427. } else {
  428. vm.fixBar = false;
  429. if (fb_messenger) {
  430. fb_messenger.classList.remove("hasBar");
  431. }
  432. }
  433. });
  434. })
  435. },
  436. computed: {
  437. currency() {
  438. return this.$store.getters.getCurrency;
  439. },
  440. seeMoreDetailsText() {
  441. if (this.button.details == false) {
  442. return "See less";
  443. } else {
  444. return "See more";
  445. }
  446. },
  447. seeMoreCancellationPolicyText() {
  448. if (this.button.cancellation_policy == false) {
  449. return "See less";
  450. } else {
  451. return "See more";
  452. }
  453. },
  454. finalPrice() {
  455. let option = 0;
  456. let custom = 0;
  457. let addition = 0;
  458. if (this.additionTotalPrice) {
  459. this.additionTotalPrice.forEach((item) => {
  460. addition += Number(item.total);
  461. });
  462. }
  463. if (this.customPlanPrice) {
  464. this.customPlanPrice.forEach((item) => {
  465. custom += Number(item.total);
  466. });
  467. }
  468. if (this.totalPrice) {
  469. this.totalPrice.forEach((item) => {
  470. option += Number(item.total);
  471. });
  472. }
  473. if (this.currency == 'USD') {
  474. return Number(addition + custom + option).toFixed(2).toLocaleString();
  475. } else {
  476. return Number(addition + custom + option).toLocaleString();
  477. }
  478. },
  479. },
  480. watch: {
  481. currency: {
  482. handler: function () {
  483. this.getServiceData();
  484. this.getPackages();
  485. // this.getAdditionalServices();
  486. },
  487. },
  488. activePackage: {
  489. handler: function (newVal, oldVal) {
  490. if (newVal !== oldVal) {
  491. this.customPlanPrice = [];
  492. this.totalPrice = [];
  493. }
  494. },
  495. },
  496. choicesIndex: {
  497. handler: function (newVal, oldVal) {
  498. if (newVal !== oldVal) {
  499. this.customPlanPrice = [];
  500. this.totalPrice = [];
  501. }
  502. },
  503. }
  504. },
  505. destroyed() {
  506. if (process.browser) {
  507. window.removeEventListener("resize", this.handleResize);
  508. }
  509. },
  510. methods: {
  511. async getBanners() {
  512. console.log("id" + this.$route.params.id);
  513. await this.$axios.get(`/trending/api/Onsite/BannerFiles?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}`)
  514. .then((response) => {
  515. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  516. let data = response.data.DATA.rel
  517. if(data.length>0){
  518. this.content.banners = data.map((item) => {
  519. return {
  520. banner_id: item.FileID,
  521. image: item.FilePath,
  522. };
  523. });
  524. }
  525. }
  526. })
  527. .catch((error) => console.log(error));
  528. },
  529. async getServiceData() {
  530. await this.$axios
  531. .get(`/trending/api/Onsite/Info?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}`)
  532. .then((response) => {
  533. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  534. let data = response.data.DATA.rel
  535. if(data){
  536. this.content.name = data.ServiceName;
  537. this.content.highlights = data.Features;
  538. this.content.details = data.Details;
  539. this.content.cancellation_policy = data.CancelPolicy;
  540. this.content.faq = data.FQAs;
  541. this.content.confirmationTime = data.ConfirmDays;
  542. }
  543. }
  544. // this.content.country = res.data.country;
  545. // this.content.city = res.data.city;
  546. // this.content.highlights = res.data.highlights;
  547. // this.content.details = res.data.details;
  548. // this.content.cancellation_policy = res.data.cancellation_policy;
  549. // this.content.supplier = res.data.supplier;
  550. // this.content.available_sections = res.data.available_sections;
  551. // this.content.times = res.data.available_sections.times;
  552. // this.content.timeStatus = res.data.available_sections.time_status;
  553. // this.content.dateStatus = res.data.available_sections.date_status;
  554. // this.content.start = res.data.available_sections.start;
  555. // this.content.end = res.data.available_sections.end;
  556. // this.content.payment_currency = res.data.payment_currency;
  557. // this.content.confirmationTime = res.data.confirmation_time.toString();
  558. })
  559. .catch((error) => console.log(error));
  560. },
  561. // async getFaq() {
  562. // await this.$axios
  563. // .get(
  564. // `${this.apiUrl}/user-services/faqs?service_id=${this.$route.params.id}&lang_code=${this.$i18n.localeProperties["langQuery"]}`
  565. // )
  566. // .then((res) => {
  567. // this.content.faq = res.data;
  568. // })
  569. // .catch((error) => console.log(error));
  570. // },
  571. async getPackages() {
  572. await this.$axios
  573. .get(`trending/api/Onsite/PackingTypes?Lang=${this.$i18n.localeProperties["langQuery"]}`)
  574. .then((response) => {
  575. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  576. let data = response.data.DATA.rel
  577. if(data.length>0){
  578. this.content.packages = data.map((item) => {
  579. return {
  580. package_id: item.ArgumentID,
  581. name: item.ArgumentValue,
  582. };
  583. });
  584. this.packageId = data[0].ArgumentID ? data[0].ArgumentID : "";
  585. }
  586. }
  587. })
  588. .catch((error) => console.log(error));
  589. },
  590. async getAdditionalServices() {
  591. await this.$axios
  592. .get(
  593. `${this.apiUrl}/user-services/additional?service_id=${this.$route.params.id}&lang_code=${this.$i18n.localeProperties["langQuery"]}&currency=${this.currency}`
  594. )
  595. .then((res) => {
  596. this.content.additionalServices =
  597. res.data.services == [] ? null : res.data;
  598. })
  599. .catch((error) => console.log(error));
  600. },
  601. async addViewCount() {
  602. let Obj = {
  603. service_id: `${this.$route.params.id}`,
  604. lang_code: `${this.$i18n.localeProperties["langQuery"]}`,
  605. add_number: 1,
  606. };
  607. await this.$axios
  608. .put(`${this.apiUrl}/user-services/view-counts`, Obj)
  609. .then((res) => { })
  610. .catch((error) => console.log(error));
  611. },
  612. opendetail() {
  613. if (this.window.width >= 1366) {
  614. this.button.details = !this.button.details;
  615. } else {
  616. this.$modal.show("Details");
  617. }
  618. },
  619. openCancellationPolicy() {
  620. if (this.window.width >= 1366) {
  621. this.button.cancellation_policy = !this.button.cancellation_policy;
  622. } else {
  623. this.$modal.show("cancellationPolicy");
  624. }
  625. },
  626. handleResize() {
  627. if (process.browser) {
  628. this.window.width = window.innerWidth;
  629. }
  630. },
  631. changeType(index) {
  632. let vm = this;
  633. vm.activePackage = index;
  634. vm.packageId = vm.content.packages[index].package_id
  635. ? vm.content.packages[index].package_id
  636. : "";
  637. vm.packageName = vm.content.packages[index].name
  638. ? vm.content.packages[index].name
  639. : "";
  640. },
  641. async getYouMightLikeData() {
  642. this.$axios
  643. .get(
  644. `${this.apiUrl}/user-services/advertisements?region=0&country=0&city=0&expo=0&counts=3&lang_code=${this.$i18n.localeProperties["langQuery"]}`
  645. )
  646. .then((res) => {
  647. this.list = res.data;
  648. })
  649. .catch((error) => console.log(error));
  650. },
  651. async getCountryCode() {
  652. this.$axios
  653. .get(
  654. `${this.apiUrl}/countries?lang_code=${this.$i18n.localeProperties["langQuery"]}`
  655. )
  656. .then((respone) => {
  657. this.countrycode = respone.data;
  658. })
  659. .catch((error) => console.log(error));
  660. },
  661. async getRegionName() {
  662. this.$axios
  663. .get(
  664. `/t/exhibitions/locations?lang=${this.$i18n.localeProperties["langQuery"]}&sort=False`
  665. )
  666. .then((respone) => {
  667. this.regionName = respone.data.region_ori;
  668. })
  669. .catch((error) => console.log(error));
  670. },
  671. bookNow() {
  672. let Obj = {
  673. service_id: this.$route.params.id,
  674. service_name: this.content.name,
  675. select_dates: this.selectDates,
  676. currency: this.currency,
  677. lang_code: this.$i18n.localeProperties["langQuery"],
  678. time: this.selectTime,
  679. package_id: this.packageId,
  680. package_name: this.packageName,
  681. specification: this.totalPrice ? this.totalPrice : {},
  682. additional_services: this.additionTotalPrice ? this.additionTotalPrice : {},
  683. custom_plan: this.customPlanPrice ? this.customPlanPrice : {},
  684. supplier_id: this.content.supplier.id ? this.content.supplier.id : '',
  685. };
  686. // this.$router.push(this.localePath("/service/checkout/1"));
  687. // this.$axios
  688. // .post(`/order?jwt=${this.$auth.$storage.getUniversal("jwt").token || ""
  689. // }`, Obj)
  690. // .then((res) => {
  691. // if (res.status == "200") {
  692. // this.$router.push(this.localePath("/service/checkout/" + res.data.order_display_id))
  693. // }
  694. // })
  695. // .catch((error) => console.log(error));
  696. },
  697. choicesIdx(data) {
  698. let vm = this;
  699. vm.choicesIndex = data;
  700. }
  701. },
  702. };
  703. </script>
  704. <style lang="scss" scoped>
  705. :deep() {
  706. // .serviceDetails,
  707. // .cancellationPolicy {
  708. // p {
  709. // margin-bottom: 6px;
  710. // }
  711. // }
  712. }
  713. .service-content {
  714. .serviceDetails img {
  715. width: 100%;
  716. height: auto;
  717. }
  718. .fix-right {
  719. position: fixed;
  720. top: 120px;
  721. right: 0 px;
  722. max-width: 400px;
  723. height: auto;
  724. z-index: 100;
  725. }
  726. .title-icon-left {
  727. background-position: left 0px center;
  728. }
  729. ul {
  730. padding-left: 24px;
  731. }
  732. img {
  733. // image-rendering: pixelated;
  734. }
  735. }
  736. .seeMore {
  737. &-hide {
  738. position: relative;
  739. max-height: 295px;
  740. overflow: hidden;
  741. &::after {
  742. content: "";
  743. display: block;
  744. position: absolute;
  745. background: url("~/assets/img/gradient_white.png") repeat-x left bottom;
  746. width: 100%;
  747. height: 130px;
  748. left: 0;
  749. bottom: 0;
  750. z-index: 1;
  751. transition: bottom 0.5s;
  752. }
  753. }
  754. &-show {
  755. position: relative;
  756. max-height: 100%;
  757. overflow: initial;
  758. &::after {
  759. display: none;
  760. }
  761. }
  762. @media screen and (min-width: 1366px) {
  763. position: relative;
  764. display: flex;
  765. align-items: center;
  766. justify-content: center;
  767. &::after {
  768. content: "";
  769. display: inline-block;
  770. position: relative;
  771. background-image: url("~/assets/svg/arrow-down-primary.svg");
  772. background-position: center center;
  773. background-repeat: no-repeat;
  774. background-size: 100%;
  775. width: 9px;
  776. height: 6px;
  777. margin-left: 16px;
  778. }
  779. &.open {
  780. &::after {
  781. transform: rotate(180deg);
  782. }
  783. }
  784. }
  785. }
  786. .section-7 {
  787. >div {
  788. box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.25), 0px 1px 2px rgba(0, 0, 0, 0.1);
  789. }
  790. }
  791. </style>