adata-ui 2.0.24 → 2.0.26

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 (35) hide show
  1. package/.nuxtrc +1 -1
  2. package/.playground/app.config.ts +5 -5
  3. package/README.md +75 -75
  4. package/components/elements/README.md +1 -1
  5. package/components/forms/README.md +1 -1
  6. package/components/modals/AConfirmationEmail.vue +40 -40
  7. package/components/modals/ContentNavigationModal.vue +38 -32
  8. package/components/modals/Resend.vue +81 -81
  9. package/components/modals/id/IdConfirmAccountOtpModal.vue +147 -0
  10. package/components/modals/id/IdConfirmSuccessfulModal.vue +25 -0
  11. package/components/modals/id/IdLoginModal.vue +150 -131
  12. package/components/modals/id/IdModals.vue +41 -7
  13. package/components/modals/id/IdNewPasswordModal.vue +55 -62
  14. package/components/modals/id/IdPasswordSuccessfulModal.vue +15 -16
  15. package/components/modals/id/IdRecoveryModal.vue +39 -34
  16. package/components/modals/id/IdRegistrationModal.vue +75 -103
  17. package/components/modals/id/IdResetPasswordOtpModal.vue +154 -0
  18. package/components/modals/two-factor/otp-input.vue +1 -1
  19. package/components/navigation/README.md +1 -1
  20. package/components/overlays/README.md +1 -1
  21. package/composables/useIdModals.ts +10 -2
  22. package/icons/chart-pie.vue +16 -0
  23. package/icons/google.vue +41 -41
  24. package/icons/linkedin.vue +24 -24
  25. package/icons/mailru.vue +34 -34
  26. package/icons/sun.vue +14 -14
  27. package/icons/work-case.vue +9 -0
  28. package/icons/yandex.vue +28 -28
  29. package/lang/ru.ts +16 -5
  30. package/layouts/default.vue +13 -13
  31. package/nuxt.config.ts +1 -0
  32. package/package.json +3 -1
  33. package/stores/auth.store.ts +12 -0
  34. package/components/modals/Accept.vue +0 -45
  35. package/components/modals/id/IdEmailModal.vue +0 -29
@@ -1,11 +1,15 @@
1
1
  <script setup lang="ts">
2
+ import { useAuthStore } from '#adata-ui/stores/auth.store'
2
3
  import * as z from 'zod'
3
4
 
4
5
  const { $toast } = useNuxtApp()
5
6
  const { commonAuth } = useAppConfig()
6
7
  const { t, locale } = useI18n()
7
8
 
8
- const { recoveryModal, emailModal } = useIdModals()
9
+ const authStore = useAuthStore()
10
+ const { intermediateState } = storeToRefs(authStore)
11
+
12
+ const { recoveryModal, resetPasswordOtpModal } = useIdModals()
9
13
  const authApiURL = commonAuth.authApiURL
10
14
  const emailField = ref('')
11
15
  const loading = ref(false)
