11<script setup lang="ts">
2- import { ref , watch , nextTick , computed } from ' vue' ;
2+ import { computed , ComputedRef , nextTick , ref , watch } from ' vue' ;
33import { Head , Form } from ' @inertiajs/vue3' ;
44import { Button } from ' @/components/ui/button' ;
55import { Input } from ' @/components/ui/input' ;
66import InputError from ' @/components/InputError.vue' ;
77import AuthLayout from ' @/layouts/AuthLayout.vue' ;
88import { PinInput , PinInputGroup , PinInputSlot } from ' @/components/ui/pin-input' ;
99
10- const recovery = ref (false );
11- const pinValue = ref <number []>([]);
12- const pinInputContainerRef = ref <HTMLElement | null >(null );
10+ const showRecoveryInput = ref (false );
11+ const code = ref <number []>([]);
1312const recoveryInputRef = ref <HTMLInputElement | null >(null );
1413
15- const codeValue = computed (() => pinValue .value .join (' ' ));
14+ const codeValue: ComputedRef < string > = computed (() => code .value .join (' ' ));
1615
17- watch (recovery , (value ) => {
18- if (value ) {
19- nextTick (() => {
20- if (recoveryInputRef .value ) {
21- recoveryInputRef .value ?.focus ();
22- }
23- });
24- } else {
16+ const authConfig = computed (() => {
17+ return {
18+ title: showRecoveryInput .value ? ' Recovery Code' : ' Authentication Code' ,
19+ description: showRecoveryInput .value
20+ ? ' Please confirm access to your account by entering one of your emergency recovery codes.'
21+ : ' Enter the authentication code provided by your authenticator application.' ,
22+ toggleText: showRecoveryInput .value
23+ ? ' login using an authentication code'
24+ : ' login using a recovery code' ,
25+ };
26+ });
27+
28+ watch (
29+ showRecoveryInput ,
30+ (isRecoveryMode ) => {
2531 nextTick (() => {
26- if (pinInputContainerRef .value ) {
27- const firstInput = pinInputContainerRef .value .querySelector (' input' );
28- if (firstInput ) firstInput .focus ();
32+ if (isRecoveryMode && recoveryInputRef .value ) {
33+ recoveryInputRef .value .focus ();
2934 }
3035 });
31- }
32- } );
36+ },
37+ );
3338
34- const toggleRecovery = (clearErrors : () => void ) => {
35- recovery .value = ! recovery .value ;
39+ const toggleRecoveryMode = (clearErrors : () => void ): void => {
40+ showRecoveryInput .value = ! showRecoveryInput .value ;
3641 clearErrors ();
37- pinValue .value = [];
38- const codeInput = document .querySelector (' input[name="code"]' ) as HTMLInputElement ;
39- const recoveryInput = document .querySelector (' input[name="recovery_code"]' ) as HTMLInputElement ;
40- if (codeInput ) codeInput .value = ' ' ;
41- if (recoveryInput ) recoveryInput .value = ' ' ;
42- };
43- </script >
42+ code .value = [];
43+ }; </script >
4444
4545<template >
46- <AuthLayout
47- :title =" recovery ? 'Recovery Code' : 'Authentication Code'"
48- :description ="
49- recovery
50- ? 'Please confirm access to your account by entering one of your emergency recovery codes.'
51- : 'Enter the authentication code provided by your authenticator application.'
52- "
53- >
46+ <AuthLayout :title =" authConfig.title" :description =" authConfig.description" >
5447 <Head title =" Two Factor Authentication" />
5548
5649 <div class =" relative space-y-2" >
57- <template v-if =" ! recovery " >
50+ <template v-if =" ! showRecoveryInput " >
5851 <Form :action =" route('two-factor.login')" method =" post" class =" space-y-4" #default =" { errors, processing, clearErrors }" >
5952 <input type =" hidden" name =" code" :value =" codeValue" />
6053 <div class =" flex flex-col items-center justify-center space-y-3 text-center" >
61- <div ref = " pinInputContainerRef " class =" flex w-full items-center justify-center" >
62- <PinInput id =" otp" v-model =" pinValue " class =" mt-1" type =" number" otp >
54+ <div class =" flex w-full items-center justify-center" >
55+ <PinInput id =" otp" v-model =" code " class =" mt-1" type =" number" otp >
6356 <PinInputGroup class =" gap-2" >
6457 <PinInputSlot
6558 v-for =" (id, index) in 6"
@@ -73,16 +66,16 @@ const toggleRecovery = (clearErrors: () => void) => {
7366 </div >
7467 <InputError :message =" errors.code" />
7568 </div >
76- <Button type =" submit" class =" w-full" :disabled =" processing || pinValue .length !== 6" > Continue </Button >
69+ <Button type =" submit" class =" w-full" :disabled =" processing || code .length !== 6" > Continue </Button >
7770
7871 <div class =" mt-4 space-x-0.5 text-center text-sm leading-5 text-muted-foreground" >
7972 <span class =" opacity-80" >or you can </span >
8073 <button
8174 type =" button"
8275 class =" cursor-pointer border-0 bg-transparent p-0 font-medium underline opacity-80"
83- @click =" () => toggleRecovery (clearErrors)"
76+ @click =" () => toggleRecoveryMode (clearErrors)"
8477 >
85- login using a recovery code
78+ {{ authConfig.toggleText }}
8679 </button >
8780 </div >
8881 </Form >
@@ -107,9 +100,9 @@ const toggleRecovery = (clearErrors: () => void) => {
107100 <button
108101 type =" button"
109102 class =" cursor-pointer border-0 bg-transparent p-0 font-medium underline opacity-80"
110- @click =" () => toggleRecovery (clearErrors)"
103+ @click =" () => toggleRecoveryMode (clearErrors)"
111104 >
112- login using an authentication code
105+ {{ authConfig.toggleText }}
113106 </button >
114107 </div >
115108 </Form >
0 commit comments