@fy-/fws-vue 2.1.6 → 2.1.7

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.
Files changed (40) hide show
  1. package/components/fws/CmsArticleBoxed.vue +23 -20
  2. package/components/fws/CmsArticleSingle.vue +74 -68
  3. package/components/fws/DataTable.vue +132 -125
  4. package/components/fws/FilterData.vue +99 -101
  5. package/components/fws/UserData.vue +33 -32
  6. package/components/fws/UserFlow.vue +163 -155
  7. package/components/fws/UserOAuth2.vue +73 -72
  8. package/components/fws/UserProfile.vue +98 -101
  9. package/components/fws/UserProfileStrict.vue +65 -64
  10. package/components/ssr/ClientOnly.ts +7 -7
  11. package/components/ui/DefaultBreadcrumb.vue +13 -13
  12. package/components/ui/DefaultConfirm.vue +35 -34
  13. package/components/ui/DefaultDateSelection.vue +19 -17
  14. package/components/ui/DefaultDropdown.vue +25 -25
  15. package/components/ui/DefaultDropdownLink.vue +15 -14
  16. package/components/ui/DefaultGallery.vue +179 -168
  17. package/components/ui/DefaultInput.vue +121 -126
  18. package/components/ui/DefaultLoader.vue +17 -17
  19. package/components/ui/DefaultModal.vue +35 -33
  20. package/components/ui/DefaultNotif.vue +50 -52
  21. package/components/ui/DefaultPaging.vue +92 -95
  22. package/components/ui/DefaultSidebar.vue +29 -25
  23. package/components/ui/DefaultTagInput.vue +121 -119
  24. package/components/ui/transitions/CollapseTransition.vue +1 -1
  25. package/components/ui/transitions/ExpandTransition.vue +1 -1
  26. package/components/ui/transitions/FadeTransition.vue +1 -1
  27. package/components/ui/transitions/ScaleTransition.vue +1 -1
  28. package/components/ui/transitions/SlideTransition.vue +3 -3
  29. package/composables/event-bus.ts +10 -8
  30. package/composables/rest.ts +59 -56
  31. package/composables/seo.ts +106 -95
  32. package/composables/ssr.ts +64 -62
  33. package/composables/templating.ts +57 -57
  34. package/composables/translations.ts +13 -13
  35. package/env.d.ts +6 -4
  36. package/index.ts +101 -98
  37. package/package.json +7 -7
  38. package/stores/serverRouter.ts +25 -25
  39. package/stores/user.ts +79 -72
  40. package/types.d.ts +65 -65
@@ -1,46 +1,47 @@
1
1
  <script setup lang="ts">
2
- import useVuelidate from "@vuelidate/core";
3
- import DefaultInput from "../ui/DefaultInput.vue";
4
- import { useUserStore } from "../../stores/user";
5
- import { useRest } from "../../composables/rest";
6
- import { useEventBus } from "../../composables/event-bus";
7
- import { computed, reactive, watchEffect } from "vue";
8
- const rest = useRest();
9
- const userStore = useUserStore();
10
- const userData = computed(() => userStore.user);
11
- const eventBus = useEventBus();
2
+ import useVuelidate from '@vuelidate/core'
3
+ import { computed, reactive, watchEffect } from 'vue'
4
+ import { useEventBus } from '../../composables/event-bus'
5
+ import { useRest } from '../../composables/rest'
6
+ import { useUserStore } from '../../stores/user'
7
+ import DefaultInput from '../ui/DefaultInput.vue'
8
+
9
+ const rest = useRest()
10
+ const userStore = useUserStore()
11
+ const userData = computed(() => userStore.user)
12
+ const eventBus = useEventBus()
12
13
  const props = withDefaults(
13
14
  defineProps<{
14
- onCompleted?: (data: any) => void;
15
+ onCompleted?: (data: any) => void
15
16
  }>(),
16
17
  {
17
18
  onCompleted: () => {},
18
19
  },
19
- );
20
+ )
20
21
  const state = reactive({
21
22
  userData: {
22
- Firstname: userData.value?.Firstname || "",
23
- Lastname: userData.value?.Lastname || "",
24
- Phone: userData.value?.Phone || "",
23
+ Firstname: userData.value?.Firstname || '',
24
+ Lastname: userData.value?.Lastname || '',
25
+ Phone: userData.value?.Phone || '',
25
26
  AcceptedTerms: userData.value?.AcceptedTerms || false,
26
27
  EnabledNotifications: userData.value?.EnabledNotifications || false,
27
28
  EnabledEmails: userData.value?.EnabledEmails || false,
28
29
  EnabledTrainingFromMyData:
29
30
  userData.value?.EnabledTrainingFromMyData || false,
30
31
  },
31
- });
32
+ })
32
33
  watchEffect(() => {
33
34
  state.userData = {
34
- Firstname: userData.value?.Firstname || "",
35
- Lastname: userData.value?.Lastname || "",
36
- Phone: userData.value?.Phone || "",
35
+ Firstname: userData.value?.Firstname || '',
36
+ Lastname: userData.value?.Lastname || '',
37
+ Phone: userData.value?.Phone || '',
37
38
  AcceptedTerms: userData.value?.AcceptedTerms || false,
38
39
  EnabledNotifications: userData.value?.EnabledNotifications || false,
39
40
  EnabledEmails: userData.value?.EnabledEmails || false,
40
41
  EnabledTrainingFromMyData:
41
42
  userData.value?.EnabledTrainingFromMyData || false,
42
- };
43
- });
43
+ }
44
+ })
44
45
  const rules = {
45
46
  userData: {
46
47
  Firstname: {},
@@ -52,22 +53,22 @@ const rules = {
52
53
  EnabledEmails: {},
53
54
  EnabledTrainingFromMyData: {},
54
55
  },
55
- };
56
- const v$ = useVuelidate(rules, state);
56
+ }
57
+ const v$ = useVuelidate(rules, state)
57
58
 
