@live-change/user-frontend 0.9.177 → 0.9.179

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.
@@ -235,5 +235,62 @@
235
235
  "openLink": "Or open authentication link:",
236
236
  "seeYouSoon": "See you soon",
237
237
  "teamSignature": "{brandName} Team"
238
+ },
239
+ "googleAuth": {
240
+ "title": "Google authentication",
241
+ "canceled": "Authentication canceled by user",
242
+ "waiting": "Waiting for server...",
243
+ "waitingForRedirect": "Authentication will open in this window.",
244
+ "error": "Error during authentication",
245
+ "errorWithColon": "Error during authentication:",
246
+ "unknownState": "Unknown authentication state: {state}",
247
+ "emailTaken": "Your account was created using email address. If you want to connect your Google account, you need to sign in with this email address. And connect your Google account using {link}.",
248
+ "emailTakenLink": "connected accounts page",
249
+ "invalidGrant": "Invalid grant. Please try again. You may used this link before, or google authentication failed.",
250
+ "connectedToAnotherUser": "This account is already connected to another user. Please sign in with your email address or google account.",
251
+ "emailAlreadyInUse": "Email is already in use",
252
+ "invalidGrantToast": "Invalid grant",
253
+ "connectedToAnotherUserToast": "Connected to another user",
254
+ "errorToast": "Error during google authentication"
255
+ },
256
+ "linkedinAuth": {
257
+ "title": "Linkedin authentication",
258
+ "canceled": "Authentication canceled by user",
259
+ "waiting": "Waiting for server...",
260
+ "waitingForRedirect": "Authentication will open in this window.",
261
+ "error": "Error during authentication",
262
+ "errorWithColon": "Error during authentication:",
263
+ "unknownState": "Unknown authentication state: {state}",
264
+ "errorToast": "Error during linkedin authentication"
265
+ },
266
+ "googleAccess": {
267
+ "title": "Google API Access",
268
+ "currentAccess": "You are currently granting us access to the following Google API features:",
269
+ "needAccess": "To use this feature, you need to grant us access to the Google APIs listed below:",
270
+ "clickButton": "Click the button below to go to the Google page where you can grant access.",
271
+ "authenticationButton": "Google Authentication",
272
+ "gainedTitle": "Signed In",
273
+ "gainedMessage": "Congratulations! You added offline access to your account. Now your account have access to:",
274
+ "next": "Next",
275
+ "redirectIn": "Redirect in {seconds}...",
276
+ "returnToIndex": "Return to {link}.",
277
+ "indexPage": "index page",
278
+ "signedInToast": "Signed in",
279
+ "signedInToastDetail": "Congratulations! You have successfully logged in to your account."
280
+ },
281
+ "password": {
282
+ "suggestions": "Suggestions",
283
+ "resetPasswordButton": "Reset password"
284
+ },
285
+ "common": {
286
+ "rememberMe": "Remember me"
287
+ },
288
+ "signOut": {
289
+ "title": "Sign Out",
290
+ "signingOut": "Signing out"
291
+ },
292
+ "connected": {
293
+ "accountConnected": "Account connected",
294
+ "accountConnectedSuccess": "Congratulations! You have successfully connected accounts."
238
295
  }
239
296
  }
@@ -235,5 +235,62 @@
235
235
  "openLink": "Lub otwórz link uwierzytelniania:",
236
236
  "seeYouSoon": "Do zobaczenia",
237
237
  "teamSignature": "Zespół {brandName}"
