Files
WMS/resources/views/livewire/auth/two-factor-challenge.blade.php
2026-09-21 13:19:22 +01:00

102 lines
5.2 KiB
PHP
Executable File

<x-layouts::auth :title="__('Two-factor authentication')">
<section
class="mx-auto w-full max-w-md overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-xl shadow-zinc-900/10 dark:border-zinc-800 dark:bg-zinc-950">
<div class="h-1.5 bg-gradient-to-r from-emerald-500 via-sky-500 to-blue-600"></div>
<div class="space-y-7 p-6 sm:p-8">
<div class="space-y-5 text-center">
<div
class="mx-auto flex h-14 w-14 items-center justify-center rounded-2xl bg-zinc-950 text-sm font-black text-white dark:bg-white dark:text-zinc-950">
WMS</div>
<div class="space-y-2">
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-sky-700 dark:text-sky-300">
{{ __('Multi-factor security') }}</p>
<h1 class="text-2xl font-bold tracking-tight text-zinc-950 dark:text-white">
{{ __('Verify your sign in') }}</h1>
<p class="text-sm leading-6 text-zinc-600 dark:text-zinc-400">
{{ __('Complete the security challenge to continue into WMS.') }}</p>
</div>
</div>
<div class="rounded-2xl border border-zinc-200 bg-zinc-50 p-5 dark:border-zinc-800 dark:bg-zinc-900/60">
<div class="relative w-full h-auto" x-cloak x-data="{
showRecoveryInput: @js($errors->has('recovery_code')),
code: '',
recovery_code: '',
focusOtp() {
this.$nextTick(() => this.$refs.otp?.querySelector('input')?.focus());
},
init() {
if (!this.showRecoveryInput) {
this.focusOtp();
}
},
toggleInput() {
this.showRecoveryInput = !this.showRecoveryInput;
this.code = '';
this.recovery_code = '';
$nextTick(() => {
this.showRecoveryInput ?
this.$refs.recovery_code?.focus() :
this.focusOtp();
});
},
}">
<div x-show="!showRecoveryInput">
<x-auth-header :title="__('Authentication code')" :description="__('Enter the authentication code provided by your authenticator application.')" />
</div>
<div x-show="showRecoveryInput">
<x-auth-header :title="__('Recovery code')" :description="__(
'Please confirm access to your account by entering one of your emergency recovery codes.',
)" />
</div>
<form method="POST" action="{{ route('two-factor.login.store') }}" class="mt-6">
@csrf
<div class="space-y-5 text-center">
<div x-show="!showRecoveryInput">
<div class="my-5 flex items-center justify-center" x-ref="otp">
<flux:otp x-model="code" length="6" name="code" label="OTP Code"
label:sr-only class="mx-auto" />
</div>
</div>
<div x-show="showRecoveryInput">
<div class="my-5">
<flux:input type="text" name="recovery_code" x-ref="recovery_code"
x-bind:required="showRecoveryInput" autocomplete="off"
x-model="recovery_code" />
</div>
@error('recovery_code')
<flux:text color="red">
{{ $message }}
</flux:text>
@enderror
</div>
<flux:button variant="primary" type="submit" class="w-full">
{{ __('Continue') }}
</flux:button>
</div>
<div class="mt-5 text-center text-sm leading-5 text-zinc-600 dark:text-zinc-400">
<span>{{ __('or you can') }}</span>
<button type="button"
class="inline font-semibold text-sky-700 underline underline-offset-4 hover:text-sky-900 dark:text-sky-300"
@click="toggleInput()">
<span x-show="!showRecoveryInput">{{ __('login using a recovery code') }}</span>
<span x-show="showRecoveryInput">{{ __('login using an authentication code') }}</span>
</button>
</div>
</form>
</div>
</div>
</div>
</section>
</x-layouts::auth>