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.

614 lines
19 KiB

2 years ago
  1. <template>
  2. <div
  3. class="purchaser-info tw-p-5 tw-mb-[20px] tw-bg-neutrals-0 tw-rounded-xl"
  4. >
  5. <div class="tw-flex tw-flex-row tw-justify-between tw-items-center">
  6. <h3
  7. :class="[
  8. 'collapse',
  9. 't16',
  10. 'tw-relative',
  11. 'tw-cursor-pointer',
  12. 'xl:tw-text-[18px]',
  13. show ? 'show' : 'hide',
  14. disabled ? 'disabled' : '',
  15. disabled ? 'tw-text-neutrals-300' : 'tw-text-black',
  16. ]"
  17. @click="show = !show"
  18. >
  19. {{ $t("Purchaser Info") }}
  20. </h3>
  21. <div class="element content-status xl:tw-ml-[20px]">
  22. <span
  23. v-if="purchaserValidation == true"
  24. class="status-check-icon tw-inline-block tw-w-[30px] tw-h-[30px]"
  25. ></span>
  26. </div>
  27. </div>
  28. <Transition name="bounce">
  29. <div v-show="show">
  30. <div class="tw-mt-[32px] md:tw-ml-[60px]">
  31. <div class="element element-tabs tw-mb-[20px]">
  32. <button
  33. :class="[
  34. 'tw-transition',
  35. 'tw-btn-md',
  36. 'tw-border',
  37. 'tw-border-solid',
  38. 'tw-border-neutrals-300',
  39. 'tw-px-[30px]',
  40. ' tw-py-[9.5px]',
  41. ' tw-rounded-2xl',
  42. infoType == 'Individual'
  43. ? 'tw-bg-neutrals-800 tw-text-neutrals-0'
  44. : 'tw-bg-neutrals-0 tw-text-neutrals-300',
  45. ]"
  46. @click="$emit('type', 'Individual')"
  47. >
  48. Individual
  49. </button>
  50. <button
  51. :class="[
  52. 'tw-transition',
  53. 'tw-btn-md',
  54. 'tw-border',
  55. 'tw-border-solid',
  56. 'tw-border-neutrals-300',
  57. 'tw-px-[30px]',
  58. ' tw-py-[9.5px]',
  59. ' tw-rounded-2xl',
  60. infoType == 'Company'
  61. ? 'tw-bg-neutrals-800 tw-text-neutrals-0'
  62. : 'tw-bg-neutrals-0 tw-text-neutrals-300',
  63. ]"
  64. @click="$emit('type', 'Company')"
  65. >
  66. Company
  67. </button>
  68. </div>
  69. <div v-show="infoType == 'Individual'">
  70. <div
  71. class="element element-form tw-grid tw-grid-cols-1 tw-gap-[10px] md:tw-grid-cols-2 md:tw-gap-x-[60px] md:tw-gap-y-[20px] md:tw-max-w-[580px]"
  72. >
  73. <div class="element">
  74. <elementInput
  75. :input="{
  76. id: 'FirstName',
  77. label: 'First name',
  78. required: true,
  79. type: 'text',
  80. }"
  81. :default="userData.first_name"
  82. :validation="validation.first_name"
  83. @change="userData.first_name = $event"
  84. ></elementInput>
  85. </div>
  86. <div class="element">
  87. <elementInput
  88. :input="{
  89. id: 'LastName',
  90. label: 'Last Name',
  91. required: true,
  92. type: 'text',
  93. }"
  94. :default="userData.last_name"
  95. :validation="validation.last_name"
  96. @change="userData.last_name = $event"
  97. ></elementInput>
  98. </div>
  99. <div class="element">
  100. <elementInput
  101. :input="{
  102. id: 'ContactEmail',
  103. label: 'Contact Email',
  104. required: true,
  105. type: 'email',
  106. }"
  107. :default="userData.email"
  108. :validation="validation.email"
  109. @change="userData.email = $event"
  110. >
  111. </elementInput>
  112. </div>
  113. <div class="element">
  114. <label class="tw-block tw-mb-[10px]"
  115. ><span
  116. >{{ $t("Phone") }}<span class="required">*</span></span
  117. ></label
  118. >
  119. <vue-country-code
  120. class="d-none"
  121. enabledCountryCode
  122. :enabledFlags="false"
  123. ></vue-country-code>
  124. <vue-phone-number-input
  125. color="#e5e5e5"
  126. :border-radius="5"
  127. error-color="#ef5a5a"
  128. valid-color="#e5e5e5"
  129. :error="error"
  130. required
  131. no-flags
  132. no-example
  133. :validation="validation.phone_number"
  134. v-model="userData.phone_number"
  135. ></vue-phone-number-input>
  136. </div>
  137. <div class="element">
  138. <elementSelect
  139. :select="{
  140. id: 'Country',
  141. label: 'Country/Region',
  142. required: true,
  143. }"
  144. :selectList="countryOptions"
  145. :default="userData.country"
  146. :validation="validation.country"
  147. @change="userData.country = $event"
  148. ></elementSelect>
  149. </div>
  150. <div class="element md:tw-col-span-2 tw-mt-[30px]">
  151. <elementCheckBox
  152. :input="{
  153. id: 'SaveInfo',
  154. label: 'Update personal info in your account',
  155. }"
  156. @update="updatePersonalInfo = $event"
  157. ></elementCheckBox>
  158. </div>
  159. </div>
  160. </div>
  161. <div v-show="infoType == 'Company'">
  162. <div
  163. class="element element-form tw-grid tw-grid-cols-1 tw-gap-y-[20px]"
  164. >
  165. <div
  166. class="element element-button-group tw-flex tw-justify-start tw-flex-wrap -tw-mx-[8px]"
  167. >
  168. <button
  169. v-for="(item, index) in userCompanyList"
  170. :key="index"
  171. :class="[
  172. 'tw-transition',
  173. 'tw-btn-md',
  174. 'tw-text-[14px]',
  175. 'tw-leading-[18px]',
  176. 'tw-text-complementary-1',
  177. 'tw-bg-neutrals-0',
  178. 'tw-px-[12px]',
  179. 'tw-py-[11px]',
  180. 'tw-mx-[8px]',
  181. 'tw-mb-[16px]',
  182. 'tw-rounded-2xl',
  183. 'tw-border tw-border-solid',
  184. 'tw-bg-complementary-3',
  185. activeLabel == index + 1
  186. ? 'tw-border-complementary-1 tw-bg-complementary-1/20'
  187. : 'tw-border-transparent',
  188. ]"
  189. @click="onLabelClick(index + 1, item)"
  190. >
  191. {{ item.company_name }}
  192. </button>
  193. <button
  194. 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]"
  195. @click="$modal.show('add-modal')"
  196. >
  197. {{ $t("Add") }}
  198. </button>
  199. </div>
  200. <div class="company-info-list">
  201. <template v-for="(item, index) in userCompanyList">
  202. <div
  203. :key="index"
  204. v-if="index + 1 === activeLabel"
  205. class="tw-grid tw-grid-cols-1 tw-gap-y-[16px]"
  206. >
  207. <div
  208. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  209. >
  210. <div class="label t14 tw-font-bold">
  211. {{ $t("Company Name") }}
  212. </div>
  213. <div class="content tw-body-4">
  214. {{ item.company_name }}
  215. </div>
  216. </div>
  217. <div
  218. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  219. >
  220. <div class="label t14 tw-font-bold">
  221. {{ $t("Tax Number") }}
  222. </div>
  223. <div class="content tw-body-4">
  224. {{ item.company_tax_no }}
  225. </div>
  226. </div>
  227. <div
  228. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  229. >
  230. <div class="label t14 tw-font-bold">
  231. {{ $t("Street Address") }}
  232. </div>
  233. <div class="content tw-body-4">
  234. {{ item.company_address1 }}{{ item.company_address2 }}
  235. </div>
  236. </div>
  237. <div
  238. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  239. >
  240. <div class="label t14 tw-font-bold">{{ $t("City") }}</div>
  241. <div class="content tw-body-4">
  242. {{ item.company_city }}
  243. </div>
  244. </div>
  245. <div
  246. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  247. >
  248. <div class="label t14 tw-font-bold">
  249. {{ $t("State/Province") }}
  250. </div>
  251. <div class="content tw-body-4">
  252. {{ item.company_state }}
  253. </div>
  254. </div>
  255. <div
  256. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  257. >
  258. <div class="label t14 tw-font-bold">
  259. {{ $t("Country") }}
  260. </div>
  261. <div class="content tw-body-4">
  262. {{ item.company_country_name }}
  263. </div>
  264. </div>
  265. <div
  266. class="element tw-grid tw-grid-cols-[140px_auto] tw-gap-x-[12px]"
  267. >
  268. <div class="label t14 tw-font-bold">
  269. {{ $t("ZIP/Postal Code") }}
  270. </div>
  271. <div class="content tw-body-4">
  272. {{ item.company_zipcode }}
  273. </div>
  274. </div>
  275. <button
  276. class="btn-edit-icon tw-w-[28px] tw-h-[28px]"
  277. @click="$modal.show('edit-modal')"
  278. ></button>
  279. </div>
  280. </template>
  281. </div>
  282. </div>
  283. </div>
  284. <div class="element tw-mt-[40px] tw-text-right">
  285. <button
  286. class="tw-transition tw-btn-md tw-bg-primary-1 tw-px-[30px] tw-py-[9.5px] tw-rounded-2xl hover:tw-bg-primary-2"
  287. @click="updatePurchaserInfo"
  288. >
  289. {{ $t("Next") }}
  290. </button>
  291. </div>
  292. </div>
  293. </div>
  294. </Transition>
  295. </div>
  296. </template>
  297. <script>
  298. import elementInput from "@/components/newComponent/form/ElementInput";
  299. import elementSelect from "@/components/newComponent/form/ElementSelect";
  300. import elementCheckBox from "@/components/newComponent/form/ElementCheckBox";
  301. import is from "is_js";
  302. export default {
  303. name: "PurchaserInfo",
  304. props: {
  305. userCompanyList: {
  306. type: Array,
  307. },
  308. countryOptions: {
  309. type: Array,
  310. },
  311. infoType: {
  312. type: String,
  313. },
  314. bookingDetail_Validation: {
  315. type: Boolean,
  316. },
  317. },
  318. components: {
  319. elementInput,
  320. elementSelect,
  321. elementCheckBox,
  322. is,
  323. },
  324. data() {
  325. return {
  326. show: false,
  327. disabled: false,
  328. completed: false,
  329. userData: {
  330. first_name: "",
  331. last_name: "",
  332. email: "",
  333. phone_number: "",
  334. country: 0,
  335. country_code: "",
  336. UserCompany: [],
  337. },
  338. updatePersonalInfo: false,
  339. userContactList: [],
  340. activeLabel: 0,
  341. Individual: {
  342. FirstName: "",
  343. LastName: "",
  344. Email: "",
  345. phone_number: "",
  346. Country: "",
  347. },
  348. Company: {
  349. company_name: "",
  350. company_tax_no: "",
  351. company_address1: "",
  352. company_address2: "",
  353. company_city: "",
  354. company_state: "",
  355. company_country: "",
  356. company_zipcode: "",
  357. },
  358. validation: {
  359. first_name: true,
  360. last_name: true,
  361. email: true,
  362. phone_number: true,
  363. country: true,
  364. },
  365. errors: null,
  366. purchaserValidation: false,
  367. error: true,
  368. isValid: false,
  369. };
  370. },
  371. async created() {
  372. if (this.$auth.loggedIn) {
  373. await this.getUser();
  374. }
  375. },
  376. watch: {
  377. userCompanyList: {
  378. handler: function () {
  379. if (this.userCompanyList) {
  380. this.activeLabel = this.userCompanyList.length > 0 ? 1 : 0;
  381. this.Company.company_name = this.userCompanyList[0].company_name;
  382. this.Company.company_tax_no = this.userCompanyList[0].company_tax_no;
  383. this.Company.company_address1 =
  384. this.userCompanyList[0].company_address1;
  385. this.Company.company_address2 =
  386. this.userCompanyList[0].company_address2;
  387. this.Company.company_city = this.userCompanyList[0].company_city;
  388. this.Company.company_state = this.userCompanyList[0].company_state;
  389. this.Company.company_country =
  390. this.userCompanyList[0].company_country_name;
  391. this.Company.company_zipcode =
  392. this.userCompanyList[0].company_zipcode;
  393. }
  394. },
  395. },
  396. bookingDetail_Validation: {
  397. handler: function () {
  398. if (this.bookingDetail_Validation) {
  399. this.show = true;
  400. } else {
  401. this.show = false;
  402. }
  403. },
  404. },
  405. purchaserValidation: {
  406. handler: function () {
  407. if (this.purchaserValidation) {
  408. this.show = false;
  409. }
  410. },
  411. },
  412. },
  413. methods: {
  414. onLabelClick(label, item) {
  415. this.activeLabel = label;
  416. this.$emit("active", this.activeLabel);
  417. this.Company.company_name = item.company_name;
  418. this.Company.company_tax_no = item.company_tax_no;
  419. this.Company.company_address1 = item.company_address1;
  420. this.Company.company_address2 = item.company_address2;
  421. this.Company.company_city = item.company_city;
  422. this.Company.company_state = item.company_state;
  423. this.Company.company_country = item.company_country_name;
  424. this.Company.company_zipcode = item.company_zipcode;
  425. },
  426. async getUser() {
  427. await this.$axios
  428. .get(
  429. `/member/users/${
  430. this.$auth.$storage.getUniversal("jwt").user_id
  431. }?jwt=${this.$auth.$storage.getUniversal("jwt").token}`
  432. )
  433. .then((result) => {
  434. this.userData.first_name = result.data.first_name;
  435. this.userData.last_name = result.data.last_name;
  436. this.userData.email = result.data.email;
  437. this.userData.phone_number = result.data.phone;
  438. this.userData.country = result.data.country;
  439. this.userData.country_code = result.data.country_code;
  440. this.userData.UserCompany = result.data.UserCompany;
  441. })
  442. .catch((err) => {
  443. console.log(err);
  444. });
  445. },
  446. updateIndividual() {
  447. const patchData = JSON.parse(JSON.stringify(this.userData));
  448. delete patchData.UserCompany;
  449. this.$axios
  450. .put(
  451. `/member/users/${
  452. this.$auth.$storage.getUniversal("jwt").user_id
  453. }?jwt=${this.$auth.$storage.getUniversal("jwt").token}`,
  454. patchData
  455. )
  456. .then((result) => {
  457. console.log(result);
  458. })
  459. .catch((err) => {
  460. console.log(err);
  461. });
  462. },
  463. updatePurchaserInfo() {
  464. switch (this.infoType) {
  465. case "Individual":
  466. this.validators();
  467. if (this.validators()) {
  468. this.updateIndividual();
  469. this.$emit("type", "Individual");
  470. this.$emit("individual", this.userData);
  471. this.$emit("company", {});
  472. this.purchaserValidation = true;
  473. this.$emit("purchaserInfo_validation", this.purchaserValidation);
  474. } else {
  475. this.purchaserValidation = false;
  476. this.$emit("purchaserInfo_validation", this.purchaserValidation);
  477. }
  478. break;
  479. case "Company":
  480. this.$emit("type", "Company");
  481. this.$emit("company", this.Company);
  482. this.$emit("individual", {});
  483. break;
  484. }
  485. },
  486. validators() {
  487. if (is.empty(this.userData.first_name)) {
  488. this.validation.first_name = false;
  489. } else {
  490. this.validation.first_name = true;
  491. }
  492. if (is.empty(this.userData.last_name)) {
  493. this.validation.last_name = false;
  494. } else {
  495. this.validation.last_name = true;
  496. }
  497. if (is.empty(this.userData.email) || is.not.email(this.userData.email)) {
  498. this.validation.email = false;
  499. } else {
  500. this.validation.email = true;
  501. }
  502. if (
  503. this.userData.phone_number == null
  504. // is.empty(this.userData.phone_number) &&
  505. // is.number(this.userData.phone_number)
  506. ) {
  507. this.validation.phone_number = false;
  508. this.error = true;
  509. } else {
  510. this.validation.phone_number = true;
  511. this.error = false;
  512. }
  513. if (is.empty(this.userData.country) || this.userData.country == 0) {
  514. this.validation.country = false;
  515. } else {
  516. this.validation.country = true;
  517. }
  518. this.errors = Object.entries(this.validation).filter(
  519. (e) => e[1] == false
  520. );
  521. if (this.errors.length > 0) {
  522. return false;
  523. } else {
  524. return true;
  525. }
  526. },
  527. },
  528. };
  529. </script>
  530. <style lang="scss" scoped>
  531. .collapse {
  532. &::before {
  533. content: "";
  534. display: inline-block;
  535. position: relative;
  536. left: 0;
  537. top: 0;
  538. background-image: url("~/assets/svg/down-arrow.svg");
  539. background-repeat: no-repeat;
  540. background-position: center;
  541. background-size: 100%;
  542. width: 16px;
  543. height: 10px;
  544. margin-right: 40px;
  545. transform: rotate(-90deg);
  546. transition: all 0.2s linear;
  547. }
  548. &.disabled {
  549. pointer-events: none;
  550. &::before {
  551. background-image: url("~/assets/svg/down-arrow-disabled.svg");
  552. }
  553. }
  554. &.show {
  555. &::before {
  556. transform: rotate(0);
  557. transition: all 0.2s linear;
  558. }
  559. }
  560. }
  561. .btn-add-icon {
  562. background-image: url("~/assets/svg/plus-blue.svg");
  563. background-repeat: no-repeat;
  564. background-position: left 12px center;
  565. background-size: 16px 16px;
  566. }
  567. .btn-edit-icon {
  568. background-image: url("~/assets/svg/edit-info.svg");
  569. background-repeat: no-repeat;
  570. background-position: center;
  571. background-size: 100%;
  572. }
  573. .bounce-enter-active {
  574. animation: bounce-in 0.3s ease-out;
  575. }
  576. .bounce-leave-active {
  577. animation: bounce-in 0.3s cubic-bezier(1, 0.5, 0.8, 1) reverse;
  578. }
  579. @keyframes bounce-in {
  580. 0% {
  581. opacity: 0;
  582. transform: translateY(-10px);
  583. }
  584. 50% {
  585. opacity: 0.5;
  586. transform: translateY(-5px);
  587. }
  588. 100% {
  589. opacity: 1;
  590. transform: translateY(0);
  591. }
  592. }
  593. .status-check-icon {
  594. background-image: url("~/assets/svg/status-check.svg");
  595. background-size: 100%;
  596. background-repeat: no-repeat;
  597. background-position: center;
  598. }
  599. </style>