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.

376 lines
11 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
  1. <template>
  2. <div
  3. class="booking-info-item tw-p-[15px] lg:tw-p-[20px] tw-mb-[30px] tw-bg-white 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="info.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. {{ item }}
  29. </div>
  30. <div class="tw-mb-[10px] tw-my-[12px] xl:tw-mb-0 tw-flex t-12 tw-text-[#232323]"
  31. >
  32. <div>{{ $t("Select Exhibition") }}</div>
  33. <div class="tw-ml-[10px]">{{ info.selectExhibition }}</div>
  34. </div>
  35. </div>
  36. <div class="element content-status tw-hidden xl:tw-block xl:tw-ml-[20px]">
  37. <span
  38. v-if="questionValidation == true"
  39. class="status-check-icon tw-inline-block tw-w-[30px] tw-h-[30px]"
  40. ></span>
  41. </div>
  42. </div>
  43. <Transition name="bounce">
  44. <div v-show="show" :class="['info-form']">
  45. <div
  46. :class="[
  47. 'bookingdetails',
  48. 'tw-border-0 tw-border-t tw-border-solid tw-border-neutrals-200',
  49. 'tw-pt-[20px] tw-mt-[20px]',
  50. ]"
  51. >
  52. <h3 class="tw-mb-[40px] t18 tw-font-bold tw-text-black">{{ $t("Ordering details") }}</h3>
  53. <table class="table-auto">
  54. <template v-for="(item,index) in questions">
  55. <template v-if="windewWidth>414">
  56. <tr v-if="item.type != 'MultilineText'" class="element tw-my-[10px]" :key="index">
  57. <td class="tw-pr-[20px]">
  58. <div class="tw-items-center">
  59. <label class="tw-font-normal "><span>{{ item.name }}
  60. <span v-if="item.requiredFlag=='1'" class="required t12 md:t14">*</span></span></label>
  61. </div>
  62. </td>
  63. <td>
  64. <div class="element tw-my-[10px]">
  65. <div class="md:tw-flex tw-items-center" v-if="item.type == 'DateText'">
  66. <selectDate @selected="item.value = $event"></selectDate>
  67. <span v-if="item.validation==false" class="required md:tw-ml-[20px] t12 md:t14">{{ $t("Required.") }}</span>
  68. </div>
  69. <div class="md:tw-flex tw-items-center" v-else-if="item.type == 'TimeText'">
  70. <elementTimePicker @change="item.value = $event"></elementTimePicker>
  71. <span v-if="item.validation==false" class="required md:tw-ml-[20px] t12 md:t14">{{ $t("Required.") }}</span>
  72. </div>
  73. <elementInputNew v-else-if="item.type == 'SingleText'"
  74. :input="{
  75. id: item.id,
  76. required: item.requiredFlag=='1' ? true : false,
  77. type: 'text',
  78. placeholder: '',
  79. }"
  80. :validation="item.validation"
  81. @change="item.value = $event"
  82. >
  83. </elementInputNew>
  84. </div>
  85. </td>
  86. </tr>
  87. </template>
  88. <template v-else>
  89. <template v-if="item.type != 'MultilineText'">
  90. <tr class="element" :key="index">
  91. <div class="tw-items-center">
  92. <label class="tw-font-normal "><span>{{ item.name }}
  93. <span v-if="item.requiredFlag=='1'" class="required t12 md:t14">*</span></span></label>
  94. </div>
  95. </tr>
  96. <tr class="element" :key="item.id+index">
  97. <div class="element tw-my-[10px]">
  98. <div class="md:tw-flex tw-items-center" v-if="item.type == 'DateText'">
  99. <selectDate @selected="item.value = $event"></selectDate>
  100. <span v-if="item.validation==false" class="required md:tw-ml-[20px] t12 md:t14">{{ $t("Required.") }}</span>
  101. </div>
  102. <div class="md:tw-flex tw-items-center" v-else-if="item.type == 'TimeText'">
  103. <elementTimePicker @change="item.value = $event"></elementTimePicker>
  104. <span v-if="item.validation==false" class="required md:tw-ml-[20px] t12 md:t14">{{ $t("Required.") }}</span>
  105. </div>
  106. <elementInputNew v-else-if="item.type == 'SingleText'"
  107. :input="{
  108. id: item.id,
  109. required: item.requiredFlag=='1' ? true : false,
  110. type: 'text',
  111. placeholder: '',
  112. }"
  113. :validation="item.validation"
  114. @change="item.value = $event"
  115. >
  116. </elementInputNew>
  117. </div>
  118. </tr>
  119. </template>
  120. </template>
  121. </template>
  122. </table>
  123. <template v-for="item in questions">
  124. <div v-if="item.type == 'MultilineText'" class="element tw-my-[10px]" :key="item.id">
  125. <elementTextarea
  126. :input="{
  127. id: item.id,
  128. label: item.name,
  129. required: false,
  130. placeholder: '',
  131. }"
  132. :default="''"
  133. :validation="true"
  134. @change="item.value = $event"
  135. ></elementTextarea>
  136. </div>
  137. </template>
  138. </div>
  139. <div class="element tw-text-right tw-mt-[40px]">
  140. <button
  141. 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"
  142. @click="updateInfo()"
  143. >
  144. {{ $t("Next") }}
  145. </button>
  146. </div>
  147. </div>
  148. </Transition>
  149. </div>
  150. </template>
  151. <script>
  152. import elementTextarea from "@/components/newComponent/form/ElementTextarea";
  153. import elementInputNew from "@/components/newComponent/form/ElementInputNew";
  154. import selectDate from "@/components/service/content/selectDate.vue";
  155. import elementTimePicker from "@/components/newComponent/form/ElementTimePicker";
  156. import Contact from "@/components/service/Contact";
  157. import is from "is_js";
  158. export default {
  159. components: {
  160. elementTextarea,
  161. elementInputNew,
  162. selectDate,
  163. elementTimePicker,
  164. is,
  165. Contact,
  166. },
  167. props: {
  168. info: {
  169. type: Object,
  170. },
  171. content: {
  172. type: Object,
  173. },
  174. questions: {
  175. type: Array,
  176. default: [],
  177. },
  178. active: {
  179. type: Number,
  180. },
  181. orderingPerson_Validation: {
  182. type: Boolean,
  183. }
  184. },
  185. data() {
  186. return {
  187. show: false,
  188. contactData: {
  189. first_name: "",
  190. last_name: "",
  191. email: "",
  192. phone_number: "",
  193. },
  194. questionValidation: false,
  195. errors: null,
  196. windewWidth: null,
  197. };
  198. },
  199. computed: {
  200. activeLabel() {
  201. return this.active;
  202. },
  203. },
  204. mounted() {
  205. let vm = this;
  206. vm.$nextTick(function () {
  207. });
  208. },
  209. created(){
  210. if (process.browser) {
  211. window.addEventListener("resize", this.handleResize);
  212. }
  213. this.handleResize();
  214. },
  215. destroyed() {
  216. if (process.browser) {
  217. window.removeEventListener("resize", this.handleResize);
  218. }
  219. },
  220. watch: {
  221. orderingPerson_Validation: {
  222. handler: function () {
  223. if (this.orderingPerson_Validation == true) {
  224. this.show = true;
  225. } else {
  226. this.show = false;
  227. }
  228. },
  229. },
  230. questionValidation: {
  231. handler: function () {
  232. if (this.questionValidation == true) {
  233. this.show = false;
  234. }else{
  235. this.show = true;
  236. }
  237. },
  238. },
  239. },
  240. methods: {
  241. handleResize() {
  242. if (process.browser) {
  243. this.windewWidth = window.innerWidth;
  244. }
  245. },
  246. updateInfo() {
  247. // 需要先校驗
  248. this.questions.forEach((item) => {
  249. if (item.requiredFlag !== "0") {
  250. if (item.value == "") {
  251. item.validation = false;
  252. } else {
  253. item.validation = true;
  254. this.$emit("answer", this.questions);
  255. }
  256. } else {
  257. this.$emit("answer", this.questions);
  258. }
  259. });
  260. this.questionValidation = this.questions.every(function (item) {
  261. if(item.type=="MultilineText"){
  262. item.validation = true;
  263. }
  264. return item.validation == true;
  265. });
  266. this.$emit("bookingDetail_validation", this.questionValidation);
  267. this.questionValidation == true;
  268. },
  269. getValidation(){
  270. this.updateInfo();
  271. this.questionValidation = this.questions.every(function (item) {
  272. return item.validation == true;
  273. });
  274. if(this.questionValidation==false){
  275. this.show = true;
  276. }
  277. return this.questionValidation;
  278. },
  279. },
  280. };
  281. </script>
  282. <style lang="scss" scoped>
  283. .collapse {
  284. @media (min-width: 1366px) {
  285. &::before {
  286. content: "";
  287. display: inline-block;
  288. position: relative;
  289. padding-left: auto;
  290. padding-right: auto;
  291. left: 25px;
  292. top: 0;
  293. background-image: url("~/assets/svg/down-arrow.svg");
  294. background-repeat: no-repeat;
  295. background-position: center;
  296. background-size: 100%;
  297. width: 16px;
  298. height: 10px;
  299. margin-right: 45px;
  300. transform: rotate(-90deg);
  301. transition: all 0.2s linear;
  302. }
  303. &.disabled {
  304. pointer-events: none;
  305. &::before {
  306. background-image: url("~/assets/svg/down-arrow-disabled.svg");
  307. }
  308. }
  309. &.show {
  310. &::before {
  311. transform: rotate(0);
  312. transition: all 0.2s linear;
  313. }
  314. }
  315. }
  316. }
  317. .status-check-icon {
  318. background-image: url("~/assets/svg/status-check.svg");
  319. background-size: 100%;
  320. background-repeat: no-repeat;
  321. background-position: center;
  322. }
  323. .btn-add-icon {
  324. background-image: url("~/assets/svg/plus-blue.svg");
  325. background-repeat: no-repeat;
  326. background-position: left 12px center;
  327. background-size: 16px 16px;
  328. }
  329. .btn-edit-icon {
  330. background-image: url("~/assets/svg/edit-info.svg");
  331. background-repeat: no-repeat;
  332. background-position: center;
  333. background-size: 100%;
  334. }
  335. .bounce-enter-active {
  336. animation: bounce-in 0.3s ease-out;
  337. }
  338. .bounce-leave-active {
  339. animation: bounce-in 0.3s cubic-bezier(1, 0.5, 0.8, 1) reverse;
  340. }
  341. @keyframes bounce-in {
  342. 0% {
  343. opacity: 0;
  344. transform: translateY(-10px);
  345. }
  346. 50% {
  347. opacity: 0.5;
  348. transform: translateY(-5px);
  349. }
  350. 100% {
  351. opacity: 1;
  352. transform: translateY(0);
  353. }
  354. }
  355. </style>