238
+ },
239
+ "googleAuth": {
240
+ "title": "Uwierzytelnianie Google",
241
+ "canceled": "Uwierzytelnianie anulowane przez użytkownika",
242
+ "waiting": "Oczekiwanie na serwer...",
243
+ "waitingForRedirect": "Uwierzytelnianie otworzy się w tym oknie.",
244
+ "error": "Błąd podczas uwierzytelniania",
245
+ "errorWithColon": "Błąd podczas uwierzytelniania:",
246
+ "unknownState": "Nieznany stan uwierzytelniania: {state}",
247
+ "emailTaken": "Twoje konto zostało utworzone przy użyciu adresu email. Jeśli chcesz połączyć swoje konto Google, musisz zalogować się tym adresem email. I połączyć swoje konto Google używając {link}.",
248
+ "emailTakenLink": "strony połączonych kont",
249
+ "invalidGrant": "Nieprawidłowy grant. Spróbuj ponownie. Możesz użyć tego linku wcześniej lub uwierzytelnianie Google nie powiodło się.",
250
+ "connectedToAnotherUser": "To konto jest już połączone z innym użytkownikiem. Zaloguj się swoim adresem email lub kontem Google.",
251
+ "emailAlreadyInUse": "Email jest już w użyciu",
252
+ "invalidGrantToast": "Nieprawidłowy grant",
253
+ "connectedToAnotherUserToast": "Połączone z innym użytkownikiem",
254
+ "errorToast": "Błąd podczas uwierzytelniania Google"
255
+ },
256
+ "linkedinAuth": {
257
+ "title": "Uwierzytelnianie LinkedIn",
258
+ "canceled": "Uwierzytelnianie anulowane przez użytkownika",
259
+ "waiting": "Oczekiwanie na serwer...",
260
+ "waitingForRedirect": "Uwierzytelnianie otworzy się w tym oknie.",
261
+ "error": "Błąd podczas uwierzytelniania",
262
+ "errorWithColon": "Błąd podczas uwierzytelniania:",
263
+ "unknownState": "Nieznany stan uwierzytelniania: {state}",
264
+ "errorToast": "Błąd podczas uwierzytelniania LinkedIn"
265
+ },
266
+ "googleAccess": {
267
+ "title": "Dostęp do Google API",
268
+ "currentAccess": "Obecnie udzielasz nam dostępu do następujących funkcji Google API:",
269
+ "needAccess": "Aby użyć tej funkcji, musisz udzielić nam dostępu do wymienionych poniżej Google API:",
270
+ "clickButton": "Kliknij przycisk poniżej, aby przejść do strony Google, gdzie możesz udzielić dostępu.",
271
+ "authenticationButton": "Uwierzytelnianie Google",
272
+ "gainedTitle": "Zalogowany",
273
+ "gainedMessage": "Gratulacje! Dodałeś dostęp offline do swojego konta. Teraz Twoje konto ma dostęp do:",
274
+ "next": "Dalej",
275
+ "redirectIn": "Przekierowanie za {seconds}...",
276
+ "returnToIndex": "Wróć do {link}.",
277
+ "indexPage": "strony głównej",
278
+ "signedInToast": "Zalogowany",
279
+ "signedInToastDetail": "Gratulacje! Pomyślnie zalogowałeś się do swojego konta."
280
+ },
281
+ "password": {
282
+ "suggestions": "Sugestie",
283
+ "resetPasswordButton": "Resetuj hasło"
284
+ },
285
+ "common": {
286
+ "rememberMe": "Zapamiętaj mnie"
287
+ },
288
+ "signOut": {
289
+ "title": "Wyloguj się",
290
+ "signingOut": "Wylogowywanie"
291
+ },
292
+ "connected": {
293
+ "accountConnected": "Konto połączone",
294
+ "accountConnectedSuccess": "Gratulacje! Pomyślnie połączyłeś konta."
238
295
  }
239
296
  }
@@ -1,14 +1,15 @@
1
1
  <template>
2
2
  <div class="w-full lg:w-6/12 md:w-9/12 max-w-[32rem]" v-shared-element:form="{ duration: '300ms', includeChildren: true }">
3
3
  <div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6">
4
- <div class="text-surface-900 dark:text-surface-0 font-medium mb-6 text-xl">Account connected</div>
5
- <div class="mt-0 p-0 leading-normal">Congratulations! You have successfully connected accounts.</div>
4
+ <div class="text-surface-900 dark:text-surface-0 font-medium mb-6 text-xl">{{ t('connected.accountConnected') }}</div>
5
+ <div class="mt-0 p-0 leading-normal">{{ t('connected.accountConnectedSuccess') }}</div>
6
6
  </div>
7
7
  </div>
8
8
  </template>
9
9
 
10
10
  <script setup>
11
-
11
+ import { useI18n } from 'vue-i18n'
12
+ const { t } = useI18n()
12
13
  </script>
13
14
 
14
15
  <style>
@@ -152,12 +152,12 @@
152
152
 