58
- const patchUser = async () => {
59
- eventBus.emit("main-loading", true);
59
+ async function patchUser() {
60
+ eventBus.emit('main-loading', true)
60
61
  if (await v$.value.userData.$validate()) {
61
- const response = await rest("User", "PATCH", state.userData);
62
- if (response && response.result == "success") {
63
- eventBus.emit("user:refresh", true);
62
+ const response = await rest('User', 'PATCH', state.userData)
63
+ if (response && response.result === 'success') {
64
+ eventBus.emit('user:refresh', true)
64
65
  if (props.onCompleted) {
65
- props.onCompleted(response);
66
+ props.onCompleted(response)
66
67
  }
67
68
  }
68
69
  }
69
- eventBus.emit("main-loading", false);
70
- };
70
+ eventBus.emit('main-loading', false)
71
+ }
71
72
  </script>
72
73
 
73
74
  <template>
@@ -100,8 +101,8 @@ const patchUser = async () => {
100
101
  :error-vuelidate="v$.userData.Phone.$errors"
101
102
  />
102
103
  <DefaultInput
103
- id="acceptedTermsFWS"
104
104
  v-if="!userData?.AcceptedTerms"
105
+ id="acceptedTermsFWS"
105
106
  v-model:checkbox-value="state.userData.AcceptedTerms"
106
107
  type="toggle"
107
108
  :label="$t('fws_accepted_terms_label')"
@@ -1,202 +1,210 @@
1
1
  <script setup lang="ts">
2
- import { ref, onMounted } from "vue";
3
- import type { KlbFlowData, KlbUserFlowField } from "@fy-/fws-types";
4
- import { useRoute, useRouter } from "vue-router";
5
- import { useTranslation } from "../../composables/translations";
6
- import { useEventBus } from "../../composables/event-bus";
7
- import { useUserStore } from "../../stores/user";
8
- import { useRest, APIResult } from "../../composables/rest";
9
- import DefaultInput from "../ui/DefaultInput.vue";
10
- import { ClientOnly } from "../ssr/ClientOnly";
11
- import { EnvelopeIcon } from "@heroicons/vue/24/solid";
12
- import { useSessionStorage } from "@vueuse/core";
13
- const rest = useRest();
2
+ import type { KlbFlowData, KlbUserFlowField } from '@fy-/fws-types'
3
+ import type { APIResult } from '../../composables/rest'
4
+ import { EnvelopeIcon } from '@heroicons/vue/24/solid'
5
+ import { useSessionStorage } from '@vueuse/core'
6
+ import { onMounted, ref } from 'vue'
7
+ import { useRoute, useRouter } from 'vue-router'
8
+ import { useEventBus } from '../../composables/event-bus'
9
+ import { useRest } from '../../composables/rest'
10
+ import { useTranslation } from '../../composables/translations'
11
+ import { useUserStore } from '../../stores/user'
12
+ import { ClientOnly } from '../ssr/ClientOnly'
13
+ import DefaultInput from '../ui/DefaultInput.vue'
14
+
15
+ const rest = useRest()
14
16
  interface UserFlow extends APIResult {
15
- data: KlbFlowData;
17
+ data: KlbFlowData
16
18
  }
17
- const showEmail = ref<boolean>(false);
19
+ const showEmail = ref<boolean>(false)
18
20
  const props = withDefaults(
19
21
  defineProps<{
20
- returnDefault?: string;
21
- forceAction?: string;
22
- onSuccess?: Function;
22
+ returnDefault?: string
23
+ forceAction?: string
24
+ onSuccess?: Function
23
25
  }>(),
24
26
  {
25
- mode: "klb",
26
- returnDefault: "/",
27
+ mode: 'klb',
28
+ returnDefault: '/',
27
29
  },
28
- );
29
- const isExternalUrl = (url: string) => {
30
- return url.startsWith("http://") || url.startsWith("https://");
31
- };
32
- type paramsType = {
33
- initial: boolean;
34
- oauth?: string;
35
- };
36
- const initial = ref<boolean>(true);
37
- const store = useUserStore();
38
- const route = useRoute();
39
- const router = useRouter();
40
- const eventBus = useEventBus();
41
- const returnTo = ref<string>(props.returnDefault);
42
- const responseMessage = ref<string | null>(null);
43
- const responseError = ref<APIResult>();
44
- const responseReq = ref<string[]>([]);
45
- const responseFields = ref<Array<KlbUserFlowField>>([]);
46
- const response = ref<UserFlow>();
47
- const hasOauth = ref<boolean>(false);
48
- const fieldsError = ref<Record<string, any>>({});
49
- const pwdRecoverMailSent = ref<boolean>(false);
50
- const inputs = ref<InstanceType<typeof DefaultInput>[]>([]);
51
- const translate = useTranslation();
30
+ )
31
+ function isExternalUrl(url: string) {
32
+ return url.startsWith('http://') || url.startsWith('https://')
33
+ }
34
+ interface paramsType {
35
+ initial: boolean
36
+ oauth?: string
37
+ }
38
+ const initial = ref<boolean>(true)
39
+ const store = useUserStore()
40
+ const route = useRoute()
41
+ const router = useRouter()
42
+ const eventBus = useEventBus()
43
+ const returnTo = ref<string>(props.returnDefault)
44
+ const responseMessage = ref<string | null>(null)
45
+ const responseError = ref<APIResult>()
46
+ const responseReq = ref<string[]>([])
47
+ const responseFields = ref<Array<KlbUserFlowField>>([])
48
+ const response = ref<UserFlow>()
49
+ const hasOauth = ref<boolean>(false)
50
+ const fieldsError = ref<Record<string, any>>({})
51
+ const pwdRecoverMailSent = ref<boolean>(false)
52
+ const inputs = ref<InstanceType<typeof DefaultInput>[]>([])
53
+ const translate = useTranslation()
52
54
  const session = useSessionStorage<string | null>(
53
- "session",
55
+ 'session',
54
56
  route.query.session ? route.query.session.toString() : null,
55
- );
57
+ )
56
58
  const formData = ref<Record<string, any>>({
57
59
  return_to: props.returnDefault,
58
60
  session: session.value,
59
61
  action: props.forceAction ? props.forceAction : undefined,
60
- });
61
- const completed = ref(false);
62
-
63
- const doTrigger = async (field: any) => {
64
- // eslint-disable-next-line
62
+ })
63
+ const completed = ref(false)
65
64
 
