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 / common / SbsFormConstruction / MainContent / parts / MainContentFooter.vue
ameliabooking / v3 / src / views / common / SbsFormConstruction / MainContent / parts Last commit date
MainContentFooter.vue 4 days ago MainContentHeader.vue 2 weeks ago MainPanelHeader.vue 1 month ago MainProfileFooter.vue 1 month ago
MainContentFooter.vue
339 lines
1 <template>
2 <div
3 v-if="!props.loading"
4 class="am-fs__main-footer"
5 :class="[
6 { 'am-fs__main-footer-cp': props.secondButtonShow },
7 { 'am-fs__main-footer-cp-mobile-s': mobileS && props.secondButtonShow },
8 {
9 'am-fs__main-footer__cart': props.addToCartButtonShow || props.backToCartButtonShow,
10 },
11 {
12 'am-fs__main-footer__cart-mobile-s':
13 (props.addToCartButtonShow || props.backToCartButtonShow) && mobileS,
14 },
15 ]"
16 :style="cssVars"
17 >
18 <template v-if="ready">
19 <AmButton
20 v-if="props.secondButtonShow"
21 category="secondary"
22 :type="props.secondaryFooterButtonType"
23 @click="secondButtonClick"
24 >
25 {{ displayLabels('congrats_panel') }}
26 </AmButton>
27 <AmButton
28 v-if="props.addToCartButtonShow"
29 class="am-button-cart"
30 category="secondary"
31 :type="props.addToCartButtonType"
32 @click="addToCartButtonClick"
33 >
34 <span class="am-icon-plus"></span>{{ displayLabels('cart_add_button') }}
35 </AmButton>
36 <AmButton
37 v-if="props.backToCartButtonShow"
38 class="am-button-cart"
39 category="secondary"
40 :type="props.backToCartButtonType"
41 @click="backToCartButtonClick"
42 >
43 {{ props.backToCartLabel }}
44 </AmButton>
45 <div v-if="payPalButtonVisible" :id="'am-paypal-element-' + shortcodeData.counter"></div>
46 <AmButton
47 v-if="!payPalButtonVisible"
48 class="am-button-continue"
49 :class="{ 'square-continue': props.paymentGateway === 'square' }"
50 :disabled="isCongratzStep ? false : footerBtnDisabled"
51 :type="props.primaryFooterButtonType"
52 @click="continueClick"
53 >
54 {{ displayLabels(labelValue) }}
55 </AmButton>
56 </template>
57 <template v-else>
58 <!-- Skeleton -->
59 <div class="am-fs__main-footer-skeleton">
60 <el-skeleton animated>
61 <template #template>
62 <el-skeleton-item />
63 </template>
64 </el-skeleton>
65 </div>
66 <!-- /Skeleton -->
67 </template>
68 </div>
69 </template>
70
71 <script setup>
72 import AmButton from '../../../../_components/button/AmButton.vue'
73 import { computed, inject, ref, watch } from 'vue'
74 import { useColorTransparency } from '../../../../../assets/js/common/colorManipulation'
75
76 let props = defineProps({
77 loading: {
78 type: Boolean,
79 default: false,
80 },
81 ready: {
82 type: Boolean,
83 default: true,
84 },
85 customizedLabels: {
86 type: Object,
87 default: () => {
88 return {}
89 },
90 },
91 primaryFooterButtonType: {
92 type: String,
93 default: 'filled',
94 },
95 secondaryFooterButtonType: {
96 type: String,
97 default: 'filled',
98 },
99 paymentGateway: {
100 type: String,
101 default: '',
102 },
103 payPalButtonShow: {
104 type: Boolean,
105 default: false,
106 },
107 secondButtonShow: {
108 type: Boolean,
109 required: false,
110 },
111 addToCartButtonShow: {
112 type: Boolean,
113 required: false,
114 },
115 addToCartButtonType: {
116 type: String,
117 required: 'text',
118 },
119 backToCartButtonShow: {
120 type: Boolean,
121 required: false,
122 },
123 backToCartButtonType: {
124 type: String,
125 required: 'text',
126 },
127 backToCartLabel: {
128 type: String,
129 default: '',
130 },
131 })
132
133 const emits = defineEmits(['addToCart', 'backToCart'])
134
135 // * Step Functions
136 const { secondButtonClick } = inject('secondButton', {
137 secondButtonClick: () => {},
138 })
139
140 const { footerButtonClick, footerBtnDisabled } = inject('changingStepsFunctions', {
141 footerButtonClick: () => {},
142 })
143
144 function removeFocusFromButton(e) {
145 if (e.target.classList.value.split(' ').indexOf('am-button') === -1) {
146 e.target.parentNode.blur()
147 } else {
148 e.target.blur()
149 }
150 }
151
152 function continueClick(e) {
153 removeFocusFromButton(e)
154 footerButtonClick()
155 }
156
157 // * Labels
158 const amLabels = inject('labels')
159
160 // * Check current step for button text (continue/finish)
161 const sidebarSteps = inject('sidebarSteps')
162 const stepIndex = inject('stepIndex')
163
164 let labelValue = ref('continue')
165
166 // flag for payPal button on congratz step
167 let isCongratzStep = ref(false)
168
169 watch(stepIndex, (value) => {
170 if (value === sidebarSteps.value.length) {
171 labelValue.value = 'finish_appointment'
172 isCongratzStep.value = true
173 } else {
174 labelValue.value = 'continue'
175 }
176 })
177
178 // The PayPal button takes the place of the Continue button, so it may only be
179 // shown on the payment step - otherwise other steps are left with no way forward.
180 let payPalButtonVisible = computed(
181 () => props.payPalButtonShow && props.paymentGateway === 'payPal' && !isCongratzStep.value,
182 )
183
184 const shortcodeData = inject(
185 'shortcodeData',
186 ref({
187 counter: 1000,
188 }),
189 )
190
191 function displayLabels(label) {
192 return Object.keys(props.customizedLabels).length && props.customizedLabels[label]
193 ? props.customizedLabels[label]
194 : amLabels[label]
195 }
196
197 function addToCartButtonClick() {
198 emits('addToCart')
199 }
200
201 function backToCartButtonClick() {
202 emits('backToCart')
203 }
204
205 // * Colors
206 let amColors = inject(
207 'amColors',
208 ref({
209 colorPrimary: '#1246D6',
210 colorSuccess: '#019719',
211 colorError: '#B4190F',
212 colorWarning: '#CCA20C',
213 colorMainBgr: '#FFFFFF',
214 colorMainHeadingText: '#33434C',
215 colorMainText: '#1A2C37',
216 colorSbBgr: '#17295A',
217 colorSbText: '#FFFFFF',
218 colorInpBgr: '#FFFFFF',
219 colorInpBorder: '#D1D5D7',
220 colorInpText: '#1A2C37',
221 colorInpPlaceHolder: '#1A2C37',
222 colorDropBgr: '#FFFFFF',
223 colorDropBorder: '#D1D5D7',
224 colorDropText: '#0E1920',
225 colorBtnPrim: '#265CF2',
226 colorBtnPrimText: '#FFFFFF',
227 colorBtnSec: '#1A2C37',
228 colorBtnSecText: '#FFFFFF',
229 }),
230 )
231 let cssVars = computed(() => {
232 return {
233 '--am-c-main-text-op15': useColorTransparency(amColors.value.colorMainText, 0.15),
234 '--am-c-success-op20': useColorTransparency(amColors.value.colorSuccess, 0.2),
235 }
236 })
237
238 let cWidth = inject('containerWidth', 0)
239 let mobileS = computed(() => cWidth.value < 420)
240 </script>
241
242 <script>
243 export default {
244 name: 'MainContentFooter',
245 }
246 </script>
247
248 <style lang="scss">
249 @mixin main-content-footer {
250 // am -- amelia
251 // fs -- form steps
252 // Amelia Form Steps
253 .am-fs {
254 // Main Container
255 &__main {
256 &-footer {
257 position: absolute;
258 left: 0;
259 bottom: 0;
260 display: flex;
261 align-items: center;
262 justify-content: flex-end;
263 width: 100%;
264 padding: 8px 32px;
265 background-color: transparent;
266 box-shadow: 0 -2px 3px var(--am-c-main-text-op15);
267
268 // cp - customer panel - button on congratulations page
269 &-cp,
270 &-ba {
271 display: flex;
272 justify-content: space-between;
273
274 &-mobile-s {
275 padding: 8px;
276
277 .am-button--secondary {
278 padding: 8px;
279 }
280 }
281 }
282
283 &__cart {
284 justify-content: space-between;
285
286 &-mobile-s {
287 padding: 8px;
288
289 .am-button--secondary {
290 padding: 8px;
291 }
292 }
293 }
294
295 .am-button-cart {
296 .am-icon-plus {
297 display: flex;
298 align-items: center;
299 justify-content: center;
300 font-size: 20px;
301 color: var(--am-c-success);
302 background-color: var(--am-c-success-op20);
303 width: 20px;
304 height: 20px;
305 border-radius: 50%;
306 margin: 0 4px 0 0;
307 &:before {
308 width: 20px;
309 height: 20px;
310 line-height: 20px;
311 }
312 }
313 }
314
315 &-skeleton {
316 .el-skeleton {
317 padding: 0;
318 &__item {
319 width: 109px;
320 height: 40px;
321 }
322 }
323 }
324 }
325 }
326 }
327 }
328
329 // Public
330 .amelia-v2-booking #amelia-container {
331 @include main-content-footer;
332 }
333
334 // Admin
335 #amelia-app-backend-new {
336 @include main-content-footer;
337 }
338 </style>
339