|
1 | 1 | <script setup lang="ts"> |
| 2 | +import AlertError from '@/components/AlertError.vue'; |
2 | 3 | import InputError from '@/components/InputError.vue'; |
3 | 4 | import { Button } from '@/components/ui/button'; |
4 | 5 | import { |
@@ -29,7 +30,7 @@ const props = defineProps<Props>(); |
29 | 30 | const isOpen = defineModel<boolean>('isOpen'); |
30 | 31 |
|
31 | 32 | const { copy, copied } = useClipboard(); |
32 | | -const { qrCodeSvg, manualSetupKey, clearSetupData, fetchSetupData } = |
| 33 | +const { qrCodeSvg, manualSetupKey, clearSetupData, fetchSetupData, errors } = |
33 | 34 | useTwoFactorAuth(); |
34 | 35 |
|
35 | 36 | const showVerificationStep = ref(false); |
@@ -150,79 +151,82 @@ watch( |
150 | 151 | class="relative flex w-auto flex-col items-center justify-center space-y-5" |
151 | 152 | > |
152 | 153 | <template v-if="!showVerificationStep"> |
153 | | - <div |
154 | | - class="relative mx-auto flex max-w-md items-center overflow-hidden" |
155 | | - > |
| 154 | + <AlertError v-if="errors?.length" :errors="errors" /> |
| 155 | + <template v-else> |
156 | 156 | <div |
157 | | - class="relative mx-auto aspect-square w-64 overflow-hidden rounded-lg border border-border" |
| 157 | + class="relative mx-auto flex max-w-md items-center overflow-hidden" |
158 | 158 | > |
159 | 159 | <div |
160 | | - v-if="!qrCodeSvg" |
161 | | - class="absolute inset-0 z-10 flex aspect-square h-auto w-full animate-pulse items-center justify-center bg-background" |
162 | | - > |
163 | | - <Loader2 class="size-6 animate-spin" /> |
164 | | - </div> |
165 | | - <div |
166 | | - v-else |
167 | | - class="relative z-10 overflow-hidden border p-5" |
| 160 | + class="relative mx-auto aspect-square w-64 overflow-hidden rounded-lg border border-border" |
168 | 161 | > |
169 | 162 | <div |
170 | | - v-html="qrCodeSvg" |
171 | | - class="flex aspect-square size-full items-center justify-center" |
172 | | - /> |
| 163 | + v-if="!qrCodeSvg" |
| 164 | + class="absolute inset-0 z-10 flex aspect-square h-auto w-full animate-pulse items-center justify-center bg-background" |
| 165 | + > |
| 166 | + <Loader2 class="size-6 animate-spin" /> |
| 167 | + </div> |
| 168 | + <div |
| 169 | + v-else |
| 170 | + class="relative z-10 overflow-hidden border p-5" |
| 171 | + > |
| 172 | + <div |
| 173 | + v-html="qrCodeSvg" |
| 174 | + class="flex aspect-square size-full items-center justify-center" |
| 175 | + /> |
| 176 | + </div> |
173 | 177 | </div> |
174 | 178 | </div> |
175 | | - </div> |
176 | 179 |
|
177 | | - <div class="flex w-full items-center space-x-5"> |
178 | | - <Button class="w-full" @click="handleModalNextStep"> |
179 | | - {{ modalConfig.buttonText }} |
180 | | - </Button> |
181 | | - </div> |
| 180 | + <div class="flex w-full items-center space-x-5"> |
| 181 | + <Button class="w-full" @click="handleModalNextStep"> |
| 182 | + {{ modalConfig.buttonText }} |
| 183 | + </Button> |
| 184 | + </div> |
182 | 185 |
|
183 | | - <div |
184 | | - class="relative flex w-full items-center justify-center" |
185 | | - > |
186 | 186 | <div |
187 | | - class="absolute inset-0 top-1/2 h-px w-full bg-border" |
188 | | - /> |
189 | | - <span class="relative bg-card px-2 py-1" |
190 | | - >or, enter the code manually</span |
| 187 | + class="relative flex w-full items-center justify-center" |
191 | 188 | > |
192 | | - </div> |
| 189 | + <div |
| 190 | + class="absolute inset-0 top-1/2 h-px w-full bg-border" |
| 191 | + /> |
| 192 | + <span class="relative bg-card px-2 py-1" |
| 193 | + >or, enter the code manually</span |
| 194 | + > |
| 195 | + </div> |
193 | 196 |
|
194 | | - <div |
195 | | - class="flex w-full items-center justify-center space-x-2" |
196 | | - > |
197 | 197 | <div |
198 | | - class="flex w-full items-stretch overflow-hidden rounded-xl border border-border" |
| 198 | + class="flex w-full items-center justify-center space-x-2" |
199 | 199 | > |
200 | 200 | <div |
201 | | - v-if="!manualSetupKey" |
202 | | - class="flex h-full w-full items-center justify-center bg-muted p-3" |
| 201 | + class="flex w-full items-stretch overflow-hidden rounded-xl border border-border" |
203 | 202 | > |
204 | | - <Loader2 class="size-4 animate-spin" /> |
205 | | - </div> |
206 | | - <template v-else> |
207 | | - <input |
208 | | - type="text" |
209 | | - readonly |
210 | | - :value="manualSetupKey" |
211 | | - class="h-full w-full bg-background p-3 text-foreground" |
212 | | - /> |
213 | | - <button |
214 | | - @click="copy(manualSetupKey || '')" |
215 | | - class="relative block h-auto border-l border-border px-3 hover:bg-muted" |
| 203 | + <div |
| 204 | + v-if="!manualSetupKey" |
| 205 | + class="flex h-full w-full items-center justify-center bg-muted p-3" |
216 | 206 | > |
217 | | - <Check |
218 | | - v-if="copied" |
219 | | - class="w-4 text-green-500" |
| 207 | + <Loader2 class="size-4 animate-spin" /> |
| 208 | + </div> |
| 209 | + <template v-else> |
| 210 | + <input |
| 211 | + type="text" |
| 212 | + readonly |
| 213 | + :value="manualSetupKey" |
| 214 | + class="h-full w-full bg-background p-3 text-foreground" |
220 | 215 | /> |
221 | | - <Copy v-else class="w-4" /> |
222 | | - </button> |
223 | | - </template> |
| 216 | + <button |
| 217 | + @click="copy(manualSetupKey || '')" |
| 218 | + class="relative block h-auto border-l border-border px-3 hover:bg-muted" |
| 219 | + > |
| 220 | + <Check |
| 221 | + v-if="copied" |
| 222 | + class="w-4 text-green-500" |
| 223 | + /> |
| 224 | + <Copy v-else class="w-4" /> |
| 225 | + </button> |
| 226 | + </template> |
| 227 | + </div> |
224 | 228 | </div> |
225 | | - </div> |
| 229 | + </template> |
226 | 230 | </template> |
227 | 231 |
|
228 | 232 | <template v-else> |
|
0 commit comments