153
153
  await Promise.all([ ...contactPromises, ...accountPromises ])
154
154
 
155
- const contacts = computed(() => contactsTypes.map((c,i) => c.contacts.value.map(v => ({
155
+ const contacts = computed(() => contactsTypes.map((c,i) => (c.contacts.value || []).map(v => ({
156
156
  contactType: c,
157
157
  ...(v)
158
158
  }))).flat())
159
159
 
160
- const accounts = computed(() => accountTypes.map((c,i) => c.accounts.value.map(v => ({
160
+ const accounts = computed(() => accountTypes.map((c,i) => (c.accounts.value || []).map(v => ({
161
161
  accountType: c,
162
162
  ...(v)
163
163
  }))).flat())
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <div v-if="additionalScopes.length > 0" class="w-full flex flex-row justify-center">
3
3
  <div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6 w-[30rem]">
4
- <div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">Google API Access</div>
4
+ <div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">{{ t('googleAccess.title') }}</div>
5
5
  <div v-if="currentAccess.length > 0">
6
6
  <p class="mt-0 p-0 leading-normal">
7
- You are currently granting us access to the following Google API features:
7
+ {{ t('googleAccess.currentAccess') }}
8
8
  </p>
9
9
  <ul>
10
10
  <li v-for="scope in currentAccess">
@@ -14,7 +14,7 @@
14
14
  </div>
15
15
  <div>
16
16
  <p>
17
- To use this feature, you need to grant us access to the Google APIs listed below:
17
+ {{ t('googleAccess.needAccess') }}
18
18
  </p>
19
19
  <ul>
20
20
  <li v-for="scope in additionalScopes" class="font-semibold text-gray-700">
@@ -22,7 +22,7 @@
22
22
  </li>
23
23
  </ul>
24
24
  <p>
25
- Click the button below to go to the Google page where you can grant access.
25
+ {{ t('googleAccess.clickButton') }}
26
26
  </p>
27
27
  </div>
28
28
  <router-link
@@ -32,7 +32,7 @@
32
32
  accessType: 'offline',
33
33
  scopes: allScopes
34
34
  } }">
35
- <Button icon="pi pi-key" label="Google Authentication" />
35
+ <Button icon="pi pi-key" :label="t('googleAccess.authenticationButton')" />
36
36
  </router-link>
37
37
  </div>
38
38
  </div>
@@ -43,6 +43,9 @@
43
43
 
44
44
  import Button from 'primevue/button'
45
45
 
46
+ import { useI18n } from 'vue-i18n'
47
+ const { t } = useI18n()
48
+
46
49
  import { onMounted, ref } from 'vue'
47
50
  const isMounted = ref(false)
48
51
  onMounted(() => isMounted.value = true)
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
  <div class="w-full lg:w-6/12 md:w-9/12 max-w-[32rem]" v-shared-element:form="{ duration: '300ms', includeChildren: true }">
3
3
  <div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6">
4
- <div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">Signed In</div>
4
+ <div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">{{ t('googleAccess.gainedTitle') }}</div>
5
5
  <p class="mt-0 p-0 leading-normal">
6
- Congratulations! You added offline access to your account. Now your account have access to:
6
+ {{ t('googleAccess.gainedMessage') }}
7
7
  <ul>
8
8
  <li v-for="access in accessList">
9
9
  {{ access }}
@@ -13,14 +13,18 @@
13
13
  </p>
14
14
  <div v-if="afterGoogleAccessGained" class="flex flex-row items-center">
15
15
  <router-link :to="afterGoogleAccessGained" class="no-underline">
16
- <Button label="Next" v-ripple />
16
+ <Button :label="t('googleAccess.next')" v-ripple />
17
17
  </router-link>
18
18
  <p class="ml-6" v-if="isMounted && redirectTime">
19
- Redirect in {{ pluralize('second', Math.ceil((redirectTime - currentTime) / 1000), true) }}...
19
+ {{ t('googleAccess.redirectIn', { seconds: pluralize('second', Math.ceil((redirectTime - currentTime) / 1000), true) }) }}
20
20
  </p>
21
21
  </div>
22
22
  <div v-else>
23
- Return to <router-link to="/">index page</router-link>.
23
+ <i18n-t keypath="googleAccess.returnToIndex" tag="span">
24
+ <template #link>
25
+ <router-link to="/">{{ t('googleAccess.indexPage') }}</router-link>
26
+ </template>
27
+ </i18n-t>
24
28
  </div>
25
29
  </div>
26
30
  </div>
@@ -30,6 +34,9 @@
30
34
 
31
35
  import Button from 'primevue/button'
32
36
 
37
+ import { useI18n } from 'vue-i18n'
38
+ const { t } = useI18n()
39
+
33
40
  import { onMounted, ref } from 'vue'
34
41
  const isMounted = ref(false)
35
42
  onMounted(() => isMounted.value = true)
@@ -43,6 +50,9 @@
43
50
  import { usePath, live, useApi } from "@live-change/vue3-ssr"
44
51
  const api = useApi()
45
52
 
53
+ import { useToast } from 'primevue/usetoast'
54
+ const toast = useToast()
55
+
46
56
  const userClientConfig = api.getServiceDefinition('user')?.clientConfig
47
57
 
48
58
  import pluralize from 'pluralize'
@@ -68,8 +78,8 @@
68
78
  setTimeout(() => { // it could be next tick
69
79
  toast.add({
70
80
  severity: 'info', life: 6000,
71
- summary: 'Signed in',
72
- detail: 'Congratulations! You have successfully logged in to your account.'
81
+ summary: t('googleAccess.signedInToast'),
82
+ detail: t('googleAccess.signedInToastDetail')
73
83
  })
74
84
  router.push(route)
75
85
  }, 100)
@@ -33,12 +33,12 @@
33
33
  v-model="data.passwordHash">
34
34
  <template #footer>
35
35
  <Divider />
36
- <p class="p-mt-2">Suggestions</p>
36
+ <p class="p-mt-2">{{ t('password.suggestions') }}</p>
37
37
  <ul class="p-pl-2 p-ml-2 p-mt-0" style="line-height: 1.5">
38
- <li>At least one lowercase</li>
39
- <li>At least one uppercase</li>
40
- <li>At least one numeric</li>
41
- <li>Minimum 8 characters</li>
38
+ <li>{{ t('auth.suggestionLowercase') }}</li>
39
+ <li>{{ t('auth.suggestionUppercase') }}</li>
40
+ <li>{{ t('auth.suggestionNumeric') }}</li>
41
+ <li>{{ t('auth.suggestionMinLength') }}</li>
42
42
  </ul>
43
43
  </template>
44
44
  </Password>
@@ -56,7 +56,7 @@
56
56
 
57
57
  </template>
58
58
 
59
- <Button type="submit" label="Reset password" icon="pi pi-key" class="w-full"></Button>
59
+ <Button type="submit" :label="t('password.resetPasswordButton')" icon="pi pi-key" class="w-full"></Button>
60
60
 
61
61
  </command-form>
62
62
  </div>
@@ -3,28 +3,28 @@
3
3
  <div class="bg-surface-0 dark:bg-surface-900 p-6 shadow rounded-border">
4
4
 
5
5
  <div class="text-center mb-8">
6
- <div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">Google authentication</div>
6
+ <div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">{{ t('googleAuth.title') }}</div>
7
7
  </div>
8
8
 
9
9
  <div v-if="state === 'canceled'" class="text-center">
10
- <div>Authentication canceled by user</div>
10
+ <div>{{ t('googleAuth.canceled') }}</div>
11
11
  <div class="flex flex-row">
12
- <Button @click="back" label="Go back" icon="pi pi-arrow-left" class="w-full p-button-secondary mb-1" />
13
- <Button @click="googleAuth" label="Try again" icon="pi pi-google" class="w-full p-button-secondary mb-1" />
12
+ <Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left" class="w-full p-button-secondary mb-1" />
13
+ <Button @click="googleAuth" :label="t('auth.tryAgain')" icon="pi pi-google" class="w-full p-button-secondary mb-1" />
14
14
  </div>
15
15
  </div>
16
16
  <div v-else-if="state === 'waiting'" class="text-center">
17
- Authentication will open in this window.
17
+ {{ t('googleAuth.waitingForRedirect') }}
18
18
  </div>
19
19
  <div v-else-if="state === 'working'" class="text-center">
20
- Waiting for server...
20
+ {{ t('googleAuth.waiting') }}
21
21
  </div>
22
22
  <div v-else-if="state === 'error'" class="text-center">
23
- <div>Error during authentication:</div>
23
+ <div>{{ t('googleAuth.errorWithColon') }}</div>
24
24
  <div>{{ error }}</div>
25
25
  </div>
26
26
  <div v-else>
27
- Unknown authentication state: {{ state }}
27
+ {{ t('googleAuth.unknownState', { state }) }}
28
28
  </div>
29
29
 
30
30
  </div>
@@ -37,6 +37,9 @@
37
37
  import { useRouter } from 'vue-router'
38
38
  const router = useRouter()
39
39
 
40
+ import { useI18n } from 'vue-i18n'
41
+ const { t } = useI18n()
42
+
40
43
  const workingZone = inject('workingZone')
41
44
 
42
45
  import { googleAuthRedirect } from '../utils/googleAuth.js'
@@ -66,6 +69,8 @@
66
69
  function googleAuth() {
67
70
  state.value = 'waiting'
68
71
 
72
+ localStorage.googleAuthScopes = JSON.stringify(scopes.value)
73
+
69
74
  workingZone.addPromise('google auth', new Promise((resolve, reject) => {
70
75
  setTimeout(() => {
71
76
  state.value = 'error'
@@ -3,32 +3,48 @@
3
3
  <div class="bg-surface-0 dark:bg-surface-900 p-6 shadow rounded-border">
4
4
 
5
5
  <div class="text-center mb-8">
6
- <div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">Google authentication</div>
6
+ <div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">{{ t('googleAuth.title') }}</div>
7
7
  </div>
8
8
 
9
9
  <div v-if="state === 'canceled'" class="text-center">
10
- <div>Authentication canceled by user</div>
10
+ <div>{{ t('googleAuth.canceled') }}</div>
11
11
  <div class="flex flex-row">
12
- <Button @click="back" label="Go back" icon="pi pi-arrow-left"
12
+ <Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left"
13
13
  class="w-full p-button-secondary mb-1" />
14
14
  </div>
15
15
  </div>
16
16
  <div v-else-if="state === 'working'" class="text-center">
17
- Waiting for server...
17
+ {{ t('googleAuth.waiting') }}
18
18
  </div>
19
19
  <div v-else-if="state === 'error'" class="text-center">
20
- <div>Error during authentication</div>
20
+ <div>{{ t('googleAuth.error') }}</div>
21
21
  <div>{{ error }}</div>
22
22
  </div>
23
23
  <div v-else-if="state === 'emailTaken'" class="text-center">
24
24
  <div>
25
- Your account was created using email address. If you want to connect your Google account,
26
- you need to sign in with this email address. And connect your Google account using
27
- <router-link :to="{ name: 'user:connected' }">connected accounts page</router-link>.
25
+ <i18n-t keypath="googleAuth.emailTaken" tag="span">
26
+ <template #link>
27
+ <router-link :to="{ name: 'user:connected' }">{{ t('googleAuth.emailTakenLink') }}</router-link>
28
+ </template>
29
+ </i18n-t>
30
+ </div>
31
+ </div>
32
+ <div v-else-if="state === 'invalidGrant'" class="text-center">
33
+ <div>
34
+ {{ t('googleAuth.invalidGrant') }}
35
+ <div class="flex flex-row">
36
+ <Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left" class="w-full p-button-secondary mb-1" />
37
+ <Button @click="googleAuth" :label="t('auth.tryAgain')" icon="pi pi-google" class="w-full p-button-secondary mb-1" />
38
+ </div>
39
+ </div>
40
+ </div>
41
+ <div v-else-if="state === 'connectedToAnotherUser'" class="text-center">
42
+ <div>
43
+ {{ t('googleAuth.connectedToAnotherUser') }}
28
44
  </div>
29
45
  </div>
30
46
  <div v-else>
31
- Unknown authentication state: {{ state }}
47
+ {{ t('googleAuth.unknownState', { state }) }}
32
48
  </div>
33
49
 
34
50
  </div>
@@ -44,6 +60,9 @@
44
60
  import { useToast } from 'primevue/usetoast'
45
61
  const toast = useToast()
46
62
 
63
+ import { useI18n } from 'vue-i18n'
64
+ const { t } = useI18n()
65
+
47
66
  const workingZone = inject('workingZone')
48
67
 
49
68
  import { useRouter, useRoute } from 'vue-router'
@@ -81,6 +100,7 @@
81
100
  while(user && api.client.value.user !== user) {
82
101
  await new Promise(resolve => setTimeout(resolve, 100))
83
102
  }
103
+ localStorage.removeItem('googleAuthScopes')
84
104
  if(actionDone === 'signIn') {
85
105
  router.push({ name: 'user:signInFinished' })
86
106
  } else if(actionDone === 'signUp') {
@@ -94,12 +114,22 @@
94
114
  }
95
115
  } catch(err) {
96
116
  if(err?.properties?.email == 'emailTaken') {
97
- toast.add({ severity: 'error', summary: 'Error', detail: 'Email is already in use', life: 3000 })
117
+ toast.add({ severity: 'error', summary: t('common.error'), detail: t('googleAuth.emailAlreadyInUse'), life: 3000 })
98
118
  state.value = 'emailTaken'
99
119
  return
100
120
  }
121
+ if((typeof err == 'string') && err.startsWith('invalid_grant')) {
122
+ toast.add({ severity: 'error', summary: t('common.error'), detail: t('googleAuth.invalidGrantToast'), life: 3000 })
123
+ state.value = 'invalidGrant'
124
+ return
125
+ }
126
+ if(err === 'connectedToAnotherUser') {
127
+ toast.add({ severity: 'error', summary: t('common.error'), detail: t('googleAuth.connectedToAnotherUserToast'), life: 3000 })
128
+ state.value = 'connectedToAnotherUser'
129
+ return
130
+ }
101
131
  console.error("Google auth error", err)
102
- toast.add({ severity: 'error', summary: 'Error', detail: 'Error during google authentication', life: 3000 })
132
+ toast.add({ severity: 'error', summary: t('common.error'), detail: t('googleAuth.errorToast'), life: 3000 })
103
133
  state.value = 'error'
104
134
  error.value = err
105
135
  }
@@ -110,6 +140,15 @@
110
140
  router.go(-1)
111
141
  }
112
142
 
143
+ async function googleAuth() {
144
+ if(localStorage.googleAuthScopes) {
145
+ const scopes = JSON.parse(localStorage.googleAuthScopes)
146
+ router.push({ name: 'user:googleAuthScopes', params: { action: action.value, accessType: 'offline', scopes: scopes } })
147
+ } else {
148
+ router.push({ name: 'user:googleAuth', params: { action: action.value } })
149
+ }
150
+ }
151
+
113
152
  </script>
114
153
 
115
154
  <style scoped>
@@ -3,28 +3,28 @@
3
3
  <div class="bg-surface-0 dark:bg-surface-900 p-6 shadow rounded-border">
4
4
 
5
5
  <div class="text-center mb-8">
6
- <div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">Linkedin authentication</div>
6
+ <div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">{{ t('linkedinAuth.title') }}</div>
7
7
  </div>
8
8
 
9
9
  <div v-if="state === 'canceled'" class="text-center">
10
- <div class="mb-1">Authentication canceled by user</div>
10
+ <div class="mb-1">{{ t('linkedinAuth.canceled') }}</div>
11
11
  <div class="flex flex-row">
12
- <Button @click="back" label="Go back" icon="pi pi-arrow-left" class="w-full p-button-secondary mb-1" />
13
- <Button @click="linkedinAuth" label="Try again" icon="pi pi-linkedin" class="w-full p-button-secondary mb-1" />
12
+ <Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left" class="w-full p-button-secondary mb-1" />
13
+ <Button @click="linkedinAuth" :label="t('auth.tryAgain')" icon="pi pi-linkedin" class="w-full p-button-secondary mb-1" />
14
14
  </div>
15
15
  </div>
16
16
  <div v-else-if="state === 'waiting'" class="text-center">
17
- Authentication will open in this window.
17
+ {{ t('linkedinAuth.waitingForRedirect') }}
18
18
  </div>
19
19
  <div v-else-if="state === 'working'" class="text-center">
20
- Waiting for server...
20
+ {{ t('linkedinAuth.waiting') }}
21
21
  </div>
22
22
  <div v-else-if="state === 'error'" class="text-center">
23
- <div>Error during authentication:</div>
23
+ <div>{{ t('linkedinAuth.errorWithColon') }}</div>
24
24
  <div>{{ error }}</div>
25
25
  </div>
26
26
  <div v-else>
27
- Unknown authentication state: {{ state }}
27
+ {{ t('linkedinAuth.unknownState', { state }) }}
28
28
  </div>
29
29
 
30
30
  </div>
@@ -37,6 +37,9 @@
37
37
  import { useRouter } from 'vue-router'
38
38
  const router = useRouter()
39
39
 
40
+ import { useI18n } from 'vue-i18n'
41
+ const { t } = useI18n()
42
+
40
43
  const workingZone = inject('workingZone')
41
44
 
42
45
  import { linkedinAuthRedirect } from '../utils/linkedinAuth.js'
@@ -3,25 +3,25 @@
3
3
  <div class="bg-surface-0 dark:bg-surface-900 p-6 shadow rounded-border">
4
4
 
5
5
  <div class="text-center mb-8">
6
- <div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">Linkedin authentication</div>
6
+ <div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">{{ t('linkedinAuth.title') }}</div>
7
7
  </div>
8
8
 
9
9
  <div v-if="state === 'canceled'" class="text-center">
10
- <div class="mb-2 text-red-500">Authentication canceled by user</div>
10
+ <div class="mb-2 text-red-500">{{ t('linkedinAuth.canceled') }}</div>
11
11
  <div class="flex flex-row">
12
- <Button @click="back" label="Go back" icon="pi pi-arrow-left"
12
+ <Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left"
13
13
  class="w-full p-button-secondary mb-1" />
14
14
  </div>
15
15
  </div>
16
16
  <div v-else-if="state === 'working'" class="text-center">
17
- Waiting for server...
17
+ {{ t('linkedinAuth.waiting') }}
18
18
  </div>
19
19
  <div v-else-if="state === 'error'" class="text-center">
20
- <div>Error during authentication</div>
20
+ <div>{{ t('linkedinAuth.error') }}</div>
21
21
  <div>{{ error }}</div>
22
22
  </div>
23
23
  <div v-else>
24
- Unknown authentication state: {{ state }}
24
+ {{ t('linkedinAuth.unknownState', { state }) }}
25
25
  </div>
26
26
 
27
27
  </div>
@@ -37,6 +37,9 @@
37
37
  import { useToast } from 'primevue/usetoast'
38
38
  const toast = useToast()
39
39
 
40
+ import { useI18n } from 'vue-i18n'
41
+ const { t } = useI18n()
42
+
40
43
  const workingZone = inject('workingZone')
41
44
 
42
45
  import { useRouter, useRoute } from 'vue-router'
@@ -88,7 +91,7 @@
88
91
  }
89
92
  } catch(error) {
90
93
  console.error("Linkedin auth error", error)
91
- toast.add({ severity: 'error', summary: 'Error', detail: 'Error during linkedin authentication', life: 3000 })
94
+ toast.add({ severity: 'error', summary: t('common.error'), detail: t('linkedinAuth.errorToast'), life: 3000 })
92
95
  state.value = 'error'
93
96
  error.value = error
94
97
  }
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <div class="w-full lg:w-6/12 md:w-9/12 max-w-[32rem]" v-shared-element:form="{ duration: '300ms', includeChildren: true }">
3
3
  <div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6">
4
- <div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">Sign Out</div>
5
- <p class="mt-0 p-0 leading-normal">Signing out</p>
4
+ <div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">{{ t('signOut.title') }}</div>
5
+ <p class="mt-0 p-0 leading-normal">{{ t('signOut.signingOut') }}</p>
6
6
  <ProgressSpinner v-if="isMounted" class="m-4" />
7
7
  </div>
8
8
  </div>
@@ -11,6 +11,9 @@
11
11
  <script setup>
12
12
  import ProgressSpinner from "primevue/progressspinner"
13
13
 
14
+ import { useI18n } from 'vue-i18n'
15
+ const { t } = useI18n()
16
+
14
17
  import { onMounted, ref } from 'vue'
15
18
  const isMounted = ref(false)
16
19
  onMounted(() => isMounted.value = true)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/user-frontend",
3
- "version": "0.9.177",
3
+ "version": "0.9.179",
4
4
  "scripts": {
5
5
  "memDev": "tsx --inspect --expose-gc server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
6
6
  "localDevInit": "tsx server/start.js localDev --enableSessions --initScript ./init.js --dbAccess",
@@ -36,29 +36,29 @@
36
36
  },
37
37
  "type": "module",
38
38
  "dependencies": {
39
- "@live-change/cli": "^0.9.177",
40
- "@live-change/dao": "^0.9.177",
41
- "@live-change/dao-vue3": "^0.9.177",
42
- "@live-change/dao-websocket": "^0.9.177",
43
- "@live-change/email-service": "^0.9.177",
44
- "@live-change/framework": "^0.9.177",
45
- "@live-change/identicon-service": "^0.9.177",
46
- "@live-change/image-frontend": "^0.9.177",
47
- "@live-change/message-authentication-service": "^0.9.177",
48
- "@live-change/notification-service": "^0.9.177",
49
- "@live-change/password-authentication-service": "^0.9.177",
50
- "@live-change/pattern": "^0.9.177",
51
- "@live-change/secret-code-service": "^0.9.177",
52
- "@live-change/secret-link-service": "^0.9.177",
53
- "@live-change/security-frontend": "^0.9.177",
54
- "@live-change/security-service": "^0.9.177",
55
- "@live-change/session-service": "^0.9.177",
56
- "@live-change/timer-service": "^0.9.177",
57
- "@live-change/upload-service": "^0.9.177",
58
- "@live-change/user-identification-service": "^0.9.177",
59
- "@live-change/user-service": "^0.9.177",
60
- "@live-change/vue3-components": "^0.9.177",
61
- "@live-change/vue3-ssr": "^0.9.177",
39
+ "@live-change/cli": "^0.9.179",
40
+ "@live-change/dao": "^0.9.179",
41
+ "@live-change/dao-vue3": "^0.9.179",
42
+ "@live-change/dao-websocket": "^0.9.179",
43
+ "@live-change/email-service": "^0.9.179",
44
+ "@live-change/framework": "^0.9.179",
45
+ "@live-change/identicon-service": "^0.9.179",
46
+ "@live-change/image-frontend": "^0.9.179",
47
+ "@live-change/message-authentication-service": "^0.9.179",
48
+ "@live-change/notification-service": "^0.9.179",
49
+ "@live-change/password-authentication-service": "^0.9.179",
50
+ "@live-change/pattern": "^0.9.179",
51
+ "@live-change/secret-code-service": "^0.9.179",
52
+ "@live-change/secret-link-service": "^0.9.179",
53
+ "@live-change/security-frontend": "^0.9.179",
54
+ "@live-change/security-service": "^0.9.179",
55
+ "@live-change/session-service": "^0.9.179",
56
+ "@live-change/timer-service": "^0.9.179",
57
+ "@live-change/upload-service": "^0.9.179",
58
+ "@live-change/user-identification-service": "^0.9.179",
59
+ "@live-change/user-service": "^0.9.179",
60
+ "@live-change/vue3-components": "^0.9.179",
61
+ "@live-change/vue3-ssr": "^0.9.179",
62
62
  "@vueuse/core": "^12.3.0",
63
63
  "codeceptjs-assert": "^0.0.5",
64
64
  "codeceptjs-video-helper": "0.1.3",
@@ -79,7 +79,7 @@
79
79
  "wtfnode": "^0.9.1"
80
80
  },
81
81
  "devDependencies": {
82
- "@live-change/codeceptjs-helper": "^0.9.177",
82
+ "@live-change/codeceptjs-helper": "^0.9.179",
83
83
  "codeceptjs": "^3.6.10",
84
84
  "generate-password": "1.7.1",
85
85
  "playwright": "1.49.1",
@@ -90,5 +90,5 @@
90
90
  "author": "Michał Łaszczewski <michal@laszczewski.pl>",
91
91
  "license": "BSD-3-Clause",
92
92
  "description": "",
93
- "gitHead": "d75c8c63935b7b78623248d255820b1da2676929"
93
+ "gitHead": "060955f28289df05d8f7da24191e42f5840c2e6b"
94
94
  }