b2in/resources/views/livewire/auth/login-simple.blade.php
2025-10-20 17:50:35 +02:00

153 lines
4.9 KiB
PHP

<?php
use Illuminate\Auth\Events\Lockout;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Validate;
use Livewire\Volt\Component;
new #[Layout('components.layouts.auth')] class extends Component {
#[Validate('required|string|email')]
public string $email = '';
#[Validate('required|string')]
public string $password = '';
public bool $remember = false;
/**
* Handle an incoming authentication request.
*/
public function login(): void
{
$this->validate();
$this->ensureIsNotRateLimited();
if (! Auth::attempt(['email' => $this->email, 'password' => $this->password], $this->remember)) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
Session::regenerate();
$this->redirectIntended(default: route('dashboard', absolute: false), navigate: true);
}
/**
* Ensure the authentication request is not rate limited.
*/
protected function ensureIsNotRateLimited(): void
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout(request()));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
/**
* Get the authentication rate limiting throttle key.
*/
protected function throttleKey(): string
{
return Str::transliterate(Str::lower($this->email).'|'.request()->ip());
}
}; ?>
<div class="flex flex-col gap-6 p-8 bg-white rounded-lg shadow-lg">
<div class="text-center">
<h1 class="text-2xl font-bold text-gray-900">Log in to your account</h1>
<p class="text-gray-600 mt-2">Enter your email and password below to log in</p>
</div>
<!-- Session Status -->
@if (session('status'))
<div class="text-center text-sm text-green-600">
{{ session('status') }}
</div>
@endif
<form wire:submit="login" class="flex flex-col gap-6">
<!-- Email Address -->
<div>
<label for="email" class="block text-sm font-medium text-gray-700">Email address</label>
<input
wire:model="email"
id="email"
type="email"
required
autofocus
autocomplete="email"
placeholder="email@example.com"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
/>
@error('email')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Password -->
<div class="relative">
<label for="password" class="block text-sm font-medium text-gray-700">Password</label>
<input
wire:model="password"
id="password"
type="password"
required
autocomplete="current-password"
placeholder="Password"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
/>
@error('password')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
@if (Route::has('password.request'))
<a href="{{ route('password.request') }}" class="absolute right-0 top-0 text-sm text-blue-600 hover:text-blue-500">
Forgot your password?
</a>
@endif
</div>
<!-- Remember Me -->
<div class="flex items-center">
<input
wire:model="remember"
id="remember"
type="checkbox"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<label for="remember" class="ml-2 block text-sm text-gray-900">Remember me</label>
</div>
<button type="submit" class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
Log in
</button>
</form>
@if (Route::has('register'))
<div class="text-center text-sm text-gray-600">
Don't have an account?
<a href="{{ route('register') }}" class="text-blue-600 hover:text-blue-500">Sign up</a>
</div>
@endif
</div>