65
+ async function doTrigger(field: any) {
66
+ // eslint-disable-next-line no-eval
66
67
  const _res = await eval(
67
68
  `const _rest = rest; ${field.info.Button_Extra.trigger}`,
68
- );
69
+ )
69
70
  if (_res.ethereum) {
70
- formData.value.ethereum = _res.ethereum;
71
- responseReq.value = [];
72
- await userFlow();
71
+ formData.value.ethereum = _res.ethereum
72
+ responseReq.value = []
73
+ await userFlow()
73
74
  }
74
- };
75
- const userFlow = async (params: paramsType = { initial: false }) => {
76
- eventBus.emit("login-loading", true);
77
- fieldsError.value = {};
78
- responseError.value = undefined;
79
- initial.value = params.initial;
75
+ }
76
+ async function userFlow(params: paramsType = { initial: false }) {
77
+ eventBus.emit('login-loading', true)
78
+ fieldsError.value = {}
79
+ responseError.value = undefined
80
+ initial.value = params.initial
80
81
  if (params.initial === false) {
81
- let hasError = false;
82
+ let hasError = false
82
83
  responseReq.value.forEach((field) => {
83
- if (!formData.value[field] || formData.value[field] == "") {
84
- fieldsError.value[field] = translate("vuelidate_validator_req");
85
- hasError = true;
84
+ if (!formData.value[field] || formData.value[field] === '') {
85
+ fieldsError.value[field] = translate('vuelidate_validator_req')
86
+ hasError = true
86
87
  }
87
- });
88
+ })
88
89
  if (hasError) {
89
- eventBus.emit("login-loading", false);
90
- return;
90
+ eventBus.emit('login-loading', false)
91
+ return
91
92
  }
92
- } else {
93
- formData.value.initial = true;
94
93
  }