@@ -31,7 +35,7 @@ async function onSubmit() {
31
35
  if (validation.value) return
32
36
  loading.value = true
33
37
 
34
- await $fetch(`${authApiURL}/password/email`, {
38
+ await $fetch(`${authApiURL}/password/email-otp`, {
35
39
  method: 'POST',
36
40
  credentials: 'include',
37
41
  headers: {
@@ -41,8 +45,10 @@ async function onSubmit() {
41
45
  email: emailField.value,
42
46
  },
43
47
  })
48
+ intermediateState.value.email = emailField.value
49
+
44
50
  recoveryModal.value = false
45
- emailModal.value = true
51
+ resetPasswordOtpModal.value = true
46
52
  }
47
53
  catch (error) {
48
54
  $toast.error(error.data.message)
@@ -51,6 +57,7 @@ async function onSubmit() {
51
57
  loading.value = false
52
58
  }
53
59
  }
60
+
54
61
  function handleEnter(e: KeyboardEvent) {
55
62
  if (e.key === 'Enter') {
56
63
  onSubmit()
@@ -77,38 +84,36 @@ onBeforeUnmount(() => {
77
84
  </script>
78
85
 
79
86
  <template>
80
- <a-modal v-model="recoveryModal">
81
- <form
82
- class="flex flex-col items-stretch gap-5 rounded-lg text-center"
83
- novalidate
84
- @submit.prevent="onSubmit"
87
+ <form
88
+ class="flex flex-col items-stretch gap-5 rounded-lg text-center"
89
+ novalidate
90
+ @submit.prevent="onSubmit"
91
+ >
92
+ <h2 class="text-center text-2xl font-bold">
93
+ {{ t('modals.id.recovery.title') }}
94
+ </h2>
95
+ <p class="text-center text-sm">
96
+ {{ t('modals.id.recovery.content') }}
97
+ </p>
98
+ <a-input-standard
99
+ v-model="emailField"
100
+ :label="t('modals.id.recovery.placeholder')"
101
+ :error="getError('emailField')"
102
+ />
103
+ <a-button :loading="loading">
104
+ {{ t('actions.recover') }}
105
+ </a-button>
106
+ <p class="text-center text-sm">
107
+ {{ t('reuse.or') }}
108
+ </p>
109
+ <a-button
110
+ type="button"
111
+ view="outline"
112
+ @click="onCancel"
85
113
  >
86
- <h2 class="text-center text-2xl font-bold">
87
- {{ t('modals.id.recovery.title') }}
88
- </h2>
89
- <p class="text-center text-sm">
90
- {{ t('modals.id.recovery.content') }}
91
- </p>
92
- <a-input-standard
93
- v-model="emailField"
94
- :label="t('modals.id.recovery.placeholder')"
95
- :error="getError('emailField')"
96
- />
97
- <a-button :loading="loading">
98
- {{ t('actions.recover') }}
99
- </a-button>
100
- <p class="text-center text-sm">
101
- {{ t('reuse.or') }}
102
- </p>
103
- <a-button
104
- type="button"
105
- view="outline"
106
- @click="onCancel"
107
- >
108
- {{ t('actions.cancel') }}
109
- </a-button>
110
- </form>
111
- </a-modal>
114
+ {{ t('actions.cancel') }}
115
+ </a-button>
116
+ </form>
112
117
  </template>
113
118
 
114
119
  <style scoped></style>
@@ -1,21 +1,22 @@
1
1
  <script setup lang="ts">
2
- import Accept from '#adata-ui/components/modals/Accept.vue'
3
2
  import { PAGES } from '#adata-ui/shared/constans/pages'
4
- import { useToggle } from '@vueuse/shared'
3
+ import { useAuthStore } from '#adata-ui/stores/auth.store'
5
4
 
6
5
  import { computed, reactive, ref } from 'vue'
7
-
8
6
  import * as z from 'zod'
9
7
 
10
8
  const { $toast } = useNuxtApp()
11
9
  const route = useRoute()
12
10
 
11
+ const authStore = useAuthStore()
12
+ const { intermediateState } = storeToRefs(authStore)
13
+
13
14
  const localePath = useLocalePath()
14
15
  const { t, locale } = useI18n()
15
16
  const { myLayer, commonAuth }: any = useAppConfig()
16
17
  const authApiURL = commonAuth.authApiURL
17
18
  const redirectUrl = useCookie('redirect_url')
18
- const { loginModal, registrationModal } = useIdModals()
19
+ const { loginModal, registrationModal, confirmAccountOtpModal } = useIdModals()
19
20
 
20
21
  export interface RegistrationForm {
21
22
  email: string
@@ -29,7 +30,6 @@ const form = reactive<RegistrationForm>({
29
30
  password_confirmation: '',
30
31
  })
31
32
 
32
- const [isAcceptModal, toggleAcceptModal] = useToggle()
33
33
  const agreement = ref(false)
34
34
  const loading = ref(false)
35
35
 
@@ -74,7 +74,7 @@ async function onSubmit() {
74
74
 
75
75
  try {
76
76
  loading.value = true
77
- const { data, message } = await $fetch(`${authApiURL}/register`, {
77
+ const { success, message } = await $fetch(`${authApiURL}/register`, {
78
78
  method: 'POST',
79
79
  credentials: 'include',
80
80
  headers: {
@@ -82,9 +82,10 @@ async function onSubmit() {
82
82
  },
83
83
  body: form,
84
84
  })
85
- if (data) {
85
+ if (success) {
86
+ intermediateState.value.email = form.email
86
87
  registrationModal.value = false
87
- toggleAcceptModal()
88
+ confirmAccountOtpModal.value = true
88
89
  $toast.success(message)
89
90
  }
90
91
  }
@@ -100,30 +101,10 @@ if (route.query.url) {
100
101
  redirectUrl.value = route.query.url as string
101
102
  }
102
103
 
103
- function goBack() {
104
- isAcceptModal.value = false
105
- }
106
-
107
104
  // onMounted(() => {
108
105
  // v$.value.$touch();
109
106
  // });
110
107
 
111
- async function onResend() {
112
- const emailResend = await fetch(`${authApiURL}/email/resend`, {
113
- method: 'GET',
114
- credentials: 'include',
115
- headers: {
116
- lang: locale.value,
117
- },
118
- })
119
- const { data, success, message } = await emailResend.json()
120
- if (success) {
121
- toggleAcceptModal()
122
- loading.value = false
123
- $toast.success(message)
124
- }
125
- }
126
-
127
108
  function getUrl() {
128
109
  return navigateTo(locale.value !== 'ru'
129
110
  ? myLayer.landingUrl + localePath('/') + PAGES.userAgreement
@@ -136,7 +117,7 @@ function getUrl() {
136
117
  }
137
118
 
138
119
  function handleEnter(event: KeyboardEvent) {
139
- if (event.key === 'Enter' && !isAcceptModal.value) {
120
+ if (event.key === 'Enter' && !confirmAccountOtpModal.value) {
140
121
  onSubmit()
141
122
  }
142
123
  }
@@ -165,80 +146,71 @@ onBeforeUnmount(() => {
165
146
  </script>
166
147
 
167
148
  <template>
168
- <a-modal v-model="registrationModal">
169
- <form
170
- class="flex flex-col items-stretch gap-5"
171
- novalidate
172
- @submit.prevent="onSubmit"
149
+ <form
150
+ class="flex flex-col items-stretch gap-5"
151
+ novalidate
152
+ @submit.prevent="onSubmit"
153
+ >
154
+ <h2 class="text-center text-2xl font-bold">
155
+ {{ t('register.form.title') }}
156
+ </h2>
157
+ <p class="text-center text-sm">
158
+ {{ t('register.form.subtitle') }}
159
+ </p>
160
+ <a-input-standard
161
+ v-model="form.email"
162
+ :label="t('register.form.labels.email')"
163
+ :error="getError('email')"
164
+ type="email"
165
+ />
166
+
167
+ <a-input-password
168
+ v-model="form.password"
169
+ :label="t('register.form.labels.password')"
170
+ :error="getError('password')"
171
+ />
172
+
173
+ <a-input-password
174
+ v-model="form.password_confirmation"
175
+ :label="t('register.form.labels.password_confirmation')"
176
+ :error="getError('password_confirmation')"
177
+ />
178
+ <a-alert color="blue">
179
+ {{ t('register.form.alert') }}
180
+ <template #icon>
181
+ <a-icon-info-circle />
182
+ </template>
183
+ </a-alert>
184
+ <a-checkbox
185
+ v-model="agreement"
186
+ side="right"
173
187
  >
174
- <h2 class="text-center text-2xl font-bold">
175
- {{ t('register.form.title') }}
176
- </h2>
177
- <p class="text-center text-sm">
178
- {{ t('register.form.subtitle') }}
179
- </p>
180
- <a-input-standard
181
- v-model="form.email"
182
- :label="t('register.form.labels.email')"
183
- :error="getError('email')"
184
- type="email"
185
- />
186
-
187
- <a-input-password
188
- v-model="form.password"
189
- :label="t('register.form.labels.password')"
190
- :error="getError('password')"
191
- />
192
-
193
- <a-input-password
194
- v-model="form.password_confirmation"
195
- :label="t('register.form.labels.password_confirmation')"
196
- :error="getError('password_confirmation')"
197
- />
198
- <a-alert color="blue">
199
- {{ t('register.form.alert') }}
200
- <template #icon>
201
- <a-icon-info-circle />
188
+ <i18n-t keypath="register.form.agreement.text">
189
+ <template #link>
190
+ <nuxt-link-locale
191
+ class="text-blue-700"
192
+ @click="getUrl"
193
+ >
194
+ {{ t('register.form.agreement.link') }}
195
+ </nuxt-link-locale>
202
196
  </template>
203
- </a-alert>
204
- <a-checkbox
205
- v-model="agreement"
206
- side="right"
207
- >
208
- <i18n-t keypath="register.form.agreement.text">
209
- <template #link>
210
- <nuxt-link-locale
211
- class="text-blue-700"
212
- @click="getUrl"
213
- >
214
- {{ t('register.form.agreement.link') }}
215
- </nuxt-link-locale>
216
- </template>
217
- </i18n-t>
218
- </a-checkbox>
219
- <a-button
220
- :disabled="!agreement"
221
- :loading="loading"
222
- >
223
- {{ t('register.form.continue') }}
224
- </a-button>
225
- <p class="text-center text-sm">
226
- {{ t('register.form.haveAcc') }}
227
- </p>
228
- <a-button
229
- type="button"
230
- view="outline"
231
- @click="onLogin"
232
- >
233
- {{ t('register.form.enter') }}
234
- </a-button>
235
- </form>
236
- </a-modal>
237
- <a-modal v-model="isAcceptModal">
238
- <accept
239
- v-if="isAcceptModal"
240
- @back="goBack"
241
- @repeated="onResend"
242
- />
243
- </a-modal>
197
+ </i18n-t>
198
+ </a-checkbox>
199
+ <a-button
200
+ :disabled="!agreement"
201
+ :loading="loading"
202
+ >
203
+ {{ t('register.form.continue') }}
204
+ </a-button>
205
+ <p class="text-center text-sm">
206
+ {{ t('register.form.haveAcc') }}
207
+ </p>
208
+ <a-button
209
+ type="button"
210
+ view="outline"
211
+ @click="onLogin"
212
+ >
213
+ {{ t('register.form.enter') }}
214
+ </a-button>
215
+ </form>
244
216
  </template>
@@ -0,0 +1,154 @@
1
+ <script setup lang="ts">
2
+ import OtpInput from '#adata-ui/components/modals/two-factor/otp-input.vue'
3
+ import { useAuthStore } from '#adata-ui/stores/auth.store'
4
+
5
+ const { $toast } = useNuxtApp()
6
+ const { t, locale } = useI18n()
7
+ const { commonAuth } = useAppConfig()
8
+
9
+ const authStore = useAuthStore()
10
+ const { intermediateState } = storeToRefs(authStore)
11
+
12
+ const { resetPasswordOtpModal, newPasswordModal } = useIdModals()
13
+
14
+ const authApiURL = commonAuth.authApiURL
15
+
16
+ const otp = ref(['', '', '', '', '', ''])
17
+ const otpFormatted = computed(() => {
18
+ return otp.value.join('')
19
+ })
20
+ const showError = ref(false)
21
+ const isLoading = ref(false)
22
+
23
+ async function onConfirm() {
24
+ try {
25
+ isLoading.value = true
26
+
27
+ const response = await $fetch(`${authApiURL}/password/validate-otp`, {
28
+ method: 'POST',
29
+ credentials: 'include',
30
+ headers: {
31
+ lang: locale.value,
32
+ },
33
+ body: {
34
+ email: intermediateState.value.email,
35
+ otp: otpFormatted.value,
36
+ },
37
+ })
38
+
39
+ intermediateState.value.token = response.data
40
+ intermediateState.value.otp = otpFormatted.value
41
+
42
+ resetPasswordOtpModal.value = false
43
+ newPasswordModal.value = true
44
+ }
45
+ catch (error) {
46
+ showError.value = true
47
+ $toast.error(error.data.message)
48
+ }
49
+ finally {
50
+ isLoading.value = false
51
+ }
52
+ }
53
+
54
+ async function onResend() {
55
+ try {
56
+ await $fetch(`${authApiURL}/password/email-otp`, {
57
+ method: 'POST',
58
+ credentials: 'include',
59
+ headers: {
60
+ lang: locale.value,
61
+ },
62
+ body: {
63
+ email: intermediateState.value.email,
64
+ },
65
+ })
66
+ runTimer()
67
+ }
68
+ catch (error) {
69
+ $toast.error(error.data.message)
70
+ }
71
+ }
72
+
73
+ function onClose() {
74
+ otp.value = ['', '', '', '', '', '']
75
+ showError.value = false
76
+ resetPasswordOtpModal.value = false
77
+ }
78
+
79
+ function handleEnter(e: KeyboardEvent) {
80
+ if (e.key === 'Enter') {
81
+ onConfirm()
82
+ }
83
+ }
84
+
85
+ const timer = ref(60)
86
+
87
+ function runTimer() {
88
+ const intervalId = setInterval(() => {
89
+ if (!timer.value) clearInterval(intervalId)
90
+ return timer.value--
91
+ }, 1000)
92
+ }
93
+
94
+ onMounted(() => {
95
+ runTimer()
96
+ document.addEventListener('keyup', handleEnter)
97
+ })
98
+
99
+ onBeforeUnmount(() => {
100
+ document.removeEventListener('keyup', handleEnter)
101
+ })
102
+ </script>
103
+
104
+ <template>
105
+ <div class="flex flex-col items-center gap-4 text-center">
106
+ <h2 class="text-2xl font-bold">
107
+ {{ t('modals.id.resetPasswordOtp.title') }}
108
+ </h2>
109
+
110
+ <a-icon-hand-with-phone-light class="size-32 dark:hidden" />
111
+ <a-icon-hand-with-phone-dark class="hidden size-32 dark:block" />
112
+
113
+ <div class="text-sm">
114
+ <p class="mb-1">
115
+ {{ t('modals.id.resetPasswordOtp.content') }}
116
+ </p>
117
+
118
+ <div v-if="timer > 0" class="text-2xl font-bold">
119
+ {{ timer }} {{ t('register.modal.seconds') }}
120
+ </div>
121
+ <button
122
+ v-else
123
+ class="text-blue-700 dark:text-blue-500"
124
+ @click="onResend"
125
+ >
126
+ {{ t('actions.resend') }}
127
+ </button>
128
+ </div>
129
+
130
+ <otp-input v-model="otp" v-model:error="showError" />
131
+
132
+ <div class="flex w-full gap-2">
133
+ <a-button
134
+ block
135
+ view="outline"
136
+ @click="onClose"
137
+ >
138
+ {{ t('actions.close') }}
139
+ </a-button>
140
+ <a-button
141
+ block
142
+ :loading="isLoading"
143
+ :disabled="otpFormatted.length < 6"
144
+ @click="onConfirm"
145
+ >
146
+ {{ t('actions.confirm') }}
147
+ </a-button>
148
+ </div>
149
+ </div>
150
+ </template>
151
+
152
+ <style scoped>
153
+
154
+ </style>
@@ -131,7 +131,7 @@ function moveFocus(index: number, to: string) {
131
131
  size="sm"
132
132
  icon-type="triangle"
133
133
  >
134
- {{ t('twoFactor.error') }}
134
+ {{ t('error.otp') }}
135
135
  </a-alert>
136
136
  </div>
137
137
  </template>
@@ -1 +1 @@
1
- # breadcrumb, tabs
1
+ # breadcrumb, tabs
@@ -1 +1 @@
1
- # tooltip, popover, slide over, modal, context menu
1
+ # tooltip, popover, slide over, modal, context menu
@@ -1,17 +1,25 @@
1
1
  export function useIdModals() {
2
2
  const loginModal = useState('login-modal', () => false)
3
+ const twoFactorModal = useState('two-factor-modal', () => false)
4
+
3
5
  const registrationModal = useState('registration-modal', () => false)
6
+ const confirmAccountOtpModal = useState('confirm-account-otp-modal', () => false)
7
+ const confirmSuccessfulModal = useState('confirm-successful-modal', () => false)
8
+
4
9
  const recoveryModal = useState('recovery-modal', () => false)
5
- const emailModal = useState('email-modal', () => false)
10
+ const resetPasswordOtpModal = useState('reset-password-otp-modal', () => false)
6
11
  const newPasswordModal = useState('new-password-modal', () => false)
7
12
  const passwordSuccessfulModal = useState('password-successful-modal', () => false)
8
13
 
9
14
  return {
10
15
  loginModal,
16
+ twoFactorModal,
11
17
  registrationModal,
18
+ confirmAccountOtpModal,
12
19
  recoveryModal,
13
- emailModal,
20
+ resetPasswordOtpModal,
14
21
  newPasswordModal,
15
22
  passwordSuccessfulModal,
23
+ confirmSuccessfulModal,
16
24
  }
17
25
  }
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <mask id="path-1-inside-1_16139_4935" fill="white">
4
+ <path d="M11.5689 2.7041C9.95675 2.7041 8.36808 3.09007 6.93567 3.82973C5.50326 4.56938 4.26876 5.64124 3.33539 6.95565C2.40202 8.27007 1.79691 9.78886 1.57065 11.385C1.3444 12.9812 1.50358 14.6083 2.03488 16.1303C2.56618 17.6524 3.45416 19.0251 4.62458 20.1337C5.79499 21.2423 7.21382 22.0546 8.76241 22.5026C10.311 22.9506 11.9444 23.0214 13.5259 22.709C15.1074 22.3965 16.5912 21.71 17.8531 20.7067L11.5689 12.8023V2.7041Z"/>
5
+ </mask>
6
+ <path d="M11.5689 2.7041C9.95675 2.7041 8.36808 3.09007 6.93567 3.82973C5.50326 4.56938 4.26876 5.64124 3.33539 6.95565C2.40202 8.27007 1.79691 9.78886 1.57065 11.385C1.3444 12.9812 1.50358 14.6083 2.03488 16.1303C2.56618 17.6524 3.45416 19.0251 4.62458 20.1337C5.79499 21.2423 7.21382 22.0546 8.76241 22.5026C10.311 22.9506 11.9444 23.0214 13.5259 22.709C15.1074 22.3965 16.5912 21.71 17.8531 20.7067L11.5689 12.8023V2.7041Z" stroke="currentColor" stroke-width="2.44898" mask="url(#path-1-inside-1_16139_4935)"/>
7
+ <mask id="path-2-inside-2_16139_4935" fill="white">
8
+ <path d="M12.3329 0.979492C14.8031 0.979492 17.2017 1.80939 19.1436 3.336C21.0856 4.8626 22.4584 6.99738 23.0417 9.39772L12.3329 11.9999V0.979492Z"/>
9
+ </mask>
10
+ <path d="M12.3329 0.979492C14.8031 0.979492 17.2017 1.80939 19.1436 3.336C21.0856 4.8626 22.4584 6.99738 23.0417 9.39772L12.3329 11.9999V0.979492Z" stroke="currentColor" stroke-width="2.44898" mask="url(#path-2-inside-2_16139_4935)"/>
11
+ <mask id="path-3-inside-3_16139_4935" fill="white">
12
+ <path d="M21.6275 10.667C22.0329 12.3775 21.9429 14.168 21.3681 15.8292C20.7932 17.4904 19.7572 18.9536 18.3813 20.0476L12.6204 12.8021L21.6275 10.667Z"/>
13
+ </mask>
14
+ <path d="M21.6275 10.667C22.0329 12.3775 21.9429 14.168 21.3681 15.8292C20.7932 17.4904 19.7572 18.9536 18.3813 20.0476L12.6204 12.8021L21.6275 10.667Z" stroke="currentColor" stroke-width="2.44898" mask="url(#path-3-inside-3_16139_4935)"/>
15
+ </svg>
16
+ </template>
package/icons/google.vue CHANGED
@@ -1,41 +1,41 @@
1
-
2
-
3
- <script lang="ts" setup>
4
- </script>
5
-
6
- <template>
7
- <svg
8
- width="32"
9
- height="32"
10
- viewBox="0 0 32 32"
11
- fill="none"
12
- xmlns="http://www.w3.org/2000/svg"
13
- >
14
- <rect
15
- x="0.5"
16
- y="0.5"
17
- width="31"
18
- height="31"
19
- rx="5.5"
20
- stroke="#9DA3AC"
21
- />
22
- <path
23
- d="M26.501 16.2332C26.501 15.3699 26.4296 14.7399 26.2748 14.0865H16.2153V17.9832H22.12C22.001 18.9515 21.3582 20.4099 19.9296 21.3898L19.9096 21.5203L23.0902 23.935L23.3106 23.9565C25.3343 22.1249 26.501 19.4298 26.501 16.2332Z"
24
- fill="#4285F4"
25
- />
26
- <path
27
- d="M16.2147 26.5C19.1075 26.5 21.5361 25.5666 23.3099 23.9566L19.929 21.3898C19.0242 22.0082 17.8099 22.4399 16.2147 22.4399C13.3814 22.4399 10.9767 20.6082 10.1195 18.0765L9.99382 18.087L6.68656 20.5954L6.64331 20.7132C8.40519 24.1432 12.0242 26.5 16.2147 26.5Z"
28
- fill="#34A853"
29
- />
30
- <path
31
- d="M10.12 18.0766C9.89379 17.4233 9.76289 16.7232 9.76289 15.9999C9.76289 15.2765 9.89379 14.5766 10.1081 13.9232L10.1021 13.7841L6.75337 11.2355L6.64381 11.2865C5.91765 12.7099 5.50098 14.3083 5.50098 15.9999C5.50098 17.6916 5.91765 19.2899 6.64381 20.7132L10.12 18.0766Z"
32
- fill="#FBBC05"
33
- />
34
- <path
35
- d="M16.2148 9.55997C18.2267 9.55997 19.5838 10.4116 20.3576 11.1233L23.3814 8.23C21.5243 6.53834 19.1076 5.5 16.2148 5.5C12.0243 5.5 8.4052 7.85665 6.64331 11.2866L10.1076 13.9233C10.9767 11.3917 13.3815 9.55997 16.2148 9.55997Z"
36
- fill="#EB4335"
37
- />
38
- </svg>
39
- </template>
40
-
41
- <style scoped></style>
1
+
2
+
3
+ <script lang="ts" setup>
4
+ </script>
5
+
6
+ <template>
7
+ <svg
8
+ width="32"
9
+ height="32"
10
+ viewBox="0 0 32 32"
11
+ fill="none"
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ >
14
+ <rect
15
+ x="0.5"
16
+ y="0.5"
17
+ width="31"
18
+ height="31"
19
+ rx="5.5"
20
+ stroke="#9DA3AC"
21
+ />
22
+ <path
23
+ d="M26.501 16.2332C26.501 15.3699 26.4296 14.7399 26.2748 14.0865H16.2153V17.9832H22.12C22.001 18.9515 21.3582 20.4099 19.9296 21.3898L19.9096 21.5203L23.0902 23.935L23.3106 23.9565C25.3343 22.1249 26.501 19.4298 26.501 16.2332Z"
24
+ fill="#4285F4"
25
+ />
26
+ <path
27
+ d="M16.2147 26.5C19.1075 26.5 21.5361 25.5666 23.3099 23.9566L19.929 21.3898C19.0242 22.0082 17.8099 22.4399 16.2147 22.4399C13.3814 22.4399 10.9767 20.6082 10.1195 18.0765L9.99382 18.087L6.68656 20.5954L6.64331 20.7132C8.40519 24.1432 12.0242 26.5 16.2147 26.5Z"
28
+ fill="#34A853"
29
+ />
30
+ <path
31
+ d="M10.12 18.0766C9.89379 17.4233 9.76289 16.7232 9.76289 15.9999C9.76289 15.2765 9.89379 14.5766 10.1081 13.9232L10.1021 13.7841L6.75337 11.2355L6.64381 11.2865C5.91765 12.7099 5.50098 14.3083 5.50098 15.9999C5.50098 17.6916 5.91765 19.2899 6.64381 20.7132L10.12 18.0766Z"
32
+ fill="#FBBC05"
33
+ />
34
+ <path
35
+ d="M16.2148 9.55997C18.2267 9.55997 19.5838 10.4116 20.3576 11.1233L23.3814 8.23C21.5243 6.53834 19.1076 5.5 16.2148 5.5C12.0243 5.5 8.4052 7.85665 6.64331 11.2866L10.1076 13.9233C10.9767 11.3917 13.3815 9.55997 16.2148 9.55997Z"
36
+ fill="#EB4335"
37
+ />
38
+ </svg>
39
+ </template>
40
+
41
+ <style scoped></style>