PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.8
Booking for Appointments and Events Calendar – Amelia v2.4.8
2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / v3 / src / views / admin / customize / steps / parts / AppointmentInfo.vue
ameliabooking / v3 / src / views / admin / customize / steps / parts Last commit date
AddToCalendar.vue 1 month ago AppointmentInfo.vue 3 days ago AppointmentInfoService.vue 1 month ago Calendar.vue 1 month ago CartItemBody.vue 1 month ago CartItemHead.vue 1 month ago CustomerCongratsInfo.vue 1 month ago PackageInfo.vue 1 month ago PackageInfoService.vue 1 month ago PaymentCongratsInfo.vue 1 month ago PaymentPackageInfo.vue 1 month ago
AppointmentInfo.vue
509 lines
1 <template>
2 <div class="am-fs__payments-wrapper" :style="cssVars">
3 <div class="am-fs__payments">
4 <AmCollapse class="am-fs__payments-services">
5 <AmCollapseItem
6 :side="true"
7 @collapse-open="recurringCollapseState = false"
8 @collapse-close="recurringCollapseState = true"
9 >
10 <template #heading>
11 <div class="am-fs__payments-services-info">
12 <span>{{ labelsDisplay('summary_services') }}</span>
13 </div>
14 </template>
15 <template #icon-below>
16 <Transition
17 :duration="{ enter: 500, leave: 500 }"
18 @enter="onCollapseClose"
19 @leave="onCollapseOpen"
20 >
21 <div v-show="recurringCollapseState" class="am-fs__payments-services-sub">
22 <p>{{ labelsDisplay('summary_services_subtotal') }}</p>
23 <p>1000.00$</p>
24 </div>
25 </Transition>
26 </template>
27 <template #default>
28 <div class="am-fs__payments-services-open">
29 <div>
30 <span>
31 Service 1 (125.00$) x 4
32 {{ labelsDisplay('summary_persons') }}</span
33 >
34 <span> 500.00$ </span>
35 </div>
36
37 <div
38 v-if="features.recurringAppointments"
39 style="color: #4d5b63"
40 class="am-fs__payments-services-open-total"
41 >
42 <span
43 >2 {{ labelsDisplay('summary_recurrences') }} x Service 1 (125.00$) x 4
44 {{ labelsDisplay('summary_persons') }}</span
45 >
46 </div>
47
48 <div style="font-weight: 500">
49 <span>{{ labelsDisplay('summary_services_subtotal') }}</span>
50 <span>1000.00$</span>
51 </div>
52 </div>
53 </template>
54 </AmCollapseItem>
55 </AmCollapse>
56
57 <AmCollapse v-if="features.extras" class="am-fs__payments-services">
58 <AmCollapseItem
59 :side="true"
60 @collapse-open="extrasCollapseState = false"
61 @collapse-close="extrasCollapseState = true"
62 >
63 <template #heading>
64 <div class="am-fs__payments-services-info">
65 <span>{{ labelsDisplay('summary_extras') }}</span>
66 </div>
67 </template>
68 <template #icon-below>
69 <Transition
70 :duration="{ enter: 500, leave: 500 }"
71 @enter="onCollapseClose"
72 @leave="onCollapseOpen"
73 >
74 <div v-show="extrasCollapseState" class="am-fs__payments-services-sub">
75 <p>{{ labelsDisplay('summary_extras_subtotal') }}</p>
76 <p>224.00$</p>
77 </div>
78 </Transition>
79 </template>
80 <template #default>
81 <div class="am-fs__payments-services-open">
82 <div v-for="extra in extras" :key="extra.extraId">
83 <span
84 >x {{ extra.times }} {{ extra.name }} ({{ useFormattedPrice(extra.price) }})
85 <span>x 4 {{ labelsDisplay('summary_persons') }}</span>
86 </span>
87 <span>{{ extra.sum }}</span>
88 </div>
89
90 <div class="am-fs__payments-services-open-total">
91 <span
92 >2 {{ labelsDisplay('summary_recurrences') }} x
93 {{ labelsDisplay('summary_extras') }} ( 112.00$ )</span
94 >
95 </div>
96
97 <div class="am-fs__payments-services-open-total">
98 <span>{{ labelsDisplay('summary_extras_subtotal') }}</span>
99 <span>224.00$</span>
100 </div>
101 </div>
102 </template>
103 </AmCollapseItem>
104 </AmCollapse>
105 </div>
106
107 <div class="am-fs__payments-app-info">
108 <div v-if="features.coupons" class="am-fs__payments-app-info-subtotal">
109 <span>{{ labelsDisplay('subtotal') }}:</span>
110 <span>1124.00$</span>
111 </div>
112
113 <el-form v-if="features.coupons" ref="couponFormRef" :rules="rules" :model="couponFormData">
114 <div class="am-fs__coupon">
115 <el-form-item :prop="'coupon'" class="am-fs__coupon-form-item">
116 <template #label>
117 <span>{{ `${labelsDisplay('coupon')}:` }}</span>
118 </template>
119 <AmInput v-model="couponFormData.coupon" size="small" :prefix-icon="IconCoupon" />
120 </el-form-item>
121
122 <AmButton size="small">
123 {{ labelsDisplay('add_coupon_btn') }}
124 </AmButton>
125 </div>
126 </el-form>
127
128 <div
129 v-if="features.coupons"
130 class="am-fs__payments-app-info-discount am-fs__payments-app-info-discount-green"
131 >
132 <span>{{ labelsDisplay('discount_amount_colon') }}:</span>
133 <span>142.40$</span>
134 </div>
135
136 <div class="am-fs__payments-app-info-total">
137 <span>{{ labelsDisplay('total_amount_colon') }}:</span>
138 <span>1081.60$</span>
139 </div>
140
141 <div v-if="props.paymentGateway !== 'onSite' && features.depositPayment">
142 <div class="am-fs__payments-app-info-total">
143 <span>{{ labelsDisplay('paying_now') }}:</span>
144 <span>200.00$</span>
145 </div>
146
147 <div class="am-fs__payments-app-info-total">
148 <span>{{ labelsDisplay('paying_later') }}:</span>
149 <span>881.00$</span>
150 </div>
151 </div>
152 </div>
153 </div>
154 </template>
155
156 <script setup>
157 import AmInput from '../../../../_components/input/AmInput.vue'
158 import AmButton from '../../../../_components/button/AmButton.vue'
159 import AmCollapse from '../../../../_components/collapse/AmCollapse'
160 import AmCollapseItem from '../../../../_components/collapse/AmCollapseItem'
161 import IconCoupon from '../../../../_components/icons/IconCoupon.vue'
162 import { computed, inject, ref } from 'vue'
163 import { useColorTransparency } from '../../../../../assets/js/common/colorManipulation'
164 import { useFormattedPrice } from '../../../../../assets/js/common/formatting'
165 import { useReactiveCustomize } from '../../../../../assets/js/admin/useReactiveCustomize.js'
166
167 // * Features
168 let features = inject('features')
169
170 let props = defineProps({
171 bookableType: {
172 type: String,
173 default: 'appointment',
174 },
175 paymentGateway: {
176 type: String,
177 default: 'onSite',
178 },
179 })
180
181 let langKey = inject('langKey')
182 let amLabels = inject('labels')
183
184 let pageRenderKey = inject('pageRenderKey')
185 const { amCustomize } = useReactiveCustomize()
186
187 let couponFormRef = ref(null)
188
189 let couponFormData = ref({
190 coupon: '',
191 })
192
193 // * Form validation rules
194 let rules = computed(() => {
195 return {
196 coupon: [
197 {
198 required: amCustomize.value[pageRenderKey.value].paymentStep.options.coupon.required,
199 trigger: ['blur', 'change'],
200 },
201 ],
202 }
203 })
204
205 let extras = [
206 {
207 name: 'Extra 1',
208 price: '3.00$',
209 times: '1',
210 sum: '12.00$',
211 },
212 {
213 name: 'Extra 2',
214 price: '5.00$',
215 times: '5',
216 sum: '100.00$',
217 },
218 ]
219
220 // * Label computed function
221 function labelsDisplay(label) {
222 let computedLabel = computed(() => {
223 return amCustomize.value[pageRenderKey.value].paymentStep.translations &&
224 amCustomize.value[pageRenderKey.value].paymentStep.translations[label] &&
225 amCustomize.value[pageRenderKey.value].paymentStep.translations[label][langKey.value]
226 ? amCustomize.value[pageRenderKey.value].paymentStep.translations[label][langKey.value]
227 : amLabels[label]
228 })
229
230 return computedLabel.value
231 }
232
233 // * Collapse visualisation
234 let recurringCollapseState = ref(true)
235 let extrasCollapseState = ref(true)
236
237 function onCollapseClose(el) {
238 el.style.opacity = 0
239 setTimeout(() => {
240 el.style.opacity = 1
241 el.style.height = 'var(--am-h-services-sub)'
242 }, 200)
243 }
244
245 function onCollapseOpen(el) {
246 el.style.opacity = 0
247 el.style.setProperty('--am-h-services-sub', `${el.offsetHeight}px`)
248 setTimeout(() => {
249 el.style.height = '0px'
250 }, 100)
251 }
252
253 // * Colors
254 let amColors = inject('amColors')
255 let cssVars = computed(() => {
256 return {
257 '--am-c-pay-text': amColors.value.colorMainText,
258 '--am-c-pay-text-op70': useColorTransparency(amColors.value.colorMainText, 0.7),
259 '--am-c-pay-text-op60': useColorTransparency(amColors.value.colorMainText, 0.6),
260 '--am-c-pay-text-op30': useColorTransparency(amColors.value.colorMainText, 0.3),
261 '--am-c-pay-success': amColors.value.colorSuccess,
262 '--am-c-pay-primary': amColors.value.colorPrimary,
263 }
264 })
265 </script>
266
267 <script>
268 export default {
269 name: 'AppointmentInfo',
270 }
271 </script>
272
273 <style lang="scss">
274 #amelia-app-backend-new {
275 #amelia-container {
276 .am-fs__payments {
277 &-app-info {
278 margin: 0;
279
280 &-subtotal {
281 display: flex;
282 justify-content: space-between;
283 border-bottom: 1px dashed var(--am-c-pay-text-op30);
284 padding: 0 0 16px;
285 margin: 16px 0 0;
286
287 span {
288 font-size: 14px;
289 font-weight: 500;
290 line-height: 1.42857;
291 color: var(--am-c-pay-text);
292 }
293 }
294
295 &-discount {
296 display: flex;
297 justify-content: space-between;
298 font-size: 13px;
299 font-weight: 400;
300 line-height: 1.3846;
301 color: var(--am-c-pay-text);
302 padding: 16px 0 0;
303
304 &-green {
305 color: var(--am-c-pay-success);
306 }
307 }
308 &-total {
309 display: flex;
310 justify-content: space-between;
311 font-size: 15px;
312 font-weight: 500;
313 line-height: 1.33333;
314 color: var(--am-c-pay-text);
315 padding: 8px 0 0;
316
317 & > span:nth-child(2) {
318 color: var(--am-c-pay-primary);
319 }
320 }
321 }
322
323 &-service {
324 border: 1px solid var(--am-c-pay-text-op30);
325 border-radius: 8px;
326 padding: 12px;
327 box-sizing: border-box;
328 }
329
330 &-services {
331 .am-collapse-item__heading {
332 flex-wrap: wrap;
333 width: 100%;
334 padding: 12px;
335 transition-delay: 0.5s;
336
337 &-side {
338 transition-delay: 0s;
339 }
340
341 .am-collapse-item__trigger {
342 padding: 0;
343 }
344 }
345 .am-collapse-item__content {
346 & > * {
347 padding: 12px;
348 }
349 }
350
351 &-info {
352 span {
353 font-size: 12px;
354 line-height: 1.33333;
355 font-weight: 500;
356 color: var(--am-c-pay-text-op60);
357 }
358 }
359
360 &-open {
361 width: 100%;
362
363 &-total {
364 border-top: 1px dashed var(--am-c-pay-text-op30);
365 padding: 12px 0 0;
366 margin: 12px 0 4px;
367
368 & > span {
369 color: var(--am-c-pay-text-op70);
370 }
371
372 &:last-child {
373 font-weight: 500;
374 }
375 }
376
377 & > div {
378 display: flex;
379 justify-content: space-between;
380 font-size: 13px;
381 font-weight: 400;
382 line-height: 1.384615;
383 color: var(--am-c-pay-text);
384 }
385 }
386
387 &-sub {
388 width: 100%;
389 display: flex;
390 justify-content: space-between;
391 transition: all ease-in-out 0.3s;
392
393 p {
394 font-size: 13px;
395 font-weight: 500;
396 line-height: 1.384615;
397 color: var(--am-c-pay-text);
398 margin: 0;
399 padding: 0;
400 }
401 }
402
403 & > div:first-child {
404 margin-top: 0;
405 }
406 }
407 }
408
409 .am-fs__coupon {
410 width: 100%;
411 display: flex;
412 padding: 0;
413 margin: 16px 0 0;
414 font-size: 14px;
415 font-weight: 400;
416 line-height: 1.42857;
417 gap: 4px;
418 color: var(--am-c-ps-text);
419 white-space: nowrap;
420 align-items: center;
421
422 .am-icon-info-reverse,
423 .am-icon-check {
424 font-size: 18px;
425 }
426
427 .am-icon-info-reverse {
428 /* $red-900 */
429 color: var(--am-c-error);
430 }
431
432 .am-icon-check {
433 /* $green-900 */
434 position: absolute;
435 width: 20px;
436 height: 20px;
437 background-color: var(--am-c-success);
438 border-radius: 50%;
439 color: var(--am-c-inp-bgr);
440
441 &:before {
442 position: absolute;
443 top: 50%;
444 left: 50%;
445 transform: translate(-50%, -50%);
446 }
447 }
448
449 & > span {
450 margin-right: 3px;
451 }
452
453 &-invalid {
454 input {
455 border: 1.5px solid var(--am-c-error);
456 }
457 }
458
459 .el-icon {
460 height: 100%;
461 }
462 }
463
464 &.am-fs__wrapper {
465 .am-fs__coupon {
466 .el-form-item {
467 display: flex;
468 gap: 5px;
469 align-items: center;
470 margin-bottom: 0;
471 width: 100%;
472
473 &__label {
474 max-width: 50%;
475 flex-wrap: wrap;
476 height: auto;
477
478 span {
479 white-space: normal;
480 word-break: break-word;
481 }
482 }
483
484 .el-form-item__error {
485 display: none;
486 }
487 }
488 }
489 }
490
491 .am-fs__coupon-discount {
492 display: flex;
493 justify-content: space-between;
494 font-size: 14px;
495 font-weight: 400;
496 line-height: 1.42857;
497 color: var(--am-c-ps-text);
498 margin-bottom: 12px;
499
500 & span:nth-child(2) {
501 font-weight: 500;
502 /* $green-900 */
503 color: var(--am-c-success);
504 }
505 }
506 }
507 }
508 </style>
509