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.

599 lines
19 KiB

2 years ago
  1. <template>
  2. <div
  3. class="booking-info-item tw-p-[15px] lg:tw-p-[20px] tw-mb-[30px] tw-bg-neutrals-0 tw-rounded-xl md:tw-mb-[40px]"
  4. >
  5. <div
  6. :class="[
  7. 'info-content',
  8. 'collapse',
  9. 'tw-cursor-pointer',
  10. 'tw-grid tw-items-start tw-grid-cols-[52px_auto] tw-gap-[15px] md:tw-grid-cols-[160px_auto] md:tw-gap-[20px] xl:tw-grid-cols-[56px_105px_520px_30px] xl:tw-gap-[16px] xl:tw-items-center',
  11. show ? 'show' : 'hide',
  12. ]"
  13. @click="show = !show"
  14. >
  15. <img
  16. class="element content-img tw-rounded-[4px] tw-h-1/5 md:tw-rounded-[12px] md:tw-h-3/5 xl:tw-h-3/5"
  17. :src="content.preview_image"
  18. />
  19. <div class="element content-text">
  20. <h3
  21. class="t12 tw-font-bold tw-mb-[10px] tw-text-base-primary md:tw-text-[16px] md:tw-leading-[21px] xl:tw-mb-[12px]"
  22. >
  23. {{ info.service_name }}
  24. </h3>
  25. <div v-for="(item, key) in info.order_item" :key="key"
  26. class="detail tw-body-5 tw-mb-[10px] xl:tw-text-neutrals-600 xl:tw-mb-[4px]"
  27. >
  28. {{
  29. (item.package_name && item.package_name != ""
  30. ? item.package_name + ",&nbsp;"
  31. : "") +
  32. (item.customer_plan_name
  33. ? item.customer_plan_name + ",&nbsp;"
  34. : "") +
  35. item.specification_name +
  36. "&nbsp;x&nbsp;" +
  37. item.quantity
  38. }}
  39. </div>
  40. <div
  41. v-for="(item, key) in info.order_as" :key="key"
  42. class="detail tw-body-5 tw-mb-[10px] xl:tw-mb-0 xl:tw-text-neutrals-600"
  43. >
  44. {{ item.as_name + "&nbsp;x&nbsp;" + item.quantity }}
  45. </div>
  46. <div
  47. class="date tw-body-5 tw-mb-[10px] xl:tw-mt-[12px]"
  48. v-if="info.service_date != null || info.service_time != null"
  49. >
  50. Service Date: {{ info.service_date + info.service_time }}
  51. </div>
  52. <div
  53. class="total t14 tw-font-bold tw-text-primary-1 tw-mb-[10px] xl:tw-hidden"
  54. >
  55. $3,500 {{ info.currency
  56. }}<span class="tw-font-normal tw-text-neutrals-400 tw-ml-[10px]"
  57. >(Tax included)</span
  58. >
  59. </div>
  60. <div class="element xl:tw-hidden">
  61. <button
  62. class="tw-transition tw-flex tw-justify-center tw-items-center tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3"
  63. >
  64. {{ $t("Enter Required info") }}
  65. <span
  66. v-if="questionValidation == true"
  67. class="status-check-icon tw-inline-block tw-items-center tw-w-[16px] tw-h-[16px] tw-ml-[10px]"
  68. ></span>
  69. </button>
  70. </div>
  71. </div>
  72. <div class="element content-status tw-hidden xl:tw-block xl:tw-ml-[20px]">
  73. <span
  74. v-if="questionValidation == true"
  75. class="status-check-icon tw-inline-block tw-w-[30px] tw-h-[30px]"
  76. ></span>
  77. </div>
  78. </div>
  79. <Transition name="bounce">
  80. <div v-show="show" :class="['info-form']">
  81. <div
  82. :class="[
  83. 'bookingdetails',
  84. 'tw-border-0 tw-border-t tw-border-solid tw-border-neutrals-200',
  85. 'tw-pt-[20px] tw-mt-[20px]',
  86. ]"
  87. >
  88. <h3 class="tw-mb-[40px]">{{ $t("Booking Details") }}</h3>
  89. <div
  90. v-for="(item, key) in content.booking_questions" :key="key"
  91. class="element tw-mb-[20px]"
  92. >
  93. <elementTextarea
  94. :input="{
  95. id: item.question_id,
  96. label: item.question,
  97. required:
  98. item.required === 1 || item.required === 'required'
  99. ? true
  100. : false,
  101. placeholder: '',
  102. }"
  103. :default="''"
  104. :validation="question[key].validation"
  105. @change="setQuestion($event, key, item)"
  106. ></elementTextarea>
  107. </div>
  108. </div>
  109. <div
  110. :class="[
  111. 'contact-info',
  112. 'tw-border-0 tw-border-t tw-border-solid tw-border-neutrals-200',
  113. 'tw-pt-[20px] tw-mt-[20px]',
  114. ]"
  115. >
  116. <h3 class="tw-mb-[20px]">{{ $t("Contact Info") }}</h3>
  117. <div
  118. class="element element-button-group tw-flex tw-justify-start tw-flex-wrap -tw-mx-[8px]"
  119. >
  120. <button
  121. v-for="(item, index) in contact"
  122. :key="index"
  123. :class="[
  124. 'tw-transition',
  125. 'tw-btn-md',
  126. 'tw-text-[14px]',
  127. 'tw-leading-[18px]',
  128. 'tw-text-complementary-1',
  129. 'tw-bg-neutrals-0',
  130. 'tw-px-[12px]',
  131. 'tw-py-[11px]',
  132. 'tw-mx-[8px]',
  133. 'tw-mb-[16px]',
  134. 'tw-rounded-2xl',
  135. 'tw-border tw-border-solid',
  136. 'tw-bg-complementary-3',
  137. activeLabel == index + 1
  138. ? 'tw-border-complementary-1 tw-bg-complementary-1/20'
  139. : 'tw-border-transparent',
  140. ]"
  141. @click="onLabelClick(index + 1, item)"
  142. >
  143. {{ item.first_name }} {{ item.last_name }}
  144. </button>
  145. <button
  146. class="btn-add-icon tw-transition tw-btn-md tw-text-[14px] tw-leading-[18px] tw-text-complementary-1 tw-bg-complementary-3 tw-pr-[12px] tw-pl-[36px] tw-py-[11px] tw-mx-[8px] tw-mb-[16px] tw-rounded-[10px]"
  147. @click="$modal.show('add-contact-modal')"
  148. >
  149. {{ $t("Add") }}
  150. </button>
  151. </div>
  152. <div class="company-info-list">
  153. <template v-for="(item, index) in contact">
  154. <div
  155. :key="index"
  156. v-if="index + 1 === activeLabel"
  157. class="tw-grid tw-grid-cols-1 tw-gap-y-[16px]"
  158. >
  159. <div
  160. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  161. >
  162. <div class="label t14 tw-font-bold">
  163. {{ $t("First Name") }}
  164. </div>
  165. <div class="content tw-body-4">
  166. {{ item.first_name }}
  167. </div>
  168. </div>
  169. <div
  170. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  171. >
  172. <div class="label t14 tw-font-bold">
  173. {{ $t("Last Name") }}
  174. </div>
  175. <div class="content tw-body-4">
  176. {{ item.last_name }}
  177. </div>
  178. </div>
  179. <div
  180. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  181. >
  182. <div class="label t14 tw-font-bold">{{ $t("Email") }}</div>
  183. <div class="content tw-body-4">
  184. {{ item.email }}
  185. </div>
  186. </div>
  187. <div
  188. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  189. >
  190. <div class="label t14 tw-font-bold">{{ $t("Phone") }}</div>
  191. <div class="content tw-body-4">
  192. {{ item.phone_number }}
  193. </div>
  194. </div>
  195. <button
  196. class="btn-edit-icon tw-w-[28px] tw-h-[28px]"
  197. @click="$modal.show('edit-contact-modal')"
  198. ></button>
  199. </div>
  200. </template>
  201. </div>
  202. </div>
  203. <div
  204. :class="[
  205. 'promo-code',
  206. 'tw-border-0 tw-border-t tw-border-solid tw-border-neutrals-200',
  207. 'tw-pt-[20px] tw-mt-[20px]',
  208. ]"
  209. >
  210. <h3 class="tw-mb-[10px]">{{ $t("Promo code") }}</h3>
  211. <elementPromoCode></elementPromoCode>
  212. </div>
  213. <div class="element tw-text-right tw-mt-[40px]">
  214. <button
  215. class="tw-transition tw-btn-md tw-bg-primary-1 tw-px-[30px] tw-py-[8.5px] tw-rounded-2xl hover:tw-bg-primary-2"
  216. @click="updateInfo()"
  217. >
  218. {{ $t("Next") }}
  219. </button>
  220. </div>
  221. </div>
  222. </Transition>
  223. <!-- <Transition name="bounce">
  224. <div v-show="show" :class="['info-form']">
  225. <div
  226. :class="[
  227. 'bookingdetails',
  228. 'tw-border-0 tw-border-t tw-border-solid tw-border-neutrals-200',
  229. 'tw-pt-[20px] tw-mt-[20px]',
  230. ]"
  231. >
  232. {{ content.booking_questions }}
  233. <h3 class="tw-mb-[40px]">{{ $t("Booking Details") }}</h3>
  234. <div
  235. v-for="(item, key) in content.booking_questions"
  236. class="element tw-mb-[20px]"
  237. >
  238. <elementTextarea
  239. :input="{
  240. id: item.question_id,
  241. label: item.question,
  242. required:
  243. item.required === 1 || item.required === 'required'
  244. ? true
  245. : false,
  246. placeholder: '',
  247. }"
  248. :default="''"
  249. :validation="true"
  250. @change="
  251. setQuestion($event, key, item.question_id, item.question)
  252. "
  253. ></elementTextarea>
  254. </div>
  255. </div>
  256. <div
  257. :class="[
  258. 'contact-info',
  259. 'tw-border-0 tw-border-t tw-border-solid tw-border-neutrals-200',
  260. 'tw-pt-[20px] tw-mt-[20px]',
  261. ]"
  262. >
  263. <h3 class="tw-mb-[20px]">{{ $t("Contact Info") }}</h3>
  264. <div
  265. class="element element-button-group tw-flex tw-justify-start tw-flex-wrap -tw-mx-[8px]"
  266. >
  267. <button
  268. v-for="(item, index) in contact"
  269. :key="index"
  270. :class="[
  271. 'tw-transition',
  272. 'tw-btn-md',
  273. 'tw-text-[14px]',
  274. 'tw-leading-[18px]',
  275. 'tw-text-complementary-1',
  276. 'tw-bg-neutrals-0',
  277. 'tw-px-[12px]',
  278. 'tw-py-[11px]',
  279. 'tw-mx-[8px]',
  280. 'tw-mb-[16px]',
  281. 'tw-rounded-2xl',
  282. 'tw-border tw-border-solid',
  283. 'tw-bg-complementary-3',
  284. activeLabel == index + 1
  285. ? 'tw-border-complementary-1 tw-bg-complementary-1/20'
  286. : 'tw-border-transparent',
  287. ]"
  288. @click="onLabelClick(index + 1, item)"
  289. >
  290. {{ item.first_name }} {{ item.last_name }}
  291. </button>
  292. <button
  293. class="btn-add-icon tw-transition tw-btn-md tw-text-[14px] tw-leading-[18px] tw-text-complementary-1 tw-bg-complementary-3 tw-pr-[12px] tw-pl-[36px] tw-py-[11px] tw-mx-[8px] tw-mb-[16px] tw-rounded-[10px]"
  294. @click="$modal.show('add-contact-modal')"
  295. >
  296. {{ $t("Add") }}
  297. </button>
  298. </div>
  299. <div class="company-info-list">
  300. <template v-for="(item, index) in contact">
  301. <div
  302. :key="index"
  303. v-if="index + 1 === activeLabel"
  304. class="tw-grid tw-grid-cols-1 tw-gap-y-[16px]"
  305. >
  306. <div
  307. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  308. >
  309. <div class="label t14 tw-font-bold">
  310. {{ $t("First Name") }}
  311. </div>
  312. <div class="content tw-body-4">
  313. {{ item.first_name }}
  314. </div>
  315. </div>
  316. <div
  317. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  318. >
  319. <div class="label t14 tw-font-bold">
  320. {{ $t("Last Name") }}
  321. </div>
  322. <div class="content tw-body-4">
  323. {{ item.last_name }}
  324. </div>
  325. </div>
  326. <div
  327. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  328. >
  329. <div class="label t14 tw-font-bold">{{ $t("Email") }}</div>
  330. <div class="content tw-body-4">
  331. {{ item.email }}
  332. </div>
  333. </div>
  334. <div
  335. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  336. >
  337. <div class="label t14 tw-font-bold">{{ $t("Phone") }}</div>
  338. <div class="content tw-body-4">
  339. {{ item.phone_number }}
  340. </div>
  341. </div>
  342. <button
  343. class="btn-edit-icon tw-w-[28px] tw-h-[28px]"
  344. @click="$modal.show('edit-contact-modal')"
  345. ></button>
  346. </div>
  347. </template>
  348. </div>
  349. </div>
  350. <div
  351. :class="[
  352. 'promo-code',
  353. 'tw-border-0 tw-border-t tw-border-solid tw-border-neutrals-200',
  354. 'tw-pt-[20px] tw-mt-[20px]',
  355. ]"
  356. >
  357. <h3 class="tw-mb-[10px]">{{ $t("Promo code") }}</h3>
  358. <elementPromoCode></elementPromoCode>
  359. </div>
  360. <div class="element tw-text-right tw-mt-[40px]">
  361. <button
  362. class="tw-transition tw-btn-md tw-bg-primary-1 tw-px-[30px] tw-py-[8.5px] tw-rounded-2xl hover:tw-bg-primary-2"
  363. @click="updateInfo()"
  364. >
  365. {{ $t("Next") }}
  366. </button>
  367. </div>
  368. </div>
  369. </Transition> -->
  370. </div>
  371. </template>
  372. <script>
  373. import elementTextarea from "@/components/newComponent/form/ElementTextarea";
  374. import elementPromoCode from "@/components/newComponent/form/ElementPromoCode";
  375. import elementTimePicker from "@/components/newComponent/form/ElementTimePicker";
  376. import is from "is_js";
  377. export default {
  378. components: {
  379. elementTextarea,
  380. elementPromoCode,
  381. elementTimePicker,
  382. is,
  383. },
  384. props: {
  385. info: {
  386. type: Object,
  387. },
  388. content: {
  389. type: Object,
  390. },
  391. questions: {
  392. type: Array,
  393. default: [],
  394. },
  395. contact: {
  396. type: Array,
  397. },
  398. active: {
  399. type: Number,
  400. },
  401. },
  402. data() {
  403. return {
  404. show: false,
  405. question: [],
  406. contactData: {
  407. first_name: "",
  408. last_name: "",
  409. email: "",
  410. phone_number: "",
  411. },
  412. questionValidation: false,
  413. errors: null,
  414. };
  415. },
  416. computed: {
  417. activeLabel() {
  418. return this.active;
  419. },
  420. },
  421. mounted() {
  422. let vm = this;
  423. vm.$nextTick(function () {
  424. if (vm.contact.length > 0) {
  425. vm.contactData.first_name = vm.contact[0].first_name;
  426. vm.contactData.last_name = vm.contact[0].last_name;
  427. vm.contactData.email = vm.contact[0].email;
  428. vm.contactData.phone_number = vm.contact[0].phone_number;
  429. }
  430. });
  431. },
  432. watch: {
  433. contact: {
  434. handler: function () {
  435. let vm = this;
  436. if (vm.contact.length > 0) {
  437. vm.contactData.first_name = vm.contact[0].first_name;
  438. vm.contactData.last_name = vm.contact[0].last_name;
  439. vm.contactData.email = vm.contact[0].email;
  440. vm.contactData.phone_number = vm.contact[0].phone_number;
  441. }
  442. },
  443. },
  444. questions: {
  445. handler: function () {
  446. this.getContent();
  447. },
  448. },
  449. questionValidation: {
  450. handler: function () {
  451. if (this.questionValidation == true) {
  452. this.show = false;
  453. }
  454. },
  455. },
  456. },
  457. methods: {
  458. onLabelClick(label) {
  459. let index = label - 1;
  460. if (index <= 0) {
  461. index = 0;
  462. }
  463. this.contactData.first_name = this.contact[index].first_name;
  464. this.contactData.last_name = this.contact[index].last_name;
  465. this.contactData.email = this.contact[index].email;
  466. this.contactData.phone_number = this.contact[index].phone_number;
  467. this.$emit("changeActiveLabel", label);
  468. },
  469. updateInfo() {
  470. this.question.forEach((item) => {
  471. if (item.required !== "") {
  472. if (item.answer == "") {
  473. item.validation = false;
  474. } else {
  475. item.validation = true;
  476. this.$emit("answer", this.question);
  477. this.$emit("contact", this.contactData);
  478. }
  479. } else {
  480. if (item.required !== "") {
  481. item.validation = true;
  482. this.$emit("answer", this.question);
  483. this.$emit("contact", this.contactData);
  484. }
  485. }
  486. });
  487. this.questionValidation = this.question.every(function (item) {
  488. return item.validation == true;
  489. });
  490. this.$emit("bookingDetail_validation", this.questionValidation);
  491. },
  492. getContent() {
  493. this.questions.forEach((item) => {
  494. item.validation = true;
  495. });
  496. this.question = JSON.parse(JSON.stringify(this.questions));
  497. this.question.forEach((item) => {
  498. item.answer = "";
  499. });
  500. },
  501. setQuestion(val, index, item) {
  502. this.question[index].answer = val;
  503. },
  504. },
  505. };
  506. </script>
  507. <style lang="scss" scoped>
  508. .collapse {
  509. @media (min-width: 1366px) {
  510. &::before {
  511. content: "";
  512. display: inline-block;
  513. position: relative;
  514. padding-left: auto;
  515. padding-right: auto;
  516. left: 25px;
  517. top: 0;
  518. background-image: url("~/assets/svg/down-arrow.svg");
  519. background-repeat: no-repeat;
  520. background-position: center;
  521. background-size: 100%;
  522. width: 16px;
  523. height: 10px;
  524. margin-right: 45px;
  525. transform: rotate(-90deg);
  526. transition: all 0.2s linear;
  527. }
  528. &.disabled {
  529. pointer-events: none;
  530. &::before {
  531. background-image: url("~/assets/svg/down-arrow-disabled.svg");
  532. }
  533. }
  534. &.show {
  535. &::before {
  536. transform: rotate(0);
  537. transition: all 0.2s linear;
  538. }
  539. }
  540. }
  541. }
  542. .status-check-icon {
  543. background-image: url("~/assets/svg/status-check.svg");
  544. background-size: 100%;
  545. background-repeat: no-repeat;
  546. background-position: center;
  547. }
  548. .btn-add-icon {
  549. background-image: url("~/assets/svg/plus-blue.svg");
  550. background-repeat: no-repeat;
  551. background-position: left 12px center;
  552. background-size: 16px 16px;
  553. }
  554. .btn-edit-icon {
  555. background-image: url("~/assets/svg/edit-info.svg");
  556. background-repeat: no-repeat;
  557. background-position: center;
  558. background-size: 100%;
  559. }
  560. .bounce-enter-active {
  561. animation: bounce-in 0.3s ease-out;
  562. }
  563. .bounce-leave-active {
  564. animation: bounce-in 0.3s cubic-bezier(1, 0.5, 0.8, 1) reverse;
  565. }
  566. @keyframes bounce-in {
  567. 0% {
  568. opacity: 0;
  569. transform: translateY(-10px);
  570. }
  571. 50% {
  572. opacity: 0.5;
  573. transform: translateY(-5px);
  574. }
  575. 100% {
  576. opacity: 1;
  577. transform: translateY(0);
  578. }
  579. }
  580. </style>