PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
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 / pages / CustomizeEventCalendar.vue
ameliabooking / v3 / src / views / admin / customize / pages Last commit date
CustomizeCatalog.vue 6 days ago CustomizeCustomerPanel.vue 6 days ago CustomizeEmployeePanel.vue 6 days ago CustomizeEventCalendar.vue 6 days ago CustomizeEventList.vue 6 days ago CustomizeStepNew.vue 6 days ago
CustomizeEventCalendar.vue
453 lines
1 <template>
2 <div
3 v-if="isLoaded"
4 id="amelia-container"
5 ref="ameliaContainer"
6 class="am-ecf"
7 :class="{ 'am-ecf-dialog': stepsArray[stepIndex].key !== 'calendar' }"
8 :style="cssVars"
9 >
10 <!-- Events Calendar -->
11 <component
12 :is="stepsArray[stepIndex]"
13 v-if="stepsArray[stepIndex].key === 'calendar'"
14 ></component>
15 <!-- /Events Calendar -->
16
17 <template v-if="stepsArray[stepIndex].key !== 'calendar'">
18 <div v-if="stepIndex > 1" class="am-dialog-el-header">
19 <EventListHeader :ready="true" :loading="false" :customized-labels="globalStepLabels()" />
20 </div>
21 <component
22 :is="stepsArray[stepIndex]"
23 :in-dialog="true"
24 global-class="am-dialog-el__main-container"
25 ></component>
26 <EventListFooter
27 v-if="stepsArray[stepIndex].key !== 'calendar'"
28 :customized-labels="globalStepLabels()"
29 :primary-footer-button-type="
30 isWaiting && stepsArray[stepIndex].name === 'EventInfo' ? waitingBtnType : primBtn
31 "
32 :secondary-footer-button-type="secBtn"
33 :second-button-show="!licence.isLite ? secBtnVisible : false"
34 :is-waiting-list="isWaiting"
35 />
36 </template>
37 </div>
38 </template>
39
40 <script setup>
41 // * import from Vue
42 import {
43 computed,
44 ref,
45 inject,
46 provide,
47 markRaw,
48 onMounted,
49 onBeforeMount,
50 onUnmounted,
51 watchEffect,
52 nextTick,
53 } from 'vue'
54
55 import { useElementSize } from '@vueuse/core'
56
57 // * import composable
58 import { defaultCustomizeSettings } from '../../../../assets/js/common/defaultCustomize'
59 import { useColorTransparency } from '../../../../assets/js/common/colorManipulation'
60 import { useReactiveCustomize } from '../../../../assets/js/admin/useReactiveCustomize.js'
61
62 // * Form Construction
63 import EventListHeader from '../../../common/EventListFormConstruction/Header/Header.vue'
64 import EventListFooter from '../../../common/EventListFormConstruction/Footer/Footer.vue'
65
66 // * Step Components
67 import EventsCalendar from '../steps/Events/EventCalendar/EventsCalendar.vue'
68 import EventInfo from '../steps/Events/common/EventInfo/EventInfo.vue'
69 import EventTickets from '../steps/Events/common/EventTickets/EventTickets.vue'
70 import EventCustomerInfo from '../steps/Events/common/EventCustomerInfo/EventCustomerInfo.vue'
71 import EventPayment from '../steps/Events/common/EventPayment/EventPayment.vue'
72 import EventCongratulations from '../steps/Events/common/Congratulations/EventCongratulations.vue'
73
74 // * Form Component Collection
75 const eventsCalendar = markRaw(EventsCalendar)
76 const eventInfo = markRaw(EventInfo)
77 const eventTickets = markRaw(EventTickets)
78 const eventCustomerInfo = markRaw(EventCustomerInfo)
79 const eventPayment = markRaw(EventPayment)
80 const eventCongratulations = markRaw(EventCongratulations)
81
82 // * Root Settings
83 let amSettings = inject('settings')
84
85 // * Plugin Licence
86 let licence = inject('licence')
87
88 // * Features
89 let features = useReactiveCustomize().features
90 provide('features', features)
91
92 // * Root Urls
93 const baseUrls = inject('baseUrls')
94
95 // Bookable Type
96 const bookableType = ref('event')
97 provide('bookableType', bookableType)
98
99 // * Language key
100 let langKey = useReactiveCustomize().langKey
101 provide('langKey', langKey)
102
103 // * Step index
104 let stepIndex = useReactiveCustomize().stepIndex
105 provide('stepIndex', stepIndex)
106
107 // * Step name
108 let stepName = useReactiveCustomize().stepName
109 provide('stepName', stepName)
110
111 // * Page render key
112 let pageRenderKey = ref('ecf')
113 provide('pageRenderKey', pageRenderKey)
114
115 // * Customize data
116 const { amCustomize } = useReactiveCustomize()
117 provide('customize', amCustomize)
118
119 let isLoaded = ref(false)
120
121 onMounted(() => {
122 window.customizeComponentLoaded = true
123
124 if (typeof window.stylesInjectedV3 === 'function') {
125 if (window.v3.componentToMount === 'CustomizeEventCalendar') {
126 window.stylesInjectedV3 = () => {
127 nextTick().then(() => {
128 isLoaded.value = true
129 })
130 }
131 }
132 }
133 })
134
135 onUnmounted(() => {
136 window.customizeComponentLoaded = false
137 // Reset to no-op function
138 window.stylesInjectedV3 = async function () {}
139 })
140
141 // * is waiting
142 let isWaiting = computed(() => {
143 return features.value.waitingList
144 })
145
146 let amFonts = computed(() => {
147 return amCustomize.value.fonts
148 })
149 provide('amFonts', amFonts)
150
151 let primBtn = computed(() => {
152 if (
153 amCustomize.value[pageRenderKey.value][stepName.value] &&
154 'primBtn' in amCustomize.value[pageRenderKey.value][stepName.value].options
155 ) {
156 return amCustomize.value[pageRenderKey.value][stepName.value].options.primBtn.buttonType
157 }
158 return 'filled'
159 })
160
161 let secBtn = computed(() => {
162 if (
163 amCustomize.value[pageRenderKey.value][stepName.value] &&
164 'secBtn' in amCustomize.value[pageRenderKey.value][stepName.value].options
165 ) {
166 return amCustomize.value[pageRenderKey.value][stepName.value].options.secBtn.buttonType
167 }
168 return 'plain'
169 })
170
171 let secBtnVisible = computed(() => {
172 if (
173 amCustomize.value[pageRenderKey.value][stepName.value] &&
174 'secBtn' in amCustomize.value[pageRenderKey.value][stepName.value].options
175 ) {
176 return amCustomize.value[pageRenderKey.value][stepName.value].options.secBtn.visibility
177 }
178 return true
179 })
180
181 let waitingBtnType = computed(() => {
182 if (
183 amCustomize.value[pageRenderKey.value][stepName.value] &&
184 'waitingBtn' in amCustomize.value[pageRenderKey.value][stepName.value].options
185 ) {
186 return amCustomize.value[pageRenderKey.value][stepName.value].options.waitingBtn.buttonType
187 }
188 return 'filled'
189 })
190
191 let stepsArray = ref([
192 eventsCalendar,
193 eventInfo,
194 eventTickets,
195 eventCustomerInfo,
196 eventPayment,
197 eventCongratulations,
198 ])
199 provide('stepsArray', stepsArray)
200
201 onMounted(() => {
202 if (!features.value.tickets) {
203 stepsArray.value = [
204 eventsCalendar,
205 eventInfo,
206 eventCustomerInfo,
207 eventPayment,
208 eventCongratulations,
209 ]
210 }
211 })
212
213 // * Component reference
214 let ameliaContainer = ref(null)
215
216 // * Plugin wrapper width
217 let { width: containerWidth } = useElementSize(ameliaContainer)
218 provide('containerWidth', containerWidth)
219
220 watchEffect(() => {
221 if (amCustomize.value.fonts.customFontSelected) {
222 activateCustomFontStyles()
223 } else {
224 importDefaultFonts()
225 }
226 })
227
228 function activateCustomFontStyles() {
229 let head = document.head || document.getElementsByTagName('head')[0]
230 if (head.querySelector('#amCustomFont')) {
231 head.querySelector('#amCustomFont').remove()
232 }
233
234 if (head.querySelector('#amDefaultFontImport')) {
235 head.querySelector('#amDefaultFontImport').remove()
236 }
237
238 let css = `@font-face {font-family: '${amCustomize.value.fonts.fontFamily}'; src: url(${amCustomize.value.fonts.fontUrl});}`
239 let style = document.createElement('style')
240 head.appendChild(style)
241 style.setAttribute('type', 'text/css')
242 style.setAttribute('id', 'amCustomFont')
243 style.appendChild(document.createTextNode(css))
244 }
245
246 function importDefaultFonts() {
247 const head = document.head || document.getElementsByTagName('head')[0]
248 if (head.querySelector('#amDefaultFontImport')) {
249 return
250 }
251
252 const base = baseUrls.value.wpAmeliaPluginURL
253 const style = document.createElement('style')
254 style.setAttribute('type', 'text/css')
255 style.setAttribute('id', 'amDefaultFontImport')
256 style.textContent = `@import url("${base}v3/src/assets/scss/common/fonts/font.css");`
257 head.appendChild(style)
258 }
259
260 /**
261 * Lifecycle Hooks
262 */
263 onBeforeMount(() => {
264 window.scrollTo({
265 top: 0,
266 left: 0,
267 behavior: 'smooth',
268 })
269 })
270
271 function globalStepLabels() {
272 let stepLabels = {}
273 let customizedLabels = amCustomize.value[pageRenderKey.value][stepName.value].translations
274 if (customizedLabels && Object.keys(customizedLabels)) {
275 Object.keys(amCustomize.value[pageRenderKey.value][stepName.value].translations).forEach(
276 (label) => {
277 stepLabels[label] =
278 amCustomize.value[pageRenderKey.value][stepName.value].translations[label][langKey.value]
279 },
280 )
281 } else {
282 stepLabels = {}
283 }
284
285 return stepLabels
286 }
287
288 // * Colors
289 // * Customize colors
290 let amColors = computed(() => {
291 const colors = amCustomize.value[pageRenderKey.value]
292 ? amCustomize.value[pageRenderKey.value].colors
293 : defaultCustomizeSettings[pageRenderKey.value].colors
294
295 return { ...colors }
296 })
297
298 provide('amColors', amColors)
299 let cssVars = computed(() => {
300 return {
301 '--am-c-primary': amColors.value.colorPrimary,
302 '--am-c-success': amColors.value.colorSuccess,
303 '--am-c-error': amColors.value.colorError,
304 '--am-c-warning': amColors.value.colorWarning,
305 '--am-c-main-bgr': amColors.value.colorMainBgr,
306 '--am-c-main-heading-text': amColors.value.colorMainHeadingText,
307 '--am-c-main-text': amColors.value.colorMainText,
308 '--am-c-sb-bgr': amColors.value.colorSbBgr,
309 '--am-c-sb-text': amColors.value.colorSbText,
310 '--am-c-inp-bgr': amColors.value.colorInpBgr,
311 '--am-c-inp-border': amColors.value.colorInpBorder,
312 '--am-c-inp-text': amColors.value.colorInpText,
313 '--am-c-inp-placeholder': amColors.value.colorInpPlaceHolder,
314 '--am-c-drop-bgr': amColors.value.colorDropBgr,
315 '--am-c-drop-text': amColors.value.colorDropText,
316 '--am-c-card-bgr': amColors.value.colorCardBgr,
317 '--am-c-card-text': amColors.value.colorCardText,
318 '--am-c-card-border': amColors.value.colorCardBorder,
319 '--am-c-btn-prim': amColors.value.colorBtnPrim,
320 '--am-c-btn-prim-text': amColors.value.colorBtnPrimText,
321 '--am-c-btn-sec': amColors.value.colorBtnSec,
322 '--am-c-btn-sec-text': amColors.value.colorBtnSecText,
323 '--am-c-skeleton-op20': useColorTransparency(amColors.value.colorMainText, 0.2),
324 '--am-c-skeleton-op60': useColorTransparency(amColors.value.colorMainText, 0.6),
325 '--am-font-family': amFonts.value.fontFamily,
326
327 // -mw- max width
328 '--am-mw-main': '792px',
329 '--am-hd-main': stepIndex.value > 0 ? '592px' : '652px',
330 '--am-c-scroll-op30': useColorTransparency(amColors.value.colorPrimary, 0.3),
331 '--am-c-scroll-op10': useColorTransparency(amColors.value.colorPrimary, 0.1),
332
333 '--am-rad-inp': '6px',
334
335 '--am-mb-dialog': '300px',
336 }
337 })
338 </script>
339
340 <script>
341 export default {
342 name: 'EventsCalendarFormWrapper',
343 }
344 </script>
345
346 <style lang="scss">
347 @import '../../../../assets/scss/public/overides/overides';
348 @import '../../../../assets/scss/common/reset/reset';
349 @import '../../../../assets/scss/common/skeleton/skeleton.scss';
350 @import '../../../../assets/scss/common/empty-state/_empty-state-mixin.scss';
351 @import '../../../../assets/scss/common/transitions/_transitions-mixin.scss';
352
353 :root {
354 // Colors
355 // shortcuts
356 // -c- color
357 // -bgr- background
358 // -prim- primary
359 // -sec- secondary
360 // primitive colors
361 --am-c-primary: #{$blue-1000};
362 --am-c-success: #{$green-1000};
363 --am-c-error: #{$red-900};
364 --am-c-warning: #{$yellow-1000};
365 // main container colors - right part of the form
366 --am-c-main-bgr: #{$am-white};
367 --am-c-main-heading-text: #{$shade-800};
368 --am-c-main-text: #{$shade-900};
369 // sidebar container colors - left part of the form
370 --am-c-sb-bgr: #17295a;
371 --am-c-sb-text: #{$am-white};
372 // input global colors - usage input, textarea, checkbox, radio button, select input, adv select input
373 --am-c-inp-bgr: #{$am-white};
374 --am-c-inp-border: #{$shade-250};
375 --am-c-inp-text: #{$shade-900};
376 --am-c-inp-placeholder: #{$shade-500};
377 // dropdown global colors - usage select dropdown, adv select dropdown
378 --am-c-drop-bgr: #{$am-white};
379 --am-c-drop-text: #{$shade-1000};
380 // button global colors
381 --am-c-btn-prim: #{$blue-900};
382 --am-c-btn-prim-text: #{$am-white};
383 --am-c-btn-sec: #{$am-white};
384 --am-c-btn-sec-text: #{$shade-900};
385
386 // Properties
387 // shortcuts
388 // -h- height
389 // -fs- font size
390 // -rad- border radius
391 --am-h-inp: 40px;
392 --am-fs-inp: 15px;
393 --am-rad-inp: 6px;
394 --am-fs-label: 15px;
395 --am-fs-btn: 15px;
396
397 // Font
398 --am-font-family: 'Amelia Roboto', sans-serif;
399 }
400
401 #amelia-app-backend-new #amelia-container {
402 * {
403 font-family: var(--am-font-family);
404 font-style: initial;
405 box-sizing: border-box;
406 word-break: break-word;
407 letter-spacing: normal;
408 }
409
410 // am - amelia
411 // elf - events list form
412 &.am-ecf {
413 margin: 24px auto 0;
414 max-width: calc(100% - 60px);
415 background-color: var(--am-c-main-bgr);
416 padding: 0;
417 border-radius: 12px;
418
419 &.am-ecf-dialog {
420 max-width: 650px;
421 padding: 0;
422 border-radius: 8px;
423 position: relative;
424 }
425 }
426
427 .am-dialog-el {
428 &__main {
429 &-container {
430 height: var(--am-hd-main);
431 display: block;
432 overflow-x: hidden;
433 padding: 16px 24px 0;
434
435 &::-webkit-scrollbar {
436 width: 6px;
437 }
438
439 &::-webkit-scrollbar-thumb {
440 border-radius: 6px;
441 background: var(--am-c-scroll-op30);
442 }
443
444 &::-webkit-scrollbar-track {
445 border-radius: 6px;
446 background: var(--am-c-scroll-op10);
447 }
448 }
449 }
450 }
451 }
452 </style>
453