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.

427 lines
12 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_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. </div>
  121. </div>
  122. <!-- country -->
  123. <div class="element">
  124. <elementSelect
  125. :select="{
  126. id: 'Country',
  127. label: 'Country/Region',
  128. required: true,
  129. }"
  130. :selectList="countryOptions"
  131. :default="userData.country"
  132. :validation="validation.country"
  133. @change="userData.country = $event"
  134. ></elementSelect>
  135. </div>
  136. </div>
  137. </div>
  138. <div class="element tw-mt-[40px] tw-text-right">
  139. <button
  140. 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"
  141. @click="OrderingPersonInfo()"
  142. >
  143. {{ $t("Next") }}
  144. </button>
  145. </div>
  146. </div>
  147. </div>
  148. </Transition>
  149. </div>
  150. </client-only>
  151. </template>>
  152. <script>
  153. import elementInput from "@/components/newComponent/form/ElementInput";
  154. import elementSelect from "@/components/newComponent/form/ElementSelect";
  155. import elementCountryCodeSelect from "@/components/newComponent/form/ElementCountryCodeSelect.vue";
  156. import { IsNumber } from "~/utils/common";
  157. import is from "is_js";
  158. export default {
  159. name: "OrderingPersonInfo",
  160. props: {
  161. countryOptions: {
  162. type: Array,
  163. },
  164. infoType: {
  165. type: String,
  166. },
  167. },
  168. components: {
  169. elementInput,
  170. elementSelect,
  171. elementCountryCodeSelect,
  172. IsNumber,
  173. is
  174. },
  175. data() {
  176. return {
  177. show: true,
  178. disabled: false,
  179. updatePersonalInfo: false,
  180. orderingPersonValidation: false,
  181. userData: {
  182. first_name: "",
  183. last_name: "",
  184. email: "",
  185. phone_number: "",
  186. country: "0",
  187. phone_code: "",
  188. UserCompany: [],
  189. },
  190. validation: {
  191. first_name: true,
  192. last_name: true,
  193. email: true,
  194. phone_code: true,
  195. phone_number: true,
  196. country: true,
  197. },
  198. translateOption: {
  199. countrySelectorLabel: this.$t("country code"),
  200. phoneNumberLabel: this.$t("phone number"),
  201. },
  202. error: false,
  203. }
  204. },
  205. created() {
  206. this.getUser()
  207. },
  208. watch: {
  209. orderingPersonValidation: {
  210. handler: function () {
  211. if(this.show){
  212. this.orderingPersonValidation = false
  213. } else {
  214. this.orderingPersonValidation = true
  215. }
  216. }
  217. }
  218. },
  219. methods: {
  220. async getUser() {
  221. await this.$axios
  222. .get(`/trending/api/Onsite/MemberInfo`)
  223. .then((res) => {
  224. if(res && res.data && res.data.DATA && res.data.DATA.rel){
  225. const data = res.data.DATA.rel
  226. if(data){
  227. this.userData.first_name = data.FirstName;
  228. this.userData.last_name = data.LastName;
  229. this.userData.email = data.Email;
  230. this.userData.phone_number = data.Phone;
  231. this.userData.country = data.CountryID;
  232. this.userData.phone_code = data.PhoneCode;
  233. }
  234. }
  235. })
  236. },
  237. getReturnCode(code){
  238. this.userData.phone_code = code;
  239. },
  240. getPhoneData(phoneData) {
  241. this.validation.phone_number = phoneData.isValid;
  242. },
  243. //post 訂購人資料
  244. postOrderingPerson() {
  245. const patchData = JSON.parse(JSON.stringify(this.userData));
  246. let params = {
  247. FirstName: patchData.first_name,
  248. LastName: patchData.last_name,
  249. Email: patchData.email,
  250. Phone: patchData.phone_number,
  251. CountryID: patchData.country,
  252. PhoneCode: patchData.phone_code,
  253. }
  254. this.$axios
  255. .post(
  256. `/trending/api/Onsite/Member`,
  257. params
  258. )
  259. .then((result) => {
  260. console.log(result);
  261. })
  262. .catch((err) => {
  263. console.log(err);
  264. });
  265. },
  266. OrderingPersonInfo() {
  267. if(this.validators()) {
  268. console.log('fuck')
  269. this.show = false;
  270. this.orderingPersonValidation = true
  271. this.$emit('orderingPerson_Validation', this.orderingPersonValidation)
  272. console.log(this.orderingPersonValidation)
  273. }
  274. },
  275. validators() {
  276. if (is.empty(this.userData.first_name)) {
  277. this.validation.first_name = false;
  278. } else {
  279. this.validation.first_name = true;
  280. }
  281. if (is.empty(this.userData.last_name)) {
  282. this.validation.last_name = false;
  283. } else {
  284. this.validation.last_name = true;
  285. }
  286. if (is.empty(this.userData.email) || is.not.email(this.userData.email)) {
  287. this.validation.email = false;
  288. } else {
  289. this.validation.email = true;
  290. }
  291. if (
  292. is.empty(this.userData.phone_number) ||
  293. IsNumber(this.userData.phone_number) == false
  294. ) {
  295. this.validation.phone_number = false;
  296. this.error = true;
  297. } else {
  298. this.validation.phone_number = true;
  299. this.error = false;
  300. }
  301. if (is.empty(this.userData.country) || this.userData.country == "0") {
  302. this.validation.country = false;
  303. } else {
  304. this.validation.country = true;
  305. }
  306. this.errors = Object.entries(this.validation).filter(
  307. (e) => e[1] == false
  308. );
  309. if (this.errors.length > 0) {
  310. this.purchaserValidation = false;
  311. return false;
  312. } else {
  313. return true;
  314. }
  315. },
  316. }
  317. }
  318. </script>
  319. <style lang="scss" scoped>
  320. .collapse {
  321. &::before {
  322. content: "";
  323. display: inline-block;
  324. position: relative;
  325. left: 0;
  326. top: 0;
  327. background-image: url("~/assets/svg/down-arrow.svg");
  328. background-repeat: no-repeat;
  329. background-position: center;
  330. background-size: 100%;
  331. width: 16px;
  332. height: 10px;
  333. margin-right: 40px;
  334. transform: rotate(-90deg);
  335. transition: all 0.2s linear;
  336. }
  337. &.disabled {
  338. pointer-events: none;
  339. &::before {
  340. background-image: url("~/assets/svg/down-arrow-disabled.svg");
  341. }
  342. }
  343. &.show {
  344. &::before {
  345. transform: rotate(0);
  346. transition: all 0.2s linear;
  347. }
  348. }
  349. }
  350. .btn-add-icon {
  351. background-image: url("~/assets/svg/plus-blue.svg");
  352. background-repeat: no-repeat;
  353. background-position: left 12px center;
  354. background-size: 16px 16px;
  355. }
  356. .btn-edit-icon {
  357. background-image: url("~/assets/svg/edit-info.svg");
  358. background-repeat: no-repeat;
  359. background-position: center;
  360. background-size: 100%;
  361. }
  362. .bounce-enter-active {
  363. animation: bounce-in 0.3s ease-out;
  364. }
  365. .bounce-leave-active {
  366. animation: bounce-in 0.3s cubic-bezier(1, 0.5, 0.8, 1) reverse;
  367. }
  368. @keyframes bounce-in {
  369. 0% {
  370. opacity: 0;
  371. transform: translateY(-10px);
  372. }
  373. 50% {
  374. opacity: 0.5;
  375. transform: translateY(-5px);
  376. }
  377. 100% {
  378. opacity: 1;
  379. transform: translateY(0);
  380. }
  381. }
  382. .status-check-icon {
  383. background-image: url("~/assets/svg/status-check.svg");
  384. background-size: 100%;
  385. background-repeat: no-repeat;
  386. background-position: center;
  387. }
  388. :deep(.input-tel__input) {
  389. height: 44px !important;
  390. padding-left: 13px !important;
  391. }
  392. </style>