@@ -39,24 +39,10 @@ const verifyStep = ref(false);
3939const showingRecoveryCodes = ref (false );
4040const showModal = ref (false );
4141
42- // Form refs
43- const enableFormRef = ref ();
44- const confirmFormRef = ref ();
45- const disableFormRef = ref ();
46- const regenerateFormRef = ref ();
47-
48- const handleEnableSuccess = (): void => {
42+ const showTwoFactorEnableModal = (): void => {
4943 showModal .value = true ;
5044};
5145
52- const handleEnableError = (): void => {
53- error .value = ' Failed to enable two-factor authentication' ;
54- };
55-
56- const handleEnableFinish = (): void => {
57- // Form component handles loading state automatically
58- };
59-
6046const handleConfirmSuccess = (): void => {
6147 verifyStep .value = false ;
6248 showModal .value = false ;
@@ -70,14 +56,6 @@ const handleConfirmError = (errors: any): void => {
7056 pinValue .value = [];
7157};
7258
73- const handleDisableSuccess = (): void => {
74- showingRecoveryCodes .value = false ;
75- };
76-
77- const handleDisableError = (): void => {
78- console .error (' Error disabling 2FA' );
79- };
80-
8159const copyToClipboard = (text : string ): void => {
8260 navigator .clipboard .writeText (text ).then (() => (copied .value = true ));
8361 setTimeout (() => (copied .value = false ), 1500 );
@@ -100,20 +78,17 @@ const toggleRecoveryCodes = () => {
10078 <HeadingSmall title =" Two-Factor Authentication" description =" Manage your two-factor authentication settings" />
10179 <div v-if =" !props.confirmed" class =" flex flex-col items-start justify-start space-y-5" >
10280 <Badge variant =" outline" class =" border-orange-200 bg-orange-50 text-orange-700 hover:bg-orange-50" > Disabled </Badge >
103- <p class =" -translate-y-1 text-stone-500 dark:text-stone-400 " >
81+ <p class =" -translate-y-1 text-muted-foreground " >
10482 When you enable 2FA, you'll be prompted for a secure code during login, which can be retrieved from your phone's TOTP
10583 supported app.
10684 </p >
10785 <Dialog :open =" showModal" @update:open =" showModal = $event" >
10886 <DialogTrigger as-child >
10987 <Form
110- ref =" enableFormRef"
11188 :async =" false"
11289 :action =" route('two-factor.enable')"
11390 method =" post"
114- @success =" handleEnableSuccess"
115- @error =" handleEnableError"
116- @finish =" handleEnableFinish"
91+ @success =" showTwoFactorEnableModal"
11792 #default =" { processing }"
11893 >
11994 <Button type =" submit" :disabled =" processing" >
@@ -123,15 +98,19 @@ const toggleRecoveryCodes = () => {
12398 </DialogTrigger >
12499 <DialogContent class =" sm:max-w-md" >
125100 <DialogHeader class =" flex items-center justify-center" >
126- <div class =" mb-3 w-auto rounded-full border border-stone-100 bg-white p-0.5 shadow-sm dark:border-stone-600 dark:bg-stone-800" >
127- <div class =" relative overflow-hidden rounded-full border border-stone-200 bg-stone-100 p-2.5 dark:border-stone-600 dark:bg-stone-200" >
128- <div class =" absolute inset-0 flex h-full w-full items-stretch justify-around divide-x divide-stone-200 opacity-50 dark:divide-stone-300 [& >div]:flex-1" >
101+ <div class =" mb-3 w-auto rounded-full border border-border bg-card p-0.5 shadow-sm" >
102+ <div class =" relative overflow-hidden rounded-full border border-border bg-muted p-2.5" >
103+ <div
104+ class =" absolute inset-0 flex size-full items-stretch justify-around divide-x divide-border opacity-50 [& >div]:flex-1"
105+ >
129106 <div v-for =" i in 5" :key =" i" ></div >
130107 </div >
131- <div class =" absolute inset-0 flex h-full w-full flex-col items-stretch justify-around divide-y divide-stone-200 opacity-50 dark:divide-stone-300 [& >div]:flex-1" >
108+ <div
109+ class =" absolute inset-0 flex size-full flex-col items-stretch justify-around divide-y divide-border opacity-50 [& >div]:flex-1"
110+ >
132111 <div v-for =" i in 5" :key =" i" ></div >
133112 </div >
134- <ScanLine class =" relative z-20 size-6 dark: text-black " />
113+ <ScanLine class =" relative z-20 size-6 text-foreground " />
135114 </div >
136115 </div >
137116 <DialogTitle >
@@ -149,19 +128,17 @@ const toggleRecoveryCodes = () => {
149128 <div class =" relative flex w-auto flex-col items-center justify-center space-y-5" >
150129 <template v-if =" ! verifyStep " >
151130 <div class =" relative mx-auto flex max-w-md items-center overflow-hidden" >
152- <div
153- class =" relative mx-auto aspect-square w-64 overflow-hidden rounded-lg border border-stone-200 dark:border-stone-700"
154- >
131+ <div class =" relative mx-auto aspect-square w-64 overflow-hidden rounded-lg border border-border" >
155132 <div
156133 v-if =" !props.qrCodeSvg"
157- class =" absolute inset-0 z-10 flex aspect-square h-auto w-full animate-pulse items-center justify-center bg-white dark:bg-stone-700 "
134+ class =" absolute inset-0 z-10 flex aspect-square h-auto w-full animate-pulse items-center justify-center bg-background "
158135 >
159136 <Loader2 class =" size-6 animate-spin" />
160137 </div >
161138 <div v-else class =" relative z-10 overflow-hidden border p-5" >
162139 <div
163140 v-html =" props.qrCodeSvg"
164- class =" flex aspect-square h-full w -full items-center justify-center"
141+ class =" flex aspect-square size -full items-center justify-center"
165142 ></div >
166143 <div v-if =" props.qrCodeSvg" class =" animate-scanning-line absolute inset-0 h-full w-full" >
167144 <div
@@ -192,28 +169,25 @@ const toggleRecoveryCodes = () => {
192169 </div >
193170
194171 <div class =" relative flex w-full items-center justify-center" >
195- <div class =" absolute inset-0 top-1/2 h-px w-full bg-stone-200 dark:bg-stone-600 " ></div >
196- <span class =" relative bg-white px-2 py-1 dark:bg-stone-800 " > or, enter the code manually </span >
172+ <div class =" absolute inset-0 top-1/2 h-px w-full bg-border " ></div >
173+ <span class =" relative bg-card px-2 py-1" > or, enter the code manually </span >
197174 </div >
198175
199176 <div class =" flex w-full items-center justify-center space-x-2" >
200- <div class =" flex w-full items-stretch overflow-hidden rounded-xl border dark:border-stone-700" >
201- <div
202- v-if =" !props.secretKey"
203- class =" flex h-full w-full items-center justify-center bg-stone-100 p-3 dark:bg-stone-700"
204- >
177+ <div class =" flex w-full items-stretch overflow-hidden rounded-xl border border-border" >
178+ <div v-if =" !props.secretKey" class =" flex h-full w-full items-center justify-center bg-muted p-3" >
205179 <Loader2 class =" size-4 animate-spin" />
206180 </div >
207181 <template v-else >
208182 <input
209183 type =" text"
210184 readonly
211185 :value =" props.secretKey"
212- class =" h-full w-full bg-white p-3 text-black dark:bg-stone-800 dark:text-stone-100 "
186+ class =" h-full w-full bg-background p-3 text-foreground "
213187 />
214188 <button
215189 @click =" copyToClipboard(props.secretKey || '')"
216- class =" relative block h-auto border-l border-stone-200 px-3 hover:bg-stone-100 dark:border-stone-600 dark:hover:bg-stone-600 "
190+ class =" relative block h-auto border-l border-border px-3 hover:bg-muted "
217191 >
218192 <Check v-if =" copied" class =" w-4 text-green-500" />
219193 <Copy v-else class =" w-4" />
@@ -225,9 +199,9 @@ const toggleRecoveryCodes = () => {
225199
226200 <template v-else >
227201 <Form
228- ref =" confirmFormRef"
229202 :action =" route('two-factor.confirm')"
230203 method =" post"
204+ :async =" false"
231205 @success =" handleConfirmSuccess"
232206 @error =" handleConfirmError"
233207 #default =" { processing }"
@@ -279,23 +253,23 @@ const toggleRecoveryCodes = () => {
279253
280254 <div v-if =" props.confirmed" class =" flex flex-col items-start justify-start space-y-5" >
281255 <Badge variant =" outline" class =" border-green-200 bg-green-50 text-green-700 hover:bg-green-50" > Enabled </Badge >
282- <p class =" text-stone-500 dark:text-stone-400 " >
256+ <p class =" text-muted-foreground " >
283257 With two factor authentication enabled, you'll be prompted for a secure, random token during login, which you can retrieve
284258 from your TOTP Authenticator app.
285259 </p >
286260
287261 <div >
288- <div class =" flex items-start rounded-t-xl border border-stone-200 bg-stone-50 p-4 dark:border-stone-700 dark:bg-stone-800 " >
262+ <div class =" flex items-start rounded-t-xl border border-muted p-4" >
289263 <LockKeyhole class =" mr-2 size-5 text-stone-500" />
290264 <div class =" space-y-1" >
291265 <h3 class =" font-medium" >2FA Recovery Codes</h3 >
292- <p class =" text-sm text-stone-500 dark:text-stone-400 " >
266+ <p class =" text-sm text-muted-foreground " >
293267 Recovery codes let you regain access if you lose your 2FA device. Store them in a secure password manager.
294268 </p >
295269 </div >
296270 </div >
297271
298- <div class =" rounded-b-xl border border-t-0 border-stone-200 bg-stone-100 text-sm dark:border-stone-700 dark:bg-stone-800 " >
272+ <div class =" rounded-b-xl border border-t-0 border-stone-200 bg-secondary dark:border-stone-700 text-sm " >
299273 <div
300274 @click =" toggleRecoveryCodes"
301275 class =" group flex h-10 cursor-pointer items-center justify-between px-5 text-xs select-none"
@@ -311,12 +285,14 @@ const toggleRecoveryCodes = () => {
311285
312286 <Form
313287 v-if =" showingRecoveryCodes"
314- ref =" regenerateFormRef"
315288 :action =" route('two-factor.recovery-codes')"
316289 method =" post"
317290 #default =" { processing }"
291+ :options =" {
292+ preserveScroll: true,
293+ }"
318294 >
319- <Button size =" sm" variant =" outline " class =" text-stone-600 " type =" submit" :disabled =" processing" @click.stop >
295+ <Button size =" sm" variant =" ghost " class =" text-underline " type =" submit" :disabled =" processing" @click.stop >
320296 {{ processing ? 'Regenerating...' : 'Regenerate Codes' }}
321297 </Button >
322298 </Form >
@@ -329,10 +305,10 @@ const toggleRecoveryCodes = () => {
329305 opacity: showingRecoveryCodes ? 1 : 0,
330306 }"
331307 >
332- <div class =" grid max-w-xl gap-1 bg-stone-200 px -4 py-4 font-mono text-sm dark:bg-stone-900 dark:text-stone-100 " >
308+ <div class =" grid max-w-xl gap-1 bg-secondary p -4 font-mono text-sm" >
333309 <div v-for =" (code, index) in props.recoveryCodes" :key =" index" >{{ code }}</div >
334310 </div >
335- <p class =" px-4 py-3 text-xs text-stone-500 select-none dark:text-stone-400 " >
311+ <p class =" px-4 py-3 text-xs text-muted-foreground select-none" >
336312 You have {{ props.recoveryCodes.length }} recovery codes left. Each can be used once to access your account and
337313 will be removed after use. If you need more, click <span class =" font-bold" >Regenerate Codes</span > above.
338314 </p >
@@ -342,11 +318,9 @@ const toggleRecoveryCodes = () => {
342318
343319 <div class =" relative inline" >
344320 <Form
345- ref =" disableFormRef"
346321 :action =" route('two-factor.disable')"
347322 method =" delete"
348- @success =" handleDisableSuccess"
349- @error =" handleDisableError"
323+ async =" true"
350324 #default =" { processing }"
351325 >
352326 <Button variant =" destructive" type =" submit" :disabled =" processing" >
0 commit comments