@fy-/fws-vue 0.0.923 → 0.0.925
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 +136 -100
- package/package.json +1 -1
|
@@ -8,11 +8,13 @@ import { useUserStore } from "../../stores/user";
|
|
|
8
8
|
import { useRest, APIResult } from "../../composables/rest";
|
|
9
9
|
import DefaultInput from "../ui/DefaultInput.vue";
|
|
10
10
|
import { ClientOnly } from "../ssr/ClientOnly";
|
|
11
|
+
import { EnvelopeIcon } from "@heroicons/vue/24/solid";
|
|
12
|
+
|
|
11
13
|
const rest = useRest();
|
|
12
14
|
interface UserFlow extends APIResult {
|
|
13
15
|
data: KlbFlowData;
|
|
14
16
|
}
|
|
15
|
-
|
|
17
|
+
const showEmail = ref<boolean>(false);
|
|
16
18
|
const props = withDefaults(
|
|
17
19
|
defineProps<{
|
|
18
20
|
returnDefault?: string;
|
|
@@ -31,6 +33,7 @@ type paramsType = {
|
|
|
31
33
|
initial: boolean;
|
|
32
34
|
oauth?: string;
|
|
33
35
|
};
|
|
36
|
+
const initial = ref<boolean>(true);
|
|
34
37
|
const store = useUserStore();
|
|
35
38
|
const route = useRoute();
|
|
36
39
|
const router = useRouter();
|
|
@@ -70,7 +73,7 @@ const userFlow = async (params: paramsType = { initial: false }) => {
|
|
|
70
73
|
eventBus.emit("login-loading", true);
|
|
71
74
|
fieldsError.value = {};
|
|
72
75
|
responseError.value = undefined;
|
|
73
|
-
|
|
76
|
+
initial.value = params.initial;
|
|
74
77
|
if (params.initial === false) {
|
|
75
78
|
let hasError = false;
|
|
76
79
|
responseReq.value.forEach((field) => {
|
|
@@ -164,6 +167,16 @@ const userFlow = async (params: paramsType = { initial: false }) => {
|
|
|
164
167
|
eventBus.emit("login-loading", false);
|
|
165
168
|
};
|
|
166
169
|
|
|
170
|
+
const getContrastingTextColor = (backgroundColor: string) => {
|
|
171
|
+
const r = parseInt(backgroundColor.substring(1, 3), 16);
|
|
172
|
+
const g = parseInt(backgroundColor.substring(3, 5), 16);
|
|
173
|
+
const b = parseInt(backgroundColor.substring(5, 7), 16);
|
|
174
|
+
|
|
175
|
+
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
176
|
+
|
|
177
|
+
return luminance > 0.5 ? "#000000" : "#FFFFFF";
|
|
178
|
+
};
|
|
179
|
+
|
|
167
180
|
onMounted(async () => {
|
|
168
181
|
await userFlow({ initial: true });
|
|
169
182
|
});
|
|
@@ -178,127 +191,150 @@ onMounted(async () => {
|
|
|
178
191
|
<!--<FyLoader id="klblogin" />-->
|
|
179
192
|
<div class="w-full">
|
|
180
193
|
<h2
|
|
181
|
-
class="text-lg text-fv-neutral-700 dark:text-fv-neutral-300"
|
|
194
|
+
class="text-lg text-fv-neutral-700 dark:text-fv-neutral-300 px-2"
|
|
182
195
|
v-if="responseMessage"
|
|
183
196
|
>
|
|
184
197
|
{{ responseMessage }}
|
|
185
198
|
</h2>
|
|
186
|
-
<template v-if="
|
|
187
|
-
<
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
199
|
+
<template v-if="hasOauth && !showEmail">
|
|
200
|
+
<div class="flex flex-col gap-2 px-2 justify-center py-2">
|
|
201
|
+
<template v-for="field of responseFields" :key="field.id">
|
|
202
|
+
<a
|
|
203
|
+
@click="
|
|
204
|
+
() => {
|
|
205
|
+
if (field.info.Button_Extra?.trigger) {
|
|
206
|
+
doTrigger(field);
|
|
207
|
+
} else {
|
|
208
|
+
userFlow({ initial: true, oauth: field.id });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
"
|
|
212
|
+
v-if="field.type && field.type == 'oauth2' && field.button"
|
|
213
|
+
href="javascript:void(0);"
|
|
214
|
+
class="flex border border-fv-neutral-300 dark:border-fv-neutral-700 shadow items-center gap-2 justify-start btn neutral defaults w-full mx-auto !font-semibold"
|
|
215
|
+
:style="`background: ${
|
|
216
|
+
field.button['background-color']
|
|
217
|
+
}; color: ${getContrastingTextColor(
|
|
218
|
+
field.button['background-color'],
|
|
219
|
+
)}`"
|
|
220
|
+
>
|
|
221
|
+
<img
|
|
222
|
+
:key="`${field.label}oauth`"
|
|
223
|
+
class="h-12 w-12 block p-2 mr-3"
|
|
224
|
+
:alt="field.info.Name"
|
|
225
|
+
:src="field.button.logo"
|
|
226
|
+
/>
|
|
227
|
+
<div>
|
|
228
|
+
{{
|
|
229
|
+
$t("user_flow_signin_with", {
|
|
230
|
+
provider: field.name,
|
|
231
|
+
})
|
|
232
|
+
}}
|
|
233
|
+
</div>
|
|
234
|
+
</a>
|
|
235
|
+
</template>
|
|
236
|
+
<button
|
|
237
|
+
type="button"
|
|
238
|
+
class="flex items-center gap-2 justify-start btn neutral defaults w-full mx-auto !font-semibold"
|
|
239
|
+
@click="
|
|
240
|
+
() => {
|
|
241
|
+
showEmail = true;
|
|
242
|
+
}
|
|
195
243
|
"
|
|
196
244
|
>
|
|
197
|
-
<
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
245
|
+
<EnvelopeIcon class="h-12 w-12 block p-2 mr-3" />
|
|
246
|
+
<div>
|
|
247
|
+
{{
|
|
248
|
+
$t("user_flow_signin_with", {
|
|
249
|
+
provider: $t("user_flow_provider_email_cta"),
|
|
250
|
+
})
|
|
251
|
+
}}
|
|
252
|
+
</div>
|
|
253
|
+
</button>
|
|
254
|
+
</div></template
|
|
255
|
+
>
|
|
256
|
+
<div
|
|
257
|
+
class="px-2 py-2"
|
|
258
|
+
v-if="forceAction || (showEmail && initial) || !initial"
|
|
259
|
+
>
|
|
260
|
+
<template v-if="responseFields && responseFields.length > 0">
|
|
261
|
+
<template v-for="field of responseFields" :key="field.label">
|
|
262
|
+
<h3
|
|
263
|
+
v-if="field.type == 'label'"
|
|
264
|
+
class="pt-2 pb-1 text-sm text-fv-neutral-500 dark:text-fv-neutral-400"
|
|
265
|
+
:class="
|
|
266
|
+
field.style == 'error'
|
|
267
|
+
? 'text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300'
|
|
268
|
+
: ''
|
|
209
269
|
"
|
|
210
270
|
>
|
|
271
|
+
<a :href="field.link" v-if="field.link" class="fws-link mb-3">{{
|
|
272
|
+
field.label
|
|
273
|
+
}}</a>
|
|
274
|
+
<span class="mb-2" v-else>{{ field.label }}</span>
|
|
275
|
+
</h3>
|
|
276
|
+
|
|
277
|
+
<template v-if="field.cat == 'input'">
|
|
278
|
+
<template
|
|
279
|
+
v-if="
|
|
280
|
+
field.type == 'text' ||
|
|
281
|
+
field.type == 'password' ||
|
|
282
|
+
field.type == 'email'
|
|
283
|
+
"
|
|
284
|
+
>
|
|
285
|
+
<DefaultInput
|
|
286
|
+
v-if="field.name"
|
|
287
|
+
:id="field.name"
|
|
288
|
+
:label="field.label"
|
|
289
|
+
class="mt-3"
|
|
290
|
+
:placeholder="
|
|
291
|
+
field.name == 'name' ? 'John Doe' : field.label
|
|
292
|
+
"
|
|
293
|
+
:error="fieldsError[field.name]"
|
|
294
|
+
:type="field.type"
|
|
295
|
+
ref="inputs"
|
|
296
|
+
v-model="formData[field.name]"
|
|
297
|
+
:req="responseReq.includes(field.name)"
|
|
298
|
+
/>
|
|
299
|
+
</template>
|
|
300
|
+
</template>
|
|
301
|
+
<template v-if="field.type == 'checkbox'">
|
|
211
302
|
<DefaultInput
|
|
212
303
|
v-if="field.name"
|
|
213
304
|
:id="field.name"
|
|
214
|
-
:label="field.label"
|
|
215
305
|
class="mt-3"
|
|
216
|
-
:
|
|
306
|
+
:label="field.label"
|
|
217
307
|
:error="fieldsError[field.name]"
|
|
218
308
|
:type="field.type"
|
|
219
|
-
|
|
220
|
-
v-model="formData[field.name]"
|
|
309
|
+
v-model:checkbox-value="formData[field.name]"
|
|
221
310
|
:req="responseReq.includes(field.name)"
|
|
311
|
+
:link-icon="field.link"
|
|
222
312
|
/>
|
|
223
313
|
</template>
|
|
224
314
|
</template>
|
|
225
|
-
<template v-if="field.type == 'checkbox'">
|
|
226
|
-
<DefaultInput
|
|
227
|
-
v-if="field.name"
|
|
228
|
-
:id="field.name"
|
|
229
|
-
class="mt-3"
|
|
230
|
-
:label="field.label"
|
|
231
|
-
:error="fieldsError[field.name]"
|
|
232
|
-
:type="field.type"
|
|
233
|
-
v-model:checkbox-value="formData[field.name]"
|
|
234
|
-
:req="responseReq.includes(field.name)"
|
|
235
|
-
:link-icon="field.link"
|
|
236
|
-
/>
|
|
237
|
-
</template>
|
|
238
|
-
</template>
|
|
239
|
-
<div
|
|
240
|
-
class="text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300"
|
|
241
|
-
v-if="responseError && responseError.token"
|
|
242
|
-
>
|
|
243
|
-
{{ $t(responseError.token) }}
|
|
244
|
-
</div>
|
|
245
|
-
<div v-if="responseReq.includes('password') && 0" class="reset-pwd">
|
|
246
|
-
<a
|
|
247
|
-
href="javascript:void(0)"
|
|
248
|
-
@click="
|
|
249
|
-
() => {
|
|
250
|
-
eventBus.emit('ResetPasswordModal', true);
|
|
251
|
-
pwdRecoverMailSent = false;
|
|
252
|
-
}
|
|
253
|
-
"
|
|
254
|
-
>{{ $t("recover_pwd_link") }}</a
|
|
255
|
-
>
|
|
256
|
-
</div>
|
|
257
|
-
<button class="btn primary medium mt-4">
|
|
258
|
-
{{ $t("cta_login_next") }}
|
|
259
|
-
</button>
|
|
260
|
-
<template v-if="hasOauth">
|
|
261
315
|
<div
|
|
262
|
-
class="
|
|
316
|
+
class="text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300"
|
|
317
|
+
v-if="responseError && responseError.token"
|
|
263
318
|
>
|
|
264
|
-
|
|
265
|
-
class="h-px bg-neutral-300 dark:bg-neutral-600 inset-x-0 absolute"
|
|
266
|
-
></div>
|
|
267
|
-
<div
|
|
268
|
-
class="bg-white dark:bg-neutral-700 fws-helper-text px-4 relative"
|
|
269
|
-
>
|
|
270
|
-
{{ $t("or_text_label") }}
|
|
271
|
-
</div>
|
|
319
|
+
{{ $t(responseError.token) }}
|
|
272
320
|
</div>
|
|
273
|
-
<div
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
"
|
|
287
|
-
v-if="field.type && field.type == 'oauth2' && field.button"
|
|
288
|
-
href="javascript:void(0);"
|
|
289
|
-
>
|
|
290
|
-
<img
|
|
291
|
-
:key="`${field.label}oauth`"
|
|
292
|
-
class="h-12 w-12 block p-2 mr-3 rounded-full border-4 shadow hover:border"
|
|
293
|
-
:alt="field.info.Name"
|
|
294
|
-
:src="field.button.logo"
|
|
295
|
-
:style="`background: ${field.button['background-color']}`"
|
|
296
|
-
/>
|
|
297
|
-
</a>
|
|
298
|
-
</template>
|
|
321
|
+
<div v-if="responseReq.includes('password') && 0" class="reset-pwd">
|
|
322
|
+
<a
|
|
323
|
+
href="javascript:void(0)"
|
|
324
|
+
@click="
|
|
325
|
+
() => {
|
|
326
|
+
eventBus.emit('ResetPasswordModal', true);
|
|
327
|
+
pwdRecoverMailSent = false;
|
|
328
|
+
}
|
|
329
|
+
"
|
|
330
|
+
>{{ $t("recover_pwd_link") }}</a
|
|
331
|
+
>
|
|
299
332
|
</div>
|
|
333
|
+
<button class="btn primary medium mt-4">
|
|
334
|
+
{{ $t("cta_login_next") }}
|
|
335
|
+
</button>
|
|
300
336
|
</template>
|
|
301
|
-
</
|
|
337
|
+
</div>
|
|
302
338
|
</div>
|
|
303
339
|
</form>
|
|
304
340
|
</ClientOnly>
|