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.

458 lines
13 KiB

  1. <template>
  2. <client-only>
  3. <!-- 狀態1 -->
  4. <div
  5. class="purchaser-info tw-p-5 tw-mb-[20px] tw-bg-white tw-rounded-xl"
  6. >
  7. <div class="tw-flex tw-flex-row tw-justify-between tw-items-center">
  8. <!-- <template> -->
  9. <h3
  10. v-if="show == true"
  11. :class="[
  12. 'collapse',
  13. 't16',
  14. 'tw-relative',
  15. 'tw-cursor-pointer',
  16. 'xl:tw-text-[18px]',
  17. show ? 'show' : 'hide',
  18. disabled ? 'disabled' : '',
  19. disabled ? 'tw-text-neutrals-300' : 'tw-text-black',
  20. ]"
  21. @click="show = !show"
  22. >
  23. {{ $t("Ordering person") }}
  24. </h3>
  25. <!-- </template> -->
  26. <div v-else>
  27. <h3
  28. :class="[
  29. 'collapse',
  30. 't16',
  31. 'tw-relative',
  32. 'tw-cursor-pointer',
  33. 'xl:tw-text-[18px]',
  34. show ? 'show' : 'hide',
  35. disabled ? 'disabled' : '',
  36. disabled ? 'tw-text-neutrals-300' : 'tw-text-black',
  37. ]"
  38. @click="show = !show"
  39. >{{ userData.first_name }} {{ userData.last_name }}</h3>
  40. <div style="margin-left: 55px;">
  41. <div>{{ '電子信箱 : ' + userData.email }}</div>
  42. <div>{{ '聯絡電話 : ' + userData.phone_code + " " + userData.phone_number }}</div>
  43. </div>
  44. </div>
  45. <div class="element content-status xl:tw-ml-[20px]">
  46. <span
  47. v-if="orderingPersonValidation == true"
  48. class="status-check-icon tw-inline-block tw-w-[30px] tw-h-[30px]"
  49. ></span>
  50. </div>
  51. </div>
  52. <Transition name="bounce">
  53. <div v-show="show">
  54. <div class="tw-mt-[32px] md:tw-ml-[60px]">
  55. <div class="element element-tabs tw-mb-[20px]">
  56. <div
  57. 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]"
  58. >
  59. <!-- first name -->
  60. <div class="element">
  61. <elementInput
  62. :input="{
  63. id: 'FirstName',
  64. label: 'First Name',
  65. required: true,
  66. type: 'text',
  67. }"
  68. :default="userData.first_name"
  69. :validation="validation.first_name"
  70. @change="userData.first_name = $event"
  71. ></elementInput>
  72. </div>
  73. <!-- last name -->
  74. <div class="element">
  75. <elementInput
  76. :input="{
  77. id: 'LastName',
  78. label: 'Last Name',
  79. required: true,
  80. type: 'text',
  81. }"
  82. :default="userData.last_name"
  83. :validation="validation.last_name"
  84. @change="userData.last_name = $event"
  85. ></elementInput>
  86. </div>
  87. <!-- Email -->
  88. <div class="element">
  89. <elementInput
  90. :input="{
  91. id: 'ContactEmail',
  92. label: 'Contact Email',
  93. required: true,
  94. type: 'email',
  95. }"
  96. :default="userData.email"
  97. :validation="validation.email"
  98. @change="userData.email = $event"
  99. >
  100. </elementInput>
  101. </div>
  102. <!-- phoneNumber -->
  103. <div class="element">
  104. <label class="tw-block tw-mb-[10px]"
  105. ><span
  106. >{{ $t("Phone") }}<span class="required">*</span></span
  107. ></label
  108. >
  109. <div class="tw-grid tw-grid-cols-[120px_auto] tw-gap-[5px]">
  110. <elementCountryCodeSelect :select="{
  111. required: true,
  112. }" :userCodeSelect="userData.phone_code" :validation="validation.phone_code" @returnCode = "getReturnCode"
  113. >
  114. </elementCountryCodeSelect>
  115. <vue-phone-number-input v-model="userData.phone_number" :validation="validation.phone_number" color="#E5e5e5" error-color="#ef5a5a"
  116. valid-color="#e5e5e5"
  117. :error="error" :border-radius="5"
  118. no-flags :no-country-selector="true" no-example @update="getPhoneData" :translations="translateOption">
  119. </vue-phone-number-input>
  120. <!-- <vue-phone-number-input v-model="userData.phone_number" :validation="validation.phone_number" color="#E5e5e5" error-color="#ef5a5a"
  121. valid-color="#e5e5e5"
  122. :error="error" :border-radius="5"
  123. no-flags :no-country-selector="true" no-example @update="getPhoneData" :translations="translateOption">
  124. </vue-phone-number-input> -->
  125. </div>
  126. </div>
  127. <!-- country -->
  128. <div class="element">
  129. <elementSelect
  130. :select="{
  131. id: 'Country',
  132. label: 'Country/Region',
  133. required: true,
  134. }"
  135. :selectList="countryOptions"
  136. :default="userData.country"
  137. :validation="validation.country"
  138. @change="userData.country = $event"
  139. ></elementSelect>
  140. </div>
  141. </div>
  142. </div>
  143. <div class="element tw-mt-[40px] tw-text-right">
  144. <button
  145. 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"
  146. @click="OrderingPersonInfo()"
  147. >
  148. {{ $t("Next") }}
  149. </button>
  150. </div>
  151. </div>
  152. </div>
  153. </Transition>
  154. </div>
  155. </client-only>
  156. </template>
  157. <script>
  158. import elementInput from "@/components/newComponent/form/ElementInput";
  159. import elementSelect from "@/components/newComponent/form/ElementSelect";
  160. import elementCountryCodeSelect from "@/components/newComponent/form/ElementCountryCodeSelect.vue";
  161. import { IsNumber } from "~/utils/common";
  162. import is from "is_js";
  163. export default {
  164. name: "OrderingPersonInfo",
  165. props: {
  166. countryOptions: {
  167. type: Array,
  168. },
  169. infoType: {
  170. type: String,
  171. },
  172. },
  173. components: {
  174. elementInput,
  175. elementSelect,
  176. elementCountryCodeSelect,
  177. IsNumber,
  178. is
  179. },
  180. data() {
  181. return {
  182. show: true,
  183. disabled: false,
  184. updatePersonalInfo: false,
  185. orderingPersonValidation: false,
  186. userData: {
  187. first_name: "",
  188. last_name: "",
  189. email: "",
  190. phone_number: "",
  191. country: "0",
  192. phone_code: "0",
  193. UserCompany: [],
  194. },
  195. validation: {
  196. first_name: true,
  197. last_name: true,
  198. email: true,
  199. phone_code: true,
  200. phone_number: true,
  201. country: true,
  202. },
  203. translateOption: {
  204. countrySelectorLabel: this.$t("country code"),
  205. phoneNumberLabel: this.$t("phone number"),
  206. },
  207. error: false,
  208. value: "0",
  209. }
  210. },
  211. created() {
  212. this.getUser()
  213. },
  214. watch: {
  215. orderingPersonValidation: {
  216. handler: function () {
  217. if(this.show){
  218. this.orderingPersonValidation = false
  219. } else {
  220. this.orderingPersonValidation = true
  221. }
  222. }
  223. }
  224. },
  225. methods: {
  226. async getUser() {
  227. await this.$axios
  228. .get(`/trending/api/Onsite/MemberInfo`)
  229. .then((res) => {
  230. if(res && res.data && res.data.DATA && res.data.DATA.rel){
  231. const data = res.data.DATA.rel
  232. if(data){
  233. //console.log(JSON.stringify(data));
  234. this.userData.first_name = data.FirstName;
  235. this.userData.last_name = data.LastName;
  236. this.userData.email = data.Email;
  237. this.userData.phone_number = data.Phone;
  238. if(data.CountryID == null){
  239. this.userData.country = "0";
  240. }else{
  241. this.userData.country = data.CountryID;
  242. }
  243. if(data.PhoneCode == null){
  244. this.userData.phone_code = "0";
  245. }else{
  246. this.userData.phone_code = data.PhoneCode;
  247. }
  248. }
  249. }
  250. })
  251. },
  252. getReturnCode(code){
  253. this.userData.phone_code = code;
  254. },
  255. getPhoneData(phoneData) {
  256. this.validation.phone_number = phoneData.isValid;
  257. },
  258. //post 訂購人資料
  259. postOrderingPerson() {
  260. const patchData = JSON.parse(JSON.stringify(this.userData));
  261. let params = {
  262. FirstName: patchData.first_name,
  263. LastName: patchData.last_name,
  264. Email: patchData.email,
  265. Phone: patchData.phone_number,
  266. CountryID: patchData.country,
  267. PhoneCode: patchData.phone_code,
  268. }
  269. this.$axios
  270. .post(
  271. `/trending/api/Onsite/Member`,
  272. params
  273. )
  274. .then((result) => {
  275. //console.log(result);
  276. })
  277. .catch((err) => {
  278. console.log(err);
  279. });
  280. },
  281. OrderingPersonInfo() {
  282. if(this.validators()) {
  283. this.show = false;
  284. this.orderingPersonValidation = true
  285. this.$emit('orderingPerson_Validation', this.orderingPersonValidation)
  286. const personInfo = JSON.parse(JSON.stringify(this.userData));
  287. //訂購人資訊
  288. let orderingPersonInfo = {
  289. FirstName: personInfo.first_name,
  290. LastName: personInfo.last_name,
  291. Email: personInfo.email,
  292. Phone: personInfo.phone_number,
  293. CountryID: personInfo.country,
  294. PhoneCode: personInfo.phone_code,
  295. }
  296. this.$emit('orderingPersonInfo', orderingPersonInfo);
  297. }
  298. },
  299. validators() {
  300. if (is.empty(this.userData.first_name)) {
  301. this.validation.first_name = false;
  302. } else {
  303. this.validation.first_name = true;
  304. }
  305. if (is.empty(this.userData.last_name)) {
  306. this.validation.last_name = false;
  307. } else {
  308. this.validation.last_name = true;
  309. }
  310. if (is.empty(this.userData.email) || is.not.email(this.userData.email)) {
  311. this.validation.email = false;
  312. } else {
  313. this.validation.email = true;
  314. }
  315. if (
  316. is.empty(this.userData.phone_number) ||
  317. IsNumber(this.userData.phone_number) == false
  318. ) {
  319. this.validation.phone_number = false;
  320. this.error = true;
  321. } else {
  322. this.validation.phone_number = true;
  323. this.error = false;
  324. }
  325. if (
  326. is.empty(this.userData.phone_code) ||
  327. this.userData.phone_code == '0'
  328. ) {
  329. this.validation.phone_code = false;
  330. } else {
  331. this.validation.phone_code = true;
  332. }
  333. if (is.empty(this.userData.country) || this.userData.country == "0") {
  334. this.validation.country = false;
  335. } else {
  336. this.validation.country = true;
  337. }
  338. this.errors = Object.entries(this.validation).filter(
  339. (e) => e[1] == false
  340. );
  341. if (this.errors.length > 0) {
  342. this.purchaserValidation = false;
  343. return false;
  344. } else {
  345. return true;
  346. }
  347. },
  348. }
  349. }
  350. </script>
  351. <style lang="scss" scoped>
  352. .collapse {
  353. &::before {
  354. content: "";
  355. display: inline-block;
  356. position: relative;
  357. left: 0;
  358. top: 0;
  359. background-image: url("~/assets/svg/down-arrow.svg");
  360. background-repeat: no-repeat;
  361. background-position: center;
  362. background-size: 100%;
  363. width: 16px;
  364. height: 10px;
  365. margin-right: 40px;
  366. transform: rotate(-90deg);
  367. transition: all 0.2s linear;
  368. }
  369. &.disabled {
  370. pointer-events: none;
  371. &::before {
  372. background-image: url("~/assets/svg/down-arrow-disabled.svg");
  373. }
  374. }
  375. &.show {
  376. &::before {
  377. transform: rotate(0);
  378. transition: all 0.2s linear;
  379. }
  380. }
  381. }
  382. .btn-add-icon {
  383. background-image: url("~/assets/svg/plus-blue.svg");
  384. background-repeat: no-repeat;
  385. background-position: left 12px center;
  386. background-size: 16px 16px;
  387. }
  388. .btn-edit-icon {
  389. background-image: url("~/assets/svg/edit-info.svg");
  390. background-repeat: no-repeat;
  391. background-position: center;
  392. background-size: 100%;
  393. }
  394. .bounce-enter-active {
  395. animation: bounce-in 0.3s ease-out;
  396. }
  397. .bounce-leave-active {
  398. animation: bounce-in 0.3s cubic-bezier(1, 0.5, 0.8, 1) reverse;
  399. }
  400. @keyframes bounce-in {
  401. 0% {
  402. opacity: 0;
  403. transform: translateY(-10px);
  404. }
  405. 50% {
  406. opacity: 0.5;
  407. transform: translateY(-5px);
  408. }
  409. 100% {
  410. opacity: 1;
  411. transform: translateY(0);
  412. }
  413. }
  414. .status-check-icon {
  415. background-image: url("~/assets/svg/status-check.svg");
  416. background-size: 100%;
  417. background-repeat: no-repeat;
  418. background-position: center;
  419. }
  420. :deep(.input-tel__input) {
  421. height: 44px !important;
  422. padding-left: 13px !important;
  423. }
  424. </style>