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 / steps / Events / common / EventCustomerInfo / EventCustomerInfo.vue
ameliabooking / v3 / src / views / admin / customize / steps / Events / common / EventCustomerInfo Last commit date
parts 5 days ago EventCustomerInfo.vue 5 days ago
EventCustomerInfo.vue
417 lines
1 <template>
2 <div ref="infoFormWrapperRef" class="am-elfci" :class="props.globalClass">
3 <!-- Social Buttons -->
4 <div v-if="features.googleSocialLogin || features.facebookSocialLogin">
5 <div class="am-elfci__social-wrapper">
6 <div class="am-elfci__social-wrapper__label">
7 {{ labelsDisplay('auto_fill_your_details') }}
8 </div>
9 <div class="am-elfci__social-wrapper__social-buttons">
10 <img
11 v-if="features.googleSocialLogin"
12 :src="baseUrls.wpAmeliaPluginURL + '/v3/src/assets/img/icons/google.svg'"
13 height="32"
14 />
15 <img
16 v-if="features.facebookSocialLogin"
17 :src="baseUrls.wpAmeliaPluginURL + '/v3/src/assets/img/icons/facebook.svg'"
18 height="32"
19 />
20 </div>
21 </div>
22
23 <!-- Social Divider -->
24 <div class="am-elfci__social-divider">
25 <span class="par-sm">{{ labelsDisplay('or_enter_details_below') }}</span>
26 </div>
27 <!-- /Social Divider -->
28 </div>
29 <!-- /Social Buttons -->
30
31 <el-form
32 ref="infoFormRef"
33 :model="infoFormData"
34 :rules="infoFormRules"
35 label-position="top"
36 class="am-elfci__form"
37 :class="responsiveClass"
38 >
39 <template v-for="item in customizeOrder" :key="item.id">
40 <component
41 :is="infoFormConstruction[item.id].template"
42 v-if="infoFormConstruction[item.id].visibility"
43 ref="customerCollectorRef"
44 v-model="infoFormData[item.id]"
45 v-model:countryPhoneIso="infoFormConstruction[item.id].countryPhoneIso"
46 v-bind="infoFormConstruction[item.id].props"
47 v-on="
48 'handlers' in infoFormConstruction[item.id]
49 ? infoFormConstruction[item.id].handlers
50 : {}
51 "
52 ></component>
53 </template>
54
55 <el-form-item
56 v-if="
57 amSettings.featuresIntegrations.mailchimp.enabled &&
58 amSettings.mailchimp.subscribeFieldVisible &&
59 amCustomize[pageRenderKey].customerInfo.options.email.visibility
60 "
61 class="am-elfci__item am-subscribe"
62 >
63 <AmCheckbox
64 :value="amSettings.mailchimp.checkedByDefault"
65 :label="labelsDisplay('subscribe_to_mailing_list')"
66 >
67 </AmCheckbox>
68 </el-form-item>
69 </el-form>
70 </div>
71 </template>
72
73 <script setup>
74 import AmCheckbox from '../../../../../../_components/checkbox/AmCheckbox.vue'
75
76 // * Import from Vue
77 import { ref, computed, inject } from 'vue'
78
79 // * Form Fields Templates
80 import { formFieldsTemplates } from '../../../../../../../assets/js/common/formFieldsTemplates'
81
82 // * Composables
83 import { useResponsiveClass } from '../../../../../../../assets/js/common/responsive'
84 import { useReactiveCustomize } from '../../../../../../../assets/js/admin/useReactiveCustomize.js'
85 import { getInternationalPhoneValue } from '../../../../../../../assets/js/common/phone'
86
87 // * Components
88 let props = defineProps({
89 globalClass: {
90 type: String,
91 default: '',
92 },
93 inDialog: {
94 type: Boolean,
95 default: false,
96 },
97 })
98
99 // * Features
100 let features = inject('features')
101
102 // * Settings
103 // * Root Settings
104 const amSettings = inject('settings')
105
106 // * Form string recognition
107 let pageRenderKey = inject('pageRenderKey')
108
109 // * Customize
110 const { amCustomize } = useReactiveCustomize()
111
112 // * Plugin Licence
113 let licence = inject('licence')
114
115 let baseUrls = inject('baseUrls')
116
117 // * Order
118 let customizeOrder = computed(() => {
119 return amCustomize.value[pageRenderKey.value].customerInfo.order
120 })
121
122 // * Options
123 let customizeOptions = computed(() => {
124 return amCustomize.value[pageRenderKey.value].customerInfo.options
125 })
126
127 // * Labels
128 let langKey = inject('langKey')
129 let amLabels = inject('labels')
130
131 function labelsDisplay(label) {
132 let computedLabel = computed(() => {
133 let translations = amCustomize.value[pageRenderKey.value].customerInfo.translations
134 return translations && translations[label] && translations[label][langKey.value]
135 ? translations[label][langKey.value]
136 : amLabels[label]
137 })
138
139 return computedLabel.value
140 }
141
142 // * Form data
143 let infoFormData = ref({
144 firstName: '',
145 lastName: '',
146 email: '',
147 phone: '',
148 })
149
150 // * Form construction
151 let infoFormConstruction = ref({
152 firstName: {
153 template: formFieldsTemplates.text,
154 visibility: true,
155 props: {
156 itemName: 'firstName',
157 label: computed(() => labelsDisplay('first_name_colon')),
158 placeholder: computed(() => labelsDisplay('enter_first_name')),
159 class: 'am-elfci__item',
160 },
161 },
162 lastName: {
163 template: formFieldsTemplates.text,
164 visibility: computed(() => customizeOptions.value.lastName.visibility),
165 props: {
166 itemName: 'lastName',
167 label: computed(() => labelsDisplay('last_name_colon')),
168 placeholder: computed(() => labelsDisplay('enter_last_name')),
169 class: 'am-elfci__item',
170 },
171 },
172 email: {
173 template: formFieldsTemplates.text,
174 visibility: computed(() => customizeOptions.value.email.visibility),
175 props: {
176 itemName: 'email',
177 label: computed(() => labelsDisplay('email_colon')),
178 placeholder: computed(() => labelsDisplay('enter_email')),
179 class: 'am-elfci__item',
180 },
181 },
182 phone: {
183 countryPhoneIso: '',
184 template: formFieldsTemplates.phone,
185 visibility: computed(() => customizeOptions.value.phone.visibility),
186 props: {
187 itemName: 'phone',
188 label: computed(() => labelsDisplay('phone_colon')),
189 placeholder: computed(() => labelsDisplay('enter_phone')),
190 defaultCode:
191 amSettings.general.phoneDefaultCountryCode === 'auto'
192 ? ''
193 : amSettings.general.phoneDefaultCountryCode.toLowerCase(),
194 phoneError: false,
195 whatsAppLabel: computed(() => labelsDisplay('whatsapp_opt_in_text')),
196 isWhatsApp: amSettings.notifications.whatsAppEnabled,
197 class: 'am-elfci__item',
198 },
199 handlers: {
200 handlePhoneData: (phoneData) => {
201 infoFormData.value.phone = getInternationalPhoneValue(
202 phoneData?.phoneNumber ?? phoneData?.e164,
203 phoneData,
204 phoneData?.countryCode
205 )
206 },
207 },
208 },
209 })
210
211 // * Form validation rules
212 let infoFormRules = computed(() => {
213 return {
214 firstName: [
215 {
216 required: true,
217 message: labelsDisplay('enter_first_name_warning'),
218 trigger: ['blur', 'submit'],
219 },
220 ],
221 lastName: [
222 {
223 required: customizeOptions.value.lastName.required,
224 message: labelsDisplay('enter_last_name_warning'),
225 trigger: ['blur', 'submit'],
226 },
227 ],
228 email: [
229 {
230 required: customizeOptions.value.email.required,
231 type: 'email',
232 message: labelsDisplay('enter_valid_email_warning'),
233 trigger: ['blur', 'submit'],
234 },
235 ],
236 phone: [
237 {
238 required: customizeOptions.value.phone.required,
239 message: labelsDisplay('enter_phone_warning'),
240 trigger: ['blur', 'submit'],
241 },
242 ],
243 }
244 })
245
246 // * Responsive - Container Width
247 let cWidth = inject('containerWidth')
248
249 let componentWidth = computed(() => {
250 return cWidth.value
251 })
252
253 let responsiveClass = computed(() => useResponsiveClass(componentWidth.value))
254 </script>
255
256 <script>
257 export default {
258 name: 'EventCustomerInfo',
259 key: 'customerInfo',
260 label: 'event_customer_info',
261 }
262 </script>
263
264 <style lang="scss">
265 #amelia-app-backend-new #amelia-container {
266 // elfci - event list form customer info
267 .am-elfci {
268 &__social-wrapper {
269 display: flex;
270 align-items: center;
271 flex-direction: column;
272 width: 100%;
273 margin: 8px 0 24px;
274 gap: 24px;
275
276 &__label {
277 font-weight: 500;
278 font-size: 15px;
279 color: var(--black, #04080b);
280 }
281
282 &__social-buttons {
283 display: flex;
284 align-items: center;
285 justify-content: center;
286 width: 100%;
287 gap: 24px;
288
289 img {
290 border: 1px solid #d1d5d7;
291 padding: 8px;
292 border-radius: 4px;
293 height: 40px;
294 width: 40px;
295 }
296 }
297 }
298
299 &__social-divider {
300 align-items: center;
301 display: flex;
302 margin-bottom: 24px;
303
304 // Before & After
305 &:before,
306 &:after {
307 background: var(--shade-250, #d1d5d7);
308 content: '';
309 height: 1px;
310 width: 100%;
311 }
312
313 span {
314 flex: none;
315 font-size: 15px;
316 font-style: normal;
317 font-weight: 400;
318 line-height: 24px;
319 color: var(--shade-500, #808a90);
320 margin-left: 8px;
321 margin-right: 8px;
322 }
323 }
324 &__main {
325 &-content.am-elf__event-customer-info {
326 padding-top: 20px;
327 }
328
329 &-inner {
330 overflow: hidden;
331 }
332 }
333
334 &__form {
335 display: flex;
336 flex-wrap: wrap;
337 justify-content: space-between;
338
339 &.am-rw-500 {
340 .am-elfci__item {
341 width: 100%;
342 }
343 }
344
345 & > * {
346 $count: 100;
347 @for $i from 0 through $count {
348 &:nth-child(#{$i + 1}) {
349 animation: 600ms cubic-bezier(0.45, 1, 0.4, 1.2) #{$i * 100}ms am-animation-slide-up;
350 animation-fill-mode: both;
351 }
352 }
353 }
354
355 .am-elfci__item {
356 width: calc(50% - 12px);
357
358 &.am-subscribe {
359 width: 100%;
360 .el-checkbox {
361 &__input {
362 height: 32px;
363 line-height: 32px;
364 align-items: center;
365 }
366
367 &__label {
368 line-height: 32px;
369 padding: 0;
370 align-items: center;
371 }
372 }
373 }
374
375 .el-form-item {
376 &__label {
377 display: inline-block;
378 color: var(--am-c-main-text);
379 font-family: var(--am-font-family);
380 font-weight: 500;
381 line-height: unset;
382 margin-bottom: 4px;
383
384 &:before {
385 color: var(--am-c-error);
386 }
387 }
388
389 &__error {
390 line-height: 1;
391 color: var(--am-c-error);
392 }
393 }
394 }
395
396 &-mobile {
397 gap: 12px 6px;
398 .el-form-item {
399 width: 100%;
400 }
401 &-s {
402 gap: 0px;
403 }
404 }
405
406 &__label {
407 display: inline-block;
408 color: var(--am-c-main-text);
409 font-family: var(--am-font-family);
410 font-weight: 500;
411 margin-bottom: 4px;
412 }
413 }
414 }
415 }
416 </style>
417