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 / CustomizeCatalog.vue
ameliabooking / v3 / src / views / admin / customize / pages Last commit date
CustomizeCatalog.vue 5 days ago CustomizeCustomerPanel.vue 5 days ago CustomizeEmployeePanel.vue 5 days ago CustomizeEventCalendar.vue 5 days ago CustomizeEventList.vue 5 days ago CustomizeStepNew.vue 5 days ago
CustomizeCatalog.vue
408 lines
1 <template>
2 <div
3 v-if="isLoaded"
4 id="amelia-container"
5 ref="ameliaContainer"
6 class="am-fc__wrapper"
7 :style="cssVars"
8 >
9 <template v-if="stepsArray.length">
10 <component :is="stepsArray[stepIndex]"></component>
11 </template>
12 </div>
13 </template>
14
15 <script setup>
16 // * Import from Vue
17 import {
18 ref,
19 provide,
20 inject,
21 markRaw,
22 computed,
23 onBeforeMount,
24 onMounted,
25 watchEffect,
26 onUnmounted,
27 nextTick,
28 } from 'vue'
29
30 import { useElementSize } from '@vueuse/core'
31
32 // * Import composables
33 import { defaultCustomizeSettings } from '../../../../assets/js/common/defaultCustomize.js'
34 import { useReactiveCustomize } from '../../../../assets/js/admin/useReactiveCustomize.js'
35
36 // * Step components
37 import CategoriesList from '../steps/CategoriesList.vue'
38 import CategoryItemsList from '../steps/CategoryItemsList.vue'
39 import CategoryService from '../steps/CategoryService.vue'
40 import CategoryPackage from '../steps/CategoryPackage.vue'
41
42 const categoriesList = markRaw(CategoriesList)
43 const categoryItemsList = markRaw(CategoryItemsList)
44 const categoryService = markRaw(CategoryService)
45 const categoryPackage = markRaw(CategoryPackage)
46
47 // * Base Urls
48 const baseUrls = inject('baseUrls')
49
50 // * Features integrations
51 let features = useReactiveCustomize().features
52 provide('features', features)
53
54 let langKey = useReactiveCustomize().langKey
55 provide('langKey', langKey)
56
57 // * Step index
58 let stepIndex = useReactiveCustomize().stepIndex
59 provide('stepIndex', stepIndex)
60
61 // * Page render key
62 let pageRenderKey = ref('cbf')
63 provide('pageRenderKey', pageRenderKey)
64
65 // * Step name
66 let stepName = useReactiveCustomize().stepName
67 provide('stepName', stepName)
68
69 // * Customize data
70 const { amCustomize } = useReactiveCustomize()
71 provide('customize', amCustomize)
72
73 // * Fonts
74 let amFonts = computed(() => {
75 return amCustomize.value.fonts
76 })
77 provide('amFonts', amFonts)
78
79 let stepsArray = ref([categoriesList, categoryItemsList, categoryService, categoryPackage])
80
81 // * Component reference
82 let ameliaContainer = ref(null)
83
84 // * Plugin wrapper width
85 let { width: containerWidth } = useElementSize(ameliaContainer)
86 provide('containerWidth', containerWidth)
87
88 let isLoaded = ref(false)
89
90 onMounted(() => {
91 window.customizeComponentLoaded = true
92
93 if (typeof window.stylesInjectedV3 === 'function') {
94 if (window.v3.componentToMount === 'CustomizeCatalog') {
95 window.stylesInjectedV3 = () => {
96 nextTick().then(() => {
97 isLoaded.value = true
98 })
99 }
100 }
101 }
102 })
103
104 // Clean up on unmount to prevent stale callbacks
105 onUnmounted(() => {
106 window.customizeComponentLoaded = false
107 // Reset to no-op function
108 window.stylesInjectedV3 = async function () {}
109 })
110
111 watchEffect(() => {
112 if (amCustomize.value.fonts.customFontSelected) {
113 activateCustomFontStyles()
114 } else {
115 importDefaultFonts()
116 }
117 })
118
119 function activateCustomFontStyles() {
120 let head = document.head || document.getElementsByTagName('head')[0]
121 if (head.querySelector('#amCustomFont')) {
122 head.querySelector('#amCustomFont').remove()
123 }
124
125 if (head.querySelector('#amDefaultFontImport')) {
126 head.querySelector('#amDefaultFontImport').remove()
127 }
128
129 let css = `@font-face {font-family: '${amCustomize.value.fonts.fontFamily}'; src: url(${amCustomize.value.fonts.fontUrl});}`
130 let style = document.createElement('style')
131 head.appendChild(style)
132 style.setAttribute('type', 'text/css')
133 style.setAttribute('id', 'amCustomFont')
134 style.appendChild(document.createTextNode(css))
135 }
136
137 function importDefaultFonts() {
138 const head = document.head || document.getElementsByTagName('head')[0]
139 if (head.querySelector('#amDefaultFontImport')) {
140 return
141 }
142
143 const base = baseUrls.value.wpAmeliaPluginURL
144 const style = document.createElement('style')
145 style.setAttribute('type', 'text/css')
146 style.setAttribute('id', 'amDefaultFontImport')
147 style.textContent = `@import url("${base}v3/src/assets/scss/common/fonts/font.css");`
148 head.appendChild(style)
149 }
150
151 /**
152 * Lifecycle Hooks
153 */
154 onBeforeMount(() => {
155 window.scrollTo({
156 top: 0,
157 left: 0,
158 behavior: 'smooth',
159 })
160 })
161
162 // * Colors
163 // * Customize colors
164 let amColors = computed(() => {
165 const colors = amCustomize.value[pageRenderKey.value]
166 ? amCustomize.value[pageRenderKey.value].colors
167 : defaultCustomizeSettings[pageRenderKey.value].colors
168
169 return { ...colors }
170 })
171
172 provide('amColors', amColors)
173
174 let cssVars = computed(() => {
175 return {
176 '--am-c-primary': amColors.value.colorPrimary,
177 '--am-c-success': amColors.value.colorSuccess,
178 '--am-c-error': amColors.value.colorError,
179 '--am-c-warning': amColors.value.colorWarning,
180 // input global colors - usage input, textarea, checkbox, radio button, select input, adv select input
181 '--am-c-inp-bgr': amColors.value.colorInpBgr,
182 '--am-c-inp-border': amColors.value.colorInpBorder,
183 '--am-c-inp-text': amColors.value.colorInpText,
184 '--am-c-inp-placeholder': amColors.value.colorInpPlaceHolder,
185 // dropdown global colors - usage select dropdown, adv select dropdown
186 '--am-c-drop-bgr': amColors.value.colorDropBgr,
187 '--am-c-drop-text': amColors.value.colorDropText,
188 // sidebar container colors - left part of the form
189 '--am-c-sb-bgr': amColors.value.colorSbBgr,
190 '--am-c-sb-text': amColors.value.colorSbText,
191 // main container colors - right part of the form
192 '--am-c-main-bgr': amColors.value.colorMainBgr,
193 '--am-c-main-heading-text': amColors.value.colorMainHeadingText,
194 '--am-c-main-text': amColors.value.colorMainText,
195 // input global colors - usage input, textarea, checkbox, radio button, select input, adv select input
196 '--am-c-card-bgr': amColors.value.colorCardBgr,
197 '--am-c-card-border': amColors.value.colorCardBorder,
198 '--am-c-card-text': amColors.value.colorCardText,
199 // button global colors
200 '--am-c-btn-prim': amColors.value.colorBtnPrim,
201 '--am-c-btn-prim-text': amColors.value.colorBtnPrimText,
202 '--am-c-btn-sec': amColors.value.colorBtnSec,
203 '--am-c-btn-sec-text': amColors.value.colorBtnSecText,
204 '--am-font-family': amCustomize.value.fonts.fontFamily,
205 // css properties
206 // -mw- max width
207 // -brad- border-radius
208 '--am-mw-main': amCustomize.value.sbsNew.sidebar.options.self.visibility ? '760px' : '520px',
209 '--am-brad-main': amCustomize.value.sbsNew.sidebar.options.self.visibility
210 ? '0 0.5rem 0.5rem 0'
211 : '0.5rem',
212 }
213 })
214 </script>
215
216 <script>
217 export default {
218 name: 'CustomizeCatalog',
219 }
220 </script>
221
222 <style lang="scss">
223 @import '../../../../../src/assets/scss/common/reset/reset';
224
225 :root {
226 // Colors
227 // shortcuts
228 // -c- color
229 // -bgr- background
230 // -prim- primary
231 // -sec- secondary
232 // primitive colors
233 --am-c-primary: #{$blue-1000};
234 --am-c-success: #{$green-1000};
235 --am-c-error: #{$red-900};
236 --am-c-warning: #{$yellow-1000};
237 // main container colors - right part of the form
238 --am-c-main-bgr: #{$blue-900};
239 --am-c-main-heading-text: #{$shade-800};
240 --am-c-main-text: #{$shade-900};
241 // sidebar container colors - left part of the form
242 --am-c-sb-bgr: #17295a;
243 --am-c-sb-text: #{$am-white};
244 // input global colors - usage input, textarea, checkbox, radio button, select input, adv select input
245 --am-c-inp-bgr: #{$blue-900};
246 --am-c-inp-border: #{$shade-250};
247 --am-c-inp-text: #{$shade-900};
248 --am-c-inp-placeholder: #{$shade-500};
249 --am-c-checkbox-border: #{$shade-300};
250 --am-c-checkbox-border-disabled: #{$blue-600};
251 --am-c-checkbox-border-focused: #{$blue-700};
252 --am-c-checkbox-label-disabled: #{$shade-600};
253 // dropdown global colors - usage select dropdown, adv select dropdown
254 --am-c-drop-bgr: #{$am-white};
255 --am-c-drop-text: #{$shade-1000};
256 // button global colors
257 --am-c-btn-prim: #{$blue-900};
258 --am-c-btn-prim-text: #{$am-white};
259 --am-c-btn-sec: #{$am-white};
260 --am-c-btn-sec-text: #{$shade-900};
261
262 // Properties
263 // shortcuts
264 // -h- height
265 // -fs- font size
266 // -rad- border radius
267 --am-h-inp: 40px;
268 --am-fs-inp: 15px;
269 --am-rad-inp: 6px;
270 --am-fs-label: 15px;
271 --am-fs-btn: 15px;
272
273 // Font
274 --am-font-family: 'Amelia Roboto', sans-serif;
275 }
276
277 //@import url('https://fonts.googleapis.com/css2?family=Rampart+One&display=swap');
278 // am -- amelia
279 // fc -- form catalog
280 #amelia-app-backend-new {
281 #amelia-container {
282 background-color: transparent;
283
284 * {
285 font-family: var(--am-font-family);
286 font-style: initial;
287 box-sizing: border-box;
288 word-break: break-word;
289 letter-spacing: normal;
290 }
291
292 &.am-fc {
293 // Container Wrapper
294 &__wrapper {
295 display: flex;
296 justify-content: center;
297 max-width: calc(100% - 48px);
298 width: 100%;
299 height: auto;
300 margin: 48px 24px;
301 padding: 0;
302 border-radius: 8px;
303 box-shadow: none;
304
305 .el-form {
306 &-item {
307 display: block;
308 font-family: var(--am-font-family);
309 font-size: var(--am-fs-label);
310 margin-bottom: 24px;
311
312 &__label {
313 flex: 0 0 auto;
314 text-align: left;
315 font-size: var(--am-fs-label);
316 line-height: 1.3;
317 color: var(--am-c-main-text);
318 box-sizing: border-box;
319 margin: 0;
320
321 &:before {
322 color: var(--am-c-error);
323 }
324 }
325
326 &__content {
327 display: flex;
328 flex-wrap: wrap;
329 align-items: center;
330 flex: 1;
331 position: relative;
332 font-size: var(--am-fs-inp);
333 min-width: 0;
334 color: var(--am-c-main-text);
335 }
336
337 &__error {
338 font-size: 12px;
339 color: var(--am-c-error);
340 padding-top: 4px;
341 }
342 }
343 }
344
345 * {
346 font-family: var(--am-font-family);
347 box-sizing: border-box;
348 }
349
350 .am-empty {
351 --am-c-e-bgr: var(--am-c-main-bgr);
352 --am-c-e-text: var(--am-c-main-text);
353 max-width: 760px;
354 width: 100%;
355 height: 460px;
356 text-align: center;
357 background-color: var(--am-c-e-bgr);
358 padding: 56px;
359 margin: 100px auto;
360 box-shadow: 0 30px 40px rgba(0, 0, 0, 0.12);
361
362 * {
363 font-family: var(--am-font-family);
364 box-sizing: border-box;
365 color: var(--am-c-e-text);
366 }
367
368 &__heading {
369 display: block;
370 text-align: center;
371 font-size: 24px;
372 line-height: 1.5;
373 font-weight: bold;
374 }
375
376 &__subheading {
377 display: block;
378 text-align: center;
379 font-size: 16px;
380 line-height: 1.5;
381 font-weight: 400;
382 }
383
384 p,
385 span {
386 padding: 0;
387 }
388
389 p {
390 font-size: 14px;
391 margin: 8px 0;
392 }
393
394 a {
395 font-size: 14px;
396 color: var(--am-c-primary);
397 }
398 }
399 }
400 }
401 }
402
403 .am-dialog-cs {
404 z-index: 10000 !important;
405 }
406 }
407 </style>
408