95
- hasOauth.value = false;
94
+ else {
95
+ formData.value.initial = true
96
+ }
97
+ hasOauth.value = false
96
98
 
97
99
  if (params.oauth) {
98
- formData.value.oauth2 = params.oauth;
100
+ formData.value.oauth2 = params.oauth
99
101
  }
100
102
 
101
- if (route.query.return_to && typeof route.query.return_to == "string") {
103
+ if (route.query.return_to && typeof route.query.return_to == 'string') {
102
104
  returnTo.value = route.query.return_to
103
105
  ? route.query.return_to
104
- : props.returnDefault;
106
+ : props.returnDefault
105
107
  }
106
108
 
107
- formData.value.return_to = returnTo.value;
108
- response.value = (await rest("User:flow", "POST", formData.value).catch(
109
+ formData.value.return_to = returnTo.value
110
+ response.value = (await rest('User:flow', 'POST', formData.value).catch(
109
111
  (err: APIResult) => {
110
- if (err.token && err.token == "invalid_request_token") {
111
- window.location.reload();
112
+ if (err.token && err.token === 'invalid_request_token') {
113
+ window.location.reload()
112
114
  }
113
- responseError.value = err;
115
+ responseError.value = err
114
116
  if (responseError.value.param) {
115
- fieldsError.value[responseError.value.param] =
116
- responseError.value.token;
117
+ fieldsError.value[responseError.value.param]
118
+ = responseError.value.token
117
119
  }
118
- eventBus.emit("login-loading", false);
119
- return;
120
+ eventBus.emit('login-loading', false)
120
121
  },
121
- )) as UserFlow;
122
- if (response.value?.result == "success") {
123
- if (response.value.data.complete == true && response.value.data.user) {
124
- store.setUser(response.value.data.user);
122
+ )) as UserFlow
123
+ if (response.value?.result === 'success') {
124
+ if (response.value.data.complete === true && response.value.data.user) {
125
+ store.setUser(response.value.data.user)
125
126
  const actualReturnTo = response.value.data.redirect
126
127
  ? response.value.data.redirect
127
- : returnTo.value;
128
- session.value = null;
128
+ : returnTo.value
129
+ session.value = null
129
130
  if (isExternalUrl(actualReturnTo)) {
130
131
  if (props.onSuccess) {
131
- await props.onSuccess();
132
- } else {
133
- window.location.href = actualReturnTo;
132
+ await props.onSuccess()
134
133
  }
135
- } else {
134
+ else {
135
+ window.location.href = actualReturnTo
136
+ }
137
+ }
138
+ else {
136
139
  if (props.onSuccess) {
137
- await props.onSuccess(actualReturnTo);
138
- } else {
139
- const routeExists = router.resolve(actualReturnTo);
140
- if (routeExists.matched.length != 0) router.push(actualReturnTo);
141
- else window.location.href = actualReturnTo;
140
+ await props.onSuccess(actualReturnTo)
141
+ }
142
+ else {
143
+ const routeExists = router.resolve(actualReturnTo)
144
+ if (routeExists.matched.length !== 0) router.push(actualReturnTo)
145
+ else window.location.href = actualReturnTo
142
146
  }
143
147
  }
144
- return;
148
+ return
145
149
  }
146
150
  if (response.value.data.url) {
147
- window.location.href = response.value.data.url;
148
- return;
151
+ window.location.href = response.value.data.url
152
+ return
149
153
  }
150
154
  if (response.value.data.redirect && response.value.data.complete) {
151
155
  router.push(
152
- response.value.data.redirect ? response.value.data.redirect : "/",
153
- );
154
- return;
156
+ response.value.data.redirect ? response.value.data.redirect : '/',
157
+ )
158
+ return
155
159
  }
156
160
  formData.value = {
157
161
  session: response.value.data.session,
158
- };
159
- session.value = response.value.data.session;
160
- inputs.value = [];
161
- responseFields.value = response.value.data.fields;
162
- if (response.value.data.message)
163
- responseMessage.value = response.value.data.message;
164
- responseReq.value = response.value.data.req;
162
+ }
163
+ session.value = response.value.data.session
164
+ inputs.value = []
165
+ responseFields.value = response.value.data.fields
166
+ if (response.value.data.message) {
167
+ responseMessage.value = response.value.data.message
168
+ }
169
+ responseReq.value = response.value.data.req
165
170
  responseFields.value.forEach((field) => {
166
- if (field.type == "oauth2") {
167
- hasOauth.value = true;
171
+ if (field.type === 'oauth2') {
172
+ hasOauth.value = true
168
173
  }
169
- });
174
+ })
170
175
  if (!hasOauth.value && responseFields.value.length > 0) {
171
- showEmail.value = true;
176
+ showEmail.value = true
172
177
  }
173
178
  setTimeout(() => {
174
- if (inputs.value.length > 0 && inputs.value[inputs.value.length - 1])
175
- inputs.value[inputs.value.length - 1].focus();
176
- }, 300);
177
- } else {
179
+ if (inputs.value.length > 0 && inputs.value[inputs.value.length - 1]) {
180
+ inputs.value[inputs.value.length - 1].focus()
181
+ }
182
+ }, 300)
183
+ }
184
+ else {
178
185
  //
179
186
  }
