PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.6
Booking for Appointments and Events Calendar – Amelia v2.4.6
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 / Cabinet / common / Authentication / SignIn.vue
ameliabooking / v3 / src / views / admin / customize / steps / Cabinet / common / Authentication Last commit date
SendAccessLink.vue 1 month ago SendAccessLinkSuccess.vue 1 month ago SetPass.vue 1 month ago SignIn.vue 1 month ago Skeleton.vue 1 month ago
SignIn.vue
427 lines
1 <template>
2 <div class="am-asi" :style="cssVars">
3 <div class="am-asi__top">
4 <AmAlert
5 v-if="profileDeleted"
6 class="am-asi__top-message"
7 type="success"
8 :title="labelsDisplay('profile_deleted')"
9 :description="''"
10 :show-icon="true"
11 :closable="true"
12 @close="profileDeleted = false"
13 ></AmAlert>
14
15 <div class="am-asi__header">
16 {{ labelsDisplay('welcome_back') }}
17 </div>
18 <div class="am-asi__text">
19 {{ labelsDisplay('enter_credentials') }}
20 </div>
21 </div>
22
23 <!-- Social Buttons -->
24 <div v-if="features.googleSocialLogin || features.facebookSocialLogin">
25 <div class="am-asi__social-wrapper">
26 <img
27 v-if="features.googleSocialLogin"
28 :src="baseUrls.wpAmeliaPluginURL + '/v3/src/assets/img/icons/google.svg'"
29 height="36"
30 />
31 <img
32 v-if="features.facebookSocialLogin"
33 :src="baseUrls.wpAmeliaPluginURL + '/v3/src/assets/img/icons/facebook.svg'"
34 height="36"
35 />
36 </div>
37 <!-- /Social Buttons -->
38
39 <!-- Social Divider -->
40 <div class="am-asi__social-divider">
41 <span class="par-sm">{{ labelsDisplay('or_enter_details_below') }}</span>
42 </div>
43 </div>
44 <!-- /Social Divider -->
45
46 <el-form
47 ref="authFormRef"
48 :model="infoFormData"
49 :rules="infoFormRules"
50 label-position="top"
51 class="am-asi__form"
52 :class="responsiveClass"
53 >
54 <template v-for="(item, index) in signInFormConstruction" :key="index">
55 <component
56 :is="item.template"
57 ref="customerCollectorRef"
58 v-model="infoFormData[index]"
59 v-bind="item.props"
60 @enter="submitForm"
61 ></component>
62 </template>
63 </el-form>
64
65 <AmButton
66 class="am-asi__btn"
67 :type="amCustomize[pageRenderKey][stepName].options.signInBtn.buttonType"
68 @click="submitForm"
69 >
70 {{ labelsDisplay('sign_in') }}
71 </AmButton>
72
73 <div class="am-asi__footer">
74 <span class="am-asi__footer-text">
75 {{ labelsDisplay('forgot_your_password') }}
76 </span>
77 <span class="am-asi__footer-link">
78 {{ labelsDisplay('reset_password') }}
79 </span>
80 </div>
81 </div>
82 </template>
83
84 <script setup>
85 // * import from Vue
86 import { ref, computed, inject, defineComponent, markRaw } from 'vue'
87
88 // * Composables
89 import { useResponsiveClass } from '../../../../../../../assets/js/common/responsive'
90 import { useColorTransparency } from '../../../../../../../assets/js/common/colorManipulation'
91
92 // * Components
93 import { formFieldsTemplates } from '../../../../../../../assets/js/common/formFieldsTemplates'
94 import AmButton from '../../../../../../_components/button/AmButton.vue'
95 import AmAlert from '../../../../../../_components/alert/AmAlert.vue'
96 import IconComponent from '../../../../../../_components/icons/IconComponent.vue'
97
98 // * Customize
99 const amCustomize = inject('customize')
100
101 // * Labels
102 const amLabels = inject('labels')
103 let langKey = inject('langKey')
104
105 let pageRenderKey = inject('pageRenderKey')
106 let stepName = inject('stepName')
107
108 // * Plugin Licence
109 let licence = inject('licence')
110
111 // * Features
112 let features = inject('features')
113
114 let baseUrls = inject('baseUrls')
115
116 // * Label computed function
117 function labelsDisplay(label) {
118 let computedLabel = computed(() => {
119 return amCustomize.value[pageRenderKey.value][stepName.value].translations &&
120 amCustomize.value[pageRenderKey.value][stepName.value].translations[label] &&
121 amCustomize.value[pageRenderKey.value][stepName.value].translations[label][langKey.value]
122 ? amCustomize.value[pageRenderKey.value][stepName.value].translations[label][langKey.value]
123 : amLabels[label]
124 })
125
126 return computedLabel.value
127 }
128
129 // * Icon components
130 let emailIcon = defineComponent({
131 components: { IconComponent },
132 template: `<IconComponent icon="email"></IconComponent>`,
133 })
134
135 let passwordIcon = defineComponent({
136 components: { IconComponent },
137 template: `<IconComponent icon="password"></IconComponent>`,
138 })
139
140 /********
141 * Form *
142 ********/
143 // * Form reference
144 let authFormRef = ref(null)
145
146 // * Form data
147 let infoFormData = ref({
148 email: '',
149 password: '',
150 })
151
152 // * Form validation rules
153 let infoFormRules = computed(() => {
154 return {
155 email: [
156 {
157 required: true,
158 message: labelsDisplay('enter_email_or_username_warning'),
159 trigger: 'submit',
160 },
161 ],
162 password: [
163 {
164 required: true,
165 message: labelsDisplay('enter_password_warning'),
166 trigger: 'submit',
167 },
168 ],
169 }
170 })
171
172 // * Form construction
173 let signInFormConstruction = ref({
174 email: {
175 template: formFieldsTemplates.text,
176 props: {
177 itemName: 'email',
178 label: computed(() => labelsDisplay('email_or_username')),
179 prefixIcon: markRaw(emailIcon),
180 placeholder: '',
181 class: 'am-asi__item',
182 },
183 },
184 password: {
185 template: formFieldsTemplates.text,
186 props: {
187 itemName: 'password',
188 itemType: 'password',
189 showPassword: true,
190 label: computed(() => labelsDisplay('password')),
191 prefixIcon: markRaw(passwordIcon),
192 placeholder: '',
193 class: 'am-asi__item',
194 },
195 },
196 })
197
198 // * Submit Form
199 let profileDeleted = ref(false)
200 function submitForm() {
201 authFormRef.value.validate((valid) => {
202 if (!valid) profileDeleted.value = true
203 return !!valid
204 })
205 }
206
207 /*************
208 * Customize *
209 *************/
210
211 // * Responsive - Container Width
212 let cWidth = inject('containerWidth')
213
214 let responsiveClass = computed(() => useResponsiveClass(cWidth.value))
215
216 // * Fonts
217 let amFonts = inject('amFonts')
218
219 // * Colors block
220 let amColors = inject('amColors')
221
222 let cssVars = computed(() => {
223 return {
224 '--am-c-primary': amColors.value.colorPrimary,
225 '--am-c-success': amColors.value.colorSuccess,
226 '--am-c-error': amColors.value.colorError,
227 '--am-c-warning': amColors.value.colorWarning,
228 '--am-c-main-bgr': amColors.value.colorMainBgr,
229 '--am-c-main-heading-text': amColors.value.colorMainHeadingText,
230 '--am-c-main-text': amColors.value.colorMainText,
231 '--am-c-main-text-op70': useColorTransparency(amColors.value.colorMainText, 0.7),
232 '--am-c-main-text-op60': useColorTransparency(amColors.value.colorMainText, 0.6),
233 '--am-c-main-text-op40': useColorTransparency(amColors.value.colorMainText, 0.4),
234 '--am-c-main-text-op25': useColorTransparency(amColors.value.colorMainText, 0.25),
235 '--am-c-inp-bgr': amColors.value.colorInpBgr,
236 '--am-c-inp-border': amColors.value.colorInpBorder,
237 '--am-c-inp-text': amColors.value.colorInpText,
238 '--am-c-inp-placeholder': amColors.value.colorInpPlaceHolder,
239 '--am-c-btn-prim': amColors.value.colorBtnPrim,
240 '--am-c-btn-prim-text': amColors.value.colorBtnPrimText,
241 '--am-c-skeleton-op20': useColorTransparency(amColors.value.colorMainText, 0.2),
242 '--am-c-skeleton-op60': useColorTransparency(amColors.value.colorMainText, 0.6),
243 '--am-font-family': amFonts.value.fontFamily,
244
245 '--am-c-scroll-op30': useColorTransparency(amColors.value.colorPrimary, 0.3),
246 '--am-c-scroll-op10': useColorTransparency(amColors.value.colorPrimary, 0.1),
247 }
248 })
249 </script>
250
251 <script>
252 export default {
253 name: 'AuthSignIn',
254 key: 'signIn',
255 }
256 </script>
257
258 <style lang="scss">
259 // am - amelia
260 // asi - authentication sign in
261 @mixin auth {
262 .am-asi {
263 max-width: 400px;
264 width: 100%;
265 background-color: var(--am-c-main-bgr);
266 box-shadow:
267 0 0 9px -4px var(--am-c-main-text-op40),
268 0px 17px 35px -12px var(--am-c-main-text-op25);
269 border-radius: 12px;
270 padding: 32px 24px 24px;
271 margin: 0 auto;
272 font-family: var(--am-font-family);
273
274 * {
275 font-family: var(--am-font-family);
276 box-sizing: border-box;
277 }
278
279 &__top {
280 display: flex;
281 flex-direction: column;
282 align-items: center;
283 margin: 0 0 32px;
284
285 &-message {
286 width: 100%;
287 margin-bottom: 22px;
288 font-weight: 500;
289 font-size: 16px;
290 line-height: 1.5;
291 border: 1px solid var(--am-c-success);
292 border-bottom-width: 4px;
293 box-shadow: 0 2px 3px rgba(26, 44, 55, 0.1);
294 border-radius: 5px;
295
296 .el-alert {
297 &--success {
298 border: none;
299 }
300
301 .el-icon {
302 color: var(--am-c-success);
303 }
304
305 &__closebtn {
306 font-size: 16px;
307 color: var(--am-c-main-text);
308 }
309 }
310 }
311 }
312
313 &__social-wrapper {
314 display: flex;
315 align-items: center;
316 justify-content: center;
317 width: 100%;
318 margin: 8px 0 24px;
319 gap: 24px;
320
321 img {
322 border: 1px solid #d1d5d7;
323 padding: 4px;
324 border-radius: 4px;
325 }
326 }
327
328 &__social-divider {
329 align-items: center;
330 display: flex;
331 margin-bottom: 24px;
332
333 // Before & After
334 &:before,
335 &:after {
336 background: var(--shade-250, #d1d5d7);
337 content: '';
338 height: 1px;
339 width: 100%;
340 }
341
342 span {
343 flex: none;
344 font-size: 15px;
345 font-style: normal;
346 font-weight: 400;
347 line-height: 24px;
348 color: var(--shade-500, #808a90);
349 margin-left: 8px;
350 margin-right: 8px;
351 }
352 }
353
354 &__header {
355 font-size: 24px;
356 font-weight: 500;
357 line-height: 1.33333;
358 color: var(--am-c-main-heading-text);
359 margin: 0 0 4px;
360 }
361
362 &__text {
363 font-size: 15px;
364 font-weight: 400;
365 line-height: 1.6;
366 text-align: center;
367 color: var(--am-c-main-text-op70);
368 }
369
370 &__form {
371 .am-ff {
372 &__item {
373 &-label {
374 font-size: 15px;
375 font-weight: 500;
376 color: var(--am-c-main-text);
377 }
378 }
379 }
380
381 .el-form {
382 &-item {
383 margin-bottom: 30px;
384
385 &__label {
386 margin: 0 0 4px;
387 }
388 }
389 }
390 }
391
392 &__btn {
393 width: 100%;
394 margin: 16px 0;
395 }
396
397 &__footer {
398 display: flex;
399 align-items: center;
400 justify-content: center;
401 flex-wrap: wrap;
402
403 &-text {
404 font-size: 15px;
405 font-weight: 400;
406 line-height: 1.6;
407 color: var(--am-c-main-text-op70);
408 cursor: pointer;
409 }
410
411 &-link {
412 font-size: 15px;
413 font-weight: 400;
414 line-height: 1.6;
415 color: var(--am-c-primary);
416 cursor: pointer;
417 }
418 }
419 }
420 }
421
422 // Admin
423 #amelia-app-backend-new {
424 @include auth;
425 }
426 </style>
427