@fy-/fws-vue 2.2.63 → 2.2.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/fws/UserFlow.vue +188 -128
- package/components/ui/DefaultInput.vue +6 -5
- package/package.json +1 -1
|
@@ -219,161 +219,221 @@ onMounted(async () => {
|
|
|
219
219
|
<form
|
|
220
220
|
v-if="!completed"
|
|
221
221
|
class="fws-login w-full"
|
|
222
|
+
aria-labelledby="login-title"
|
|
222
223
|
@submit.prevent="userFlow()"
|
|
223
224
|
>
|
|
224
|
-
<!--
|
|
225
|
-
<div
|
|
225
|
+
<!-- Message / Header -->
|
|
226
|
+
<div
|
|
227
|
+
v-if="responseMessage"
|
|
228
|
+
class="fws-login__header mb-4"
|
|
229
|
+
>
|
|
226
230
|
<h2
|
|
227
|
-
|
|
228
|
-
class="text-lg text-fv-neutral-700 dark:text-fv-neutral-300
|
|
231
|
+
id="login-title"
|
|
232
|
+
class="text-lg font-medium text-fv-neutral-700 dark:text-fv-neutral-300"
|
|
229
233
|
>
|
|
230
234
|
{{ responseMessage }}
|
|
231
235
|
</h2>
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
userFlow({ initial: true, oauth: field.id });
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
"
|
|
254
|
-
>
|
|
255
|
-
<img
|
|
256
|
-
:key="`${field.label}oauth`"
|
|
257
|
-
class="h-12 w-12 block p-2 mr-3"
|
|
258
|
-
:alt="field.info.Name"
|
|
259
|
-
:src="field.button.logo"
|
|
260
|
-
>
|
|
261
|
-
<div>
|
|
262
|
-
{{
|
|
263
|
-
$t("user_flow_signin_with", {
|
|
264
|
-
provider: field.name,
|
|
265
|
-
})
|
|
266
|
-
}}
|
|
267
|
-
</div>
|
|
268
|
-
</a>
|
|
269
|
-
</template>
|
|
270
|
-
<button
|
|
271
|
-
type="button"
|
|
272
|
-
class="flex items-center gap-2 justify-start btn neutral defaults w-full mx-auto !font-semibold"
|
|
273
|
-
@click="
|
|
274
|
-
() => {
|
|
275
|
-
showEmail = true;
|
|
236
|
+
</div>
|
|
237
|
+
|
|
238
|
+
<!-- OAuth providers section -->
|
|
239
|
+
<div v-if="hasOauth && !showEmail" class="fws-login__oauth space-y-3">
|
|
240
|
+
<template v-for="field of responseFields" :key="field.id">
|
|
241
|
+
<a
|
|
242
|
+
v-if="field.type && field.type === 'oauth2' && field.button"
|
|
243
|
+
href="javascript:void(0);"
|
|
244
|
+
class="flex w-full items-center justify-start gap-3 px-4 py-2.5 rounded-lg border border-fv-neutral-200 dark:border-fv-neutral-700
|
|
245
|
+
transition-all duration-200 hover:shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-fv-neutral-800
|
|
246
|
+
focus:ring-fv-primary-500 dark:focus:ring-fv-primary-600"
|
|
247
|
+
:style="field.button && field.button['background-color']
|
|
248
|
+
? `background: ${field.button['background-color']}; color: ${$getContrastingTextColor(field.button['background-color'])}`
|
|
249
|
+
: ''"
|
|
250
|
+
@click="
|
|
251
|
+
() => {
|
|
252
|
+
if (field.info && field.info.Button_Extra && field.info.Button_Extra.trigger) {
|
|
253
|
+
doTrigger(field);
|
|
276
254
|
}
|
|
277
|
-
|
|
255
|
+
else {
|
|
256
|
+
userFlow({ initial: true, oauth: field.id });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
"
|
|
260
|
+
>
|
|
261
|
+
<img
|
|
262
|
+
v-if="field.button && field.button.logo"
|
|
263
|
+
:key="`${field.label}oauth`"
|
|
264
|
+
class="h-6 w-6 flex-shrink-0"
|
|
265
|
+
:alt="field.info && field.info.Name ? field.info.Name : ''"
|
|
266
|
+
:src="field.button.logo"
|
|
278
267
|
>
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
provider: $t("user_flow_provider_email_cta"),
|
|
284
|
-
})
|
|
285
|
-
}}
|
|
286
|
-
</div>
|
|
287
|
-
</button>
|
|
288
|
-
</div>
|
|
268
|
+
<span class="text-base font-medium">
|
|
269
|
+
{{ $t("user_flow_signin_with", { provider: field.name }) }}
|
|
270
|
+
</span>
|
|
271
|
+
</a>
|
|
289
272
|
</template>
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
class="
|
|
273
|
+
|
|
274
|
+
<div class="relative my-6">
|
|
275
|
+
<div class="absolute inset-0 flex items-center">
|
|
276
|
+
<div class="w-full border-t border-fv-neutral-200 dark:border-fv-neutral-700" />
|
|
277
|
+
</div>
|
|
278
|
+
<div class="relative flex justify-center text-sm">
|
|
279
|
+
<span class="px-2 bg-white dark:bg-fv-neutral-800 text-fv-neutral-500 dark:text-fv-neutral-400">
|
|
280
|
+
{{ $t("user_flow_or") }}
|
|
281
|
+
</span>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
|
|
285
|
+
<button
|
|
286
|
+
type="button"
|
|
287
|
+
class="flex w-full items-center justify-start gap-3 px-4 py-2.5 rounded-lg border border-fv-neutral-200 dark:border-fv-neutral-700
|
|
288
|
+
bg-white dark:bg-fv-neutral-700 text-fv-neutral-800 dark:text-white
|
|
289
|
+
hover:bg-fv-neutral-50 dark:hover:bg-fv-neutral-650 transition-all duration-200
|
|
290
|
+
hover:shadow-sm focus:outline-none focus:ring-2 focus:ring-fv-primary-500 dark:focus:ring-fv-primary-600"
|
|
291
|
+
aria-label="Sign in with email"
|
|
292
|
+
@click="showEmail = true"
|
|
293
293
|
>
|
|
294
|
-
<
|
|
295
|
-
|
|
294
|
+
<EnvelopeIcon class="h-6 w-6 text-fv-primary-500 dark:text-fv-primary-400 flex-shrink-0" />
|
|
295
|
+
<span class="text-base font-medium">
|
|
296
|
+
{{ $t("user_flow_signin_with", { provider: $t("user_flow_provider_email_cta") }) }}
|
|
297
|
+
</span>
|
|
298
|
+
</button>
|
|
299
|
+
</div>
|
|
300
|
+
|
|
301
|
+
<!-- Form fields section -->
|
|
302
|
+
<div
|
|
303
|
+
v-if="forceAction || (showEmail && initial) || !initial"
|
|
304
|
+
class="fws-login__form space-y-4"
|
|
305
|
+
>
|
|
306
|
+
<template v-if="responseFields && responseFields.length > 0">
|
|
307
|
+
<!-- Labels and text elements -->
|
|
308
|
+
<template v-for="field of responseFields" :key="field.label">
|
|
309
|
+
<div
|
|
310
|
+
v-if="field.type === 'label'"
|
|
311
|
+
class="mb-2"
|
|
312
|
+
>
|
|
296
313
|
<h3
|
|
297
|
-
|
|
298
|
-
class="
|
|
299
|
-
:class="
|
|
314
|
+
class="text-sm"
|
|
315
|
+
:class="[
|
|
300
316
|
field.style === 'error'
|
|
301
|
-
? '
|
|
302
|
-
: ''
|
|
303
|
-
"
|
|
317
|
+
? 'p-3 rounded-lg bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 font-medium'
|
|
318
|
+
: 'text-fv-neutral-600 dark:text-fv-neutral-400',
|
|
319
|
+
]"
|
|
304
320
|
>
|
|
305
|
-
<a
|
|
306
|
-
field.
|
|
307
|
-
|
|
308
|
-
|
|
321
|
+
<a
|
|
322
|
+
v-if="field.link"
|
|
323
|
+
:href="field.link"
|
|
324
|
+
class="text-fv-primary-600 dark:text-fv-primary-400 hover:underline focus:outline-none focus:ring-2 focus:ring-fv-primary-500 dark:focus:ring-fv-primary-600 rounded"
|
|
325
|
+
>
|
|
326
|
+
{{ field.label }}
|
|
327
|
+
</a>
|
|
328
|
+
<span v-else v-html="field.label" />
|
|
309
329
|
</h3>
|
|
330
|
+
</div>
|
|
310
331
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
v-if="field.name"
|
|
325
|
-
:id="field.name"
|
|
326
|
-
ref="inputs"
|
|
327
|
-
v-model="formData[field.name]"
|
|
328
|
-
:label="field.label"
|
|
329
|
-
:mask="field.mask"
|
|
330
|
-
class="mt-3"
|
|
331
|
-
:placeholder="
|
|
332
|
-
field.name === 'name' ? 'John Doe' : field.label
|
|
333
|
-
"
|
|
334
|
-
:error="fieldsError[field.name]"
|
|
335
|
-
:type="field.type"
|
|
336
|
-
:req="responseReq.includes(field.name)"
|
|
337
|
-
:autocomplete="autocompleteValue(field.name)"
|
|
338
|
-
/>
|
|
339
|
-
</template>
|
|
340
|
-
</template>
|
|
341
|
-
<template v-if="field.type === 'checkbox'">
|
|
332
|
+
<!-- Input fields -->
|
|
333
|
+
<template v-if="field.cat === 'input'">
|
|
334
|
+
<template
|
|
335
|
+
v-if="
|
|
336
|
+
field.type === 'text'
|
|
337
|
+
|| field.type === 'password'
|
|
338
|
+
|| field.type === 'email'
|
|
339
|
+
|| field.type === 'mask'
|
|
340
|
+
|| field.type === 'tel'
|
|
341
|
+
|| field.type === 'number'
|
|
342
|
+
|| field.type === 'phone'
|
|
343
|
+
"
|
|
344
|
+
>
|
|
342
345
|
<DefaultInput
|
|
343
346
|
v-if="field.name"
|
|
344
347
|
:id="field.name"
|
|
345
|
-
|
|
346
|
-
|
|
348
|
+
ref="inputs"
|
|
349
|
+
v-model="formData[field.name]"
|
|
347
350
|
:label="field.label"
|
|
351
|
+
:mask="field.mask"
|
|
352
|
+
:placeholder="
|
|
353
|
+
field.name === 'name' ? 'John Doe' : field.label
|
|
354
|
+
"
|
|
348
355
|
:error="fieldsError[field.name]"
|
|
349
356
|
:type="field.type"
|
|
350
357
|
:req="responseReq.includes(field.name)"
|
|
351
|
-
:
|
|
358
|
+
:autocomplete="autocompleteValue(field.name)"
|
|
352
359
|
/>
|
|
353
360
|
</template>
|
|
354
361
|
</template>
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
>{{ $t("recover_pwd_link") }}</a>
|
|
370
|
-
</div>
|
|
371
|
-
<button class="btn primary medium mt-4">
|
|
372
|
-
{{ $t("cta_login_next") }}
|
|
373
|
-
</button>
|
|
362
|
+
|
|
363
|
+
<!-- Checkbox inputs -->
|
|
364
|
+
<template v-if="field.type === 'checkbox'">
|
|
365
|
+
<DefaultInput
|
|
366
|
+
v-if="field.name"
|
|
367
|
+
:id="field.name"
|
|
368
|
+
v-model:checkbox-value="formData[field.name]"
|
|
369
|
+
:label="field.label"
|
|
370
|
+
:error="fieldsError[field.name]"
|
|
371
|
+
:type="field.type"
|
|
372
|
+
:req="responseReq.includes(field.name)"
|
|
373
|
+
:link-icon="field.link"
|
|
374
|
+
/>
|
|
375
|
+
</template>
|
|
374
376
|
</template>
|
|
375
|
-
|
|
377
|
+
|
|
378
|
+
<!-- Error message -->
|
|
379
|
+
<div
|
|
380
|
+
v-if="responseError && responseError.token"
|
|
381
|
+
class="p-3 rounded-lg bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 text-sm font-medium"
|
|
382
|
+
role="alert"
|
|
383
|
+
v-html="$t(responseError.token)"
|
|
384
|
+
/>
|
|
385
|
+
|
|
386
|
+
<!-- Password recovery link -->
|
|
387
|
+
<div
|
|
388
|
+
v-if="responseReq.includes('password') && 0"
|
|
389
|
+
class="text-right my-2"
|
|
390
|
+
>
|
|
391
|
+
<button
|
|
392
|
+
type="button"
|
|
393
|
+
class="text-fv-primary-600 dark:text-fv-primary-400 text-sm hover:underline focus:outline-none focus:ring-2 focus:ring-fv-primary-500 rounded"
|
|
394
|
+
@click="
|
|
395
|
+
() => {
|
|
396
|
+
eventBus.emit('ResetPasswordModal', true);
|
|
397
|
+
pwdRecoverMailSent = false;
|
|
398
|
+
}
|
|
399
|
+
"
|
|
400
|
+
>
|
|
401
|
+
{{ $t("recover_pwd_link") }}
|
|
402
|
+
</button>
|
|
403
|
+
</div>
|
|
404
|
+
|
|
405
|
+
<!-- Submit button -->
|
|
406
|
+
<button
|
|
407
|
+
type="submit"
|
|
408
|
+
class="w-full flex justify-center py-2.5 px-4 border border-transparent rounded-lg shadow-sm
|
|
409
|
+
text-white bg-fv-primary-600 hover:bg-fv-primary-700 dark:bg-fv-primary-700 dark:hover:bg-fv-primary-800
|
|
410
|
+
focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-fv-primary-500 dark:focus:ring-fv-primary-600
|
|
411
|
+
dark:focus:ring-offset-fv-neutral-800 font-medium transition-all duration-200"
|
|
412
|
+
aria-label="Continue"
|
|
413
|
+
>
|
|
414
|
+
{{ $t("cta_login_next") }}
|
|
415
|
+
</button>
|
|
416
|
+
</template>
|
|
376
417
|
</div>
|
|
377
418
|
</form>
|
|
378
419
|
</ClientOnly>
|
|
379
420
|
</template>
|
|
421
|
+
|
|
422
|
+
<style scoped>
|
|
423
|
+
.fws-login {
|
|
424
|
+
@apply transition-all duration-300;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.fws-login__oauth a,
|
|
428
|
+
.fws-login__oauth button,
|
|
429
|
+
.fws-login__form button[type="submit"] {
|
|
430
|
+
@apply transition-all duration-200;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
@media (max-width: 640px) {
|
|
434
|
+
.fws-login__oauth,
|
|
435
|
+
.fws-login__form {
|
|
436
|
+
@apply px-0;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
</style>
|
|
@@ -187,7 +187,7 @@ defineExpose({ focus, blur, getInputRef })
|
|
|
187
187
|
:name="id"
|
|
188
188
|
:class="{
|
|
189
189
|
'error': checkErrors,
|
|
190
|
-
'bg-fv-neutral-50 border border-fv-neutral-300 text-fv-neutral-900 text-sm rounded-lg block w-full dark:bg-fv-neutral-700 dark:border-fv-neutral-600 dark:placeholder-fv-neutral-
|
|
190
|
+
'bg-fv-neutral-50 border border-fv-neutral-300 text-fv-neutral-900 text-sm rounded-lg block w-full dark:bg-fv-neutral-700 dark:border-fv-neutral-600 dark:placeholder-fv-neutral-300 dark:text-white transition-all duration-200': type !== 'range',
|
|
191
191
|
'p-2.5': type !== 'range',
|
|
192
192
|
'focus:border-fv-primary-500 dark:focus:border-fv-primary-500': !checkErrors,
|
|
193
193
|
'focus:ring-2 focus:ring-fv-primary-300 dark:focus:ring-fv-primary-800 focus:ring-opacity-50': type !== 'range',
|
|
@@ -288,7 +288,7 @@ defineExpose({ focus, blur, getInputRef })
|
|
|
288
288
|
:aria-invalid="checkErrors ? 'true' : 'false'"
|
|
289
289
|
class="block p-2.5 w-full text-sm text-fv-neutral-900 bg-fv-neutral-50 rounded-lg
|
|
290
290
|
border border-fv-neutral-300 focus:ring-2 focus:ring-fv-primary-300 focus:border-fv-primary-500
|
|
291
|
-
dark:bg-fv-neutral-700 dark:border-fv-neutral-600 dark:placeholder-fv-neutral-
|
|
291
|
+
dark:bg-fv-neutral-700 dark:border-fv-neutral-600 dark:placeholder-fv-neutral-300
|
|
292
292
|
dark:text-white dark:focus:ring-fv-primary-800 dark:focus:border-fv-primary-500
|
|
293
293
|
transition-colors duration-200 shadow-sm"
|
|
294
294
|
@focus="handleFocus"
|
|
@@ -332,7 +332,7 @@ defineExpose({ focus, blur, getInputRef })
|
|
|
332
332
|
:aria-invalid="checkErrors ? 'true' : 'false'"
|
|
333
333
|
class="block p-2.5 w-full text-sm text-fv-neutral-900 bg-fv-neutral-50
|
|
334
334
|
rounded-lg border border-fv-neutral-300 focus:ring-2 focus:ring-fv-primary-300 focus:border-fv-primary-500
|
|
335
|
-
dark:bg-fv-neutral-700 dark:border-fv-neutral-600 dark:placeholder-fv-neutral-
|
|
335
|
+
dark:bg-fv-neutral-700 dark:border-fv-neutral-600 dark:placeholder-fv-neutral-300
|
|
336
336
|
dark:text-white dark:focus:ring-fv-primary-800 dark:focus:border-fv-primary-500
|
|
337
337
|
transition-colors duration-200 shadow-sm min-h-[100px]"
|
|
338
338
|
@focus="handleFocus"
|
|
@@ -375,7 +375,7 @@ defineExpose({ focus, blur, getInputRef })
|
|
|
375
375
|
class="appearance-none bg-fv-neutral-50 border border-fv-neutral-300 text-fv-neutral-900 text-sm
|
|
376
376
|
rounded-lg focus:ring-2 focus:ring-fv-primary-300 focus:border-fv-primary-500
|
|
377
377
|
block w-full p-2.5 dark:bg-fv-neutral-700 dark:border-fv-neutral-600
|
|
378
|
-
dark:placeholder-fv-neutral-
|
|
378
|
+
dark:placeholder-fv-neutral-300 dark:text-white dark:focus:ring-fv-primary-800
|
|
379
379
|
dark:focus:border-fv-primary-500 shadow-sm transition-colors duration-200 pr-10"
|
|
380
380
|
@focus="handleFocus"
|
|
381
381
|
@blur="handleBlur"
|
|
@@ -577,6 +577,7 @@ input, select, textarea, input[type="range"]::-webkit-slider-thumb, input[type="
|
|
|
577
577
|
input::placeholder,
|
|
578
578
|
textarea::placeholder,
|
|
579
579
|
select::placeholder {
|
|
580
|
-
@apply text-fv-neutral-400 dark:text-fv-neutral-
|
|
580
|
+
@apply text-fv-neutral-400 dark:text-fv-neutral-300;
|
|
581
|
+
opacity: 0.8;
|
|
581
582
|
}
|
|
582
583
|
</style>
|