180
187
 
181
- eventBus.emit("login-loading", false);
182
- };
188
+ eventBus.emit('login-loading', false)
189
+ }
183
190
 
184
191
  onMounted(async () => {
185
- await userFlow({ initial: true });
186
- });
192
+ await userFlow({ initial: true })
193
+ })
187
194
  </script>
195
+
188
196
  <template>
189
197
  <ClientOnly>
190
198
  <form
191
- @submit.prevent="userFlow()"
192
199
  v-if="!completed"
193
200
  class="fws-login w-full"
201
+ @submit.prevent="userFlow()"
194
202
  >
195
- <!--<FyLoader id="klblogin" />-->
203
+ <!-- <FyLoader id="klblogin" /> -->
196
204
  <div class="w-full">
197
205
  <h2
198
- class="text-lg text-fv-neutral-700 dark:text-fv-neutral-300 px-2"
199
206
  v-if="responseMessage"
207
+ class="text-lg text-fv-neutral-700 dark:text-fv-neutral-300 px-2"
200
208
  >
201
209
  {{ responseMessage }}
202
210
  </h2>
@@ -204,30 +212,31 @@ onMounted(async () => {
204
212
  <div class="flex flex-col gap-2 px-2 justify-center py-2">
205
213
  <template v-for="field of responseFields" :key="field.id">
206
214
  <a
215
+ v-if="field.type && field.type === 'oauth2' && field.button"
216
+ href="javascript:void(0);"
217
+ 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"
218
+ :style="`background: ${
219
+ field.button['background-color']
220
+ }; color: ${$getContrastingTextColor(
221
+ field.button['background-color'],
222
+ )}`"
207
223
  @click="
208
224
  () => {
209
225
  if (field.info.Button_Extra?.trigger) {
210
226
  doTrigger(field);
211
- } else {
227
+ }
228
+ else {
212
229
  userFlow({ initial: true, oauth: field.id });
213
230
  }
214
231
  }
215
232
  "
216
- v-if="field.type && field.type == 'oauth2' && field.button"
217
- href="javascript:void(0);"
218
- 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"
219
- :style="`background: ${
220
- field.button['background-color']
221
- }; color: ${$getContrastingTextColor(
222
- field.button['background-color'],
223
- )}`"
224
233
  >
225
234
  <img
226
235
  :key="`${field.label}oauth`"
227
236
  class="h-12 w-12 block p-2 mr-3"
228
237
  :alt="field.info.Name"
229
238
  :src="field.button.logo"
230
- />
239
+ >
231
240
  <div>
232
241
  {{
233
242
  $t("user_flow_signin_with", {
@@ -255,72 +264,72 @@ onMounted(async () => {
255
264
  }}
256
265
  </div>
257
266
  </button>
258
- </div></template
259
- >
267
+ </div>
268
+ </template>
260
269
  <div
261
- class="px-2 py-2"
262
270
  v-if="forceAction || (showEmail && initial) || !initial"
271
+ class="px-2 py-2"
263
272
  >
264
273
  <template v-if="responseFields && responseFields.length > 0">
265
274
  <template v-for="field of responseFields" :key="field.label">
266
275
  <h3
267
- v-if="field.type == 'label'"
276
+ v-if="field.type === 'label'"
268
277
  class="pt-2 pb-1 text-sm text-fv-neutral-500 dark:text-fv-neutral-400"
269
278
  :class="
270
- field.style == 'error'
279
+ field.style === 'error'
271
280
  ? 'text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300'
272
281
  : ''
273
282
  "
274
283
  >
275
- <a :href="field.link" v-if="field.link" class="fws-link mb-3">{{
284
+ <a v-if="field.link" :href="field.link" class="fws-link mb-3">{{
276
285
  field.label
277
286
  }}</a>
278
- <span class="mb-2" v-else>{{ field.label }}</span>
287
+ <span v-else class="mb-2">{{ field.label }}</span>
279
288
  </h3>
280
289
 
281
- <template v-if="field.cat == 'input'">
290
+ <template v-if="field.cat === 'input'">
282
291
  <template
283
292
  v-if="
284
- field.type == 'text' ||
285
- field.type == 'password' ||
286
- field.type == 'email' ||
287
- field.type == 'mask'
293
+ field.type === 'text'
294
+ || field.type === 'password'
295
+ || field.type === 'email'
296
+ || field.type === 'mask'
288
297
  "
289
298
  >
290
299
  <DefaultInput
291
300
  v-if="field.name"
292
301
  :id="field.name"
302
+ ref="inputs"
303
+ v-model="formData[field.name]"
293
304
  :label="field.label"
294
305
  :mask="field.mask"
295
306
  class="mt-3"
296
307
  :placeholder="
297
- field.name == 'name' ? 'John Doe' : field.label
308
+ field.name === 'name' ? 'John Doe' : field.label
298
309
  "
299
310
  :error="fieldsError[field.name]"
300
311
  :type="field.type"
301
- ref="inputs"
302
- v-model="formData[field.name]"
303
312
  :req="responseReq.includes(field.name)"
304
313
  />
305
314
  </template>
306
315
  </template>
307
- <template v-if="field.type == 'checkbox'">
316
+ <template v-if="field.type === 'checkbox'">
308
317
  <DefaultInput
309
318
  v-if="field.name"
310
319
  :id="field.name"
320
+ v-model:checkbox-value="formData[field.name]"
311
321
  class="mt-3"
312
322
  :label="field.label"
313
323
  :error="fieldsError[field.name]"
314
324
  :type="field.type"
315
- v-model:checkbox-value="formData[field.name]"
316
325
  :req="responseReq.includes(field.name)"
317
326
  :link-icon="field.link"
318
327
  />
319
328
  </template>
320
329
  </template>
321
330
  <div
322
- class="text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300"
323
331
  v-if="responseError && responseError.token"
332
+ class="text-sm my-2 p-1 font-semibold text-red-800 dark:text-red-300"
324
333
  >
325
334
  {{ $t(responseError.token) }}
326
335
  </div>
@@ -333,8 +342,7 @@ onMounted(async () => {
333
342
  pwdRecoverMailSent = false;
334
343
  }
335
344
  "
336
- >{{ $t("recover_pwd_link") }}</a
337
- >
345
+ >{{ $t("recover_pwd_link") }}</a>
338
346
  </div>
339
347
  <button class="btn primary medium mt-4">
340
348
  {{ $t("cta_login_next") }}