fest(auth): implementasi fitur lupa kata sandi
This commit is contained in:
parent
8a30f8a782
commit
7f7d597116
38
app/Livewire/Auth/ForgotPassword.php
Normal file
38
app/Livewire/Auth/ForgotPassword.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use App\Traits\WithToast;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth', [
|
||||
'title' => 'Lupa Kata Sandi',
|
||||
])]
|
||||
class ForgotPassword extends Component
|
||||
{
|
||||
use WithToast;
|
||||
|
||||
#[Validate(['required', 'string'])]
|
||||
public string $email = '';
|
||||
|
||||
public function sendLink()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$status = Password::sendResetLink(
|
||||
$this->only('email')
|
||||
);
|
||||
|
||||
return $status === Password::ResetLinkSent
|
||||
? $this->toast(__($status), 'Berhasil')
|
||||
: $this->toast(__($status), 'Gagal', 'danger');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.auth.forgot-password');
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,18 @@ class Login extends Component
|
||||
#[Validate('required', attribute: 'kata sandi')]
|
||||
public string $password = '';
|
||||
|
||||
public function mount()
|
||||
{
|
||||
if (request()->has('message')) {
|
||||
$this->toast(request('message'));
|
||||
$this->js("
|
||||
const url = new URL(window.location);
|
||||
url.search = '';
|
||||
window.history.replaceState({}, '', url);
|
||||
");
|
||||
}
|
||||
}
|
||||
|
||||
public function auth()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
47
app/Livewire/Auth/ResetPassword.php
Normal file
47
app/Livewire/Auth/ResetPassword.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use App\Livewire\Forms\Auth\ResetPasswordForm;
|
||||
use App\Traits\WithToast;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Url;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth', [
|
||||
'title' => 'Atur Ulang Kata Sandi',
|
||||
])]
|
||||
class ResetPassword extends Component
|
||||
{
|
||||
use WithToast;
|
||||
|
||||
public ResetPasswordForm $form;
|
||||
|
||||
#[Url]
|
||||
public $token = '';
|
||||
|
||||
#[Url]
|
||||
public $email = '';
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->form->setTokenAndEmail($this->token, $this->email);
|
||||
}
|
||||
|
||||
public function resetPassword()
|
||||
{
|
||||
$status = $this->form->store();
|
||||
|
||||
return $status === Password::PasswordReset
|
||||
? $this->redirectRoute('login', [
|
||||
'message' => 'Kata sandi berhasil diperbarui, silakan masuk kembali.',
|
||||
], navigate: true)
|
||||
: $this->toast(__($status), 'Gagal', 'danger');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.auth.reset-password');
|
||||
}
|
||||
}
|
||||
64
app/Livewire/Forms/Auth/ResetPasswordForm.php
Normal file
64
app/Livewire/Forms/Auth/ResetPasswordForm.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Forms\Auth;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Livewire\Form;
|
||||
|
||||
class ResetPasswordForm extends Form
|
||||
{
|
||||
public string $token = '';
|
||||
|
||||
public string $email = '';
|
||||
|
||||
public string $password = '';
|
||||
|
||||
public string $password_confirmation = '';
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'token' => 'required',
|
||||
'email' => ['required', 'email'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
'password_confirmation' => ['required', 'string', 'min:8', 'same:password'],
|
||||
];
|
||||
}
|
||||
|
||||
public function validationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'password' => 'kata sandi',
|
||||
'password_confirmation' => 'konfirmasi kata sandi',
|
||||
];
|
||||
}
|
||||
|
||||
public function setTokenAndEmail(string $token, string $email)
|
||||
{
|
||||
$this->token = $token;
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$status = Password::reset(
|
||||
$this->only('email', 'password', 'password_confirmation', 'token'),
|
||||
function (User $user, string $password) {
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($password),
|
||||
]);
|
||||
|
||||
$user->save();
|
||||
|
||||
event(new PasswordReset($user));
|
||||
}
|
||||
);
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Notifications\ResetPassword;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
@ -19,6 +21,8 @@ public function register(): void
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
ResetPassword::createUrlUsing(function (User $user, string $token) {
|
||||
return config('app.url').'/auth/reset-password?token='.$token.'&email='.$user->email;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
39
resources/views/livewire/auth/forgot-password.blade.php
Normal file
39
resources/views/livewire/auth/forgot-password.blade.php
Normal file
@ -0,0 +1,39 @@
|
||||
<div class="flex min-h-screen">
|
||||
<div class="flex-1 flex justify-center items-center">
|
||||
<div class="w-80 md:w-100 space-y-6">
|
||||
<div class="flex justify-center opacity-50">
|
||||
<flux:brand href="{{ route('homepage') }}" name="Yadi Parfum" wire:navigate.hover>
|
||||
<x-slot name="logo">
|
||||
<div
|
||||
class="size-8 rounded shrink-0 bg-accent text-accent-foreground flex items-center justify-center">
|
||||
<i class="font-serif font-bold">YD</i>
|
||||
</div>
|
||||
</x-slot>
|
||||
</flux:brand>
|
||||
</div>
|
||||
|
||||
<flux:heading size="lg" class="mb-1">Lupa Kata Sandi?</flux:heading>
|
||||
<flux:text>
|
||||
Silakan masukkan alamat email Anda. Kami akan mengirimkan instruksi untuk mengatur ulang kata sandi.
|
||||
</flux:text>
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<flux:input wire:model="email" label="Email" type="text" placeholder="info.pangestuyoga@gmail.com"
|
||||
autocomplete="off" />
|
||||
|
||||
<flux:button variant="primary" class="w-full cursor-pointer" wire:click="sendLink">Kirim Tautan
|
||||
</flux:button>
|
||||
</div>
|
||||
<flux:subheading class="text-center">
|
||||
Sudah ingat kata sandi? <flux:link href="{{ route('login') }}" wire:navigate.hover>Masuk
|
||||
</flux:link>
|
||||
</flux:subheading>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 p-4 max-lg:hidden">
|
||||
<div class="relative rounded-lg h-full w-full bg-zinc-100 flex flex-col items-start justify-end p-16 bg-cover bg-center bg-no-repeat"
|
||||
style="background-image: url('/assets/images/cover.jpg')">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -25,7 +25,9 @@ class="size-8 rounded shrink-0 bg-accent text-accent-foreground flex items-cente
|
||||
<div class="mb-3 flex justify-between">
|
||||
<flux:label>Kata Sandi</flux:label>
|
||||
|
||||
<flux:link href="#" variant="subtle" class="text-sm">Lupa kata sandi?</flux:link>
|
||||
<flux:link href="{{ route('password.request') }}" variant="subtle" class="text-sm"
|
||||
wire:navigate.hover>Lupa kata
|
||||
sandi?</flux:link>
|
||||
</div>
|
||||
|
||||
<flux:input wire:model="password" type="password" placeholder="********" viewable />
|
||||
|
||||
43
resources/views/livewire/auth/reset-password.blade.php
Normal file
43
resources/views/livewire/auth/reset-password.blade.php
Normal file
@ -0,0 +1,43 @@
|
||||
<div class="flex min-h-screen">
|
||||
<div class="flex-1 flex justify-center items-center">
|
||||
<div class="w-80 md:w-100 space-y-6">
|
||||
<div class="flex justify-center opacity-50">
|
||||
<flux:brand href="{{ route('homepage') }}" name="Yadi Parfum" wire:navigate.hover>
|
||||
<x-slot name="logo">
|
||||
<div
|
||||
class="size-8 rounded shrink-0 bg-accent text-accent-foreground flex items-center justify-center">
|
||||
<i class="font-serif font-bold">YD</i>
|
||||
</div>
|
||||
</x-slot>
|
||||
</flux:brand>
|
||||
</div>
|
||||
|
||||
<flux:heading size="lg" class="mb-1">Atur Ulang Kata Sandi</flux:heading>
|
||||
<flux:text>
|
||||
Silakan masukkan kata sandi baru Anda untuk mengatur ulang kata sandi Anda.
|
||||
</flux:text>
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<flux:input label="Kata Sandi" wire:model="form.password" type="password" placeholder="********"
|
||||
viewable />
|
||||
|
||||
<flux:input label="Konfirmasi Kata Sandi" wire:model="form.password_confirmation" type="password"
|
||||
placeholder="********" viewable />
|
||||
|
||||
<flux:button variant="primary" class="w-full cursor-pointer" wire:click="resetPassword">Atur Ulang
|
||||
</flux:button>
|
||||
</div>
|
||||
|
||||
<flux:subheading class="text-center">
|
||||
Sudah ingat kata sandi? <flux:link href="{{ route('login') }}" wire:navigate.hover>Masuk
|
||||
</flux:link>
|
||||
</flux:subheading>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 p-4 max-lg:hidden">
|
||||
<div class="relative rounded-lg h-full w-full bg-zinc-100 flex flex-col items-start justify-end p-16 bg-cover bg-center bg-no-repeat"
|
||||
style="background-image: url('/assets/images/cover.jpg')">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1,8 +1,10 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Auth\ForgotPassword as ForgotPasswordComponent;
|
||||
use App\Livewire\Auth\Login as LoginComponent;
|
||||
use App\Livewire\Auth\Logout as LogoutComponent;
|
||||
use App\Livewire\Auth\Register as RegisterComponent;
|
||||
use App\Livewire\Auth\ResetPassword as ResetPasswordComponent;
|
||||
use Illuminate\Foundation\Auth\EmailVerificationRequest;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
@ -12,6 +14,10 @@
|
||||
->group(function () {
|
||||
Route::get('login', LoginComponent::class)->name('login');
|
||||
Route::get('register', RegisterComponent::class)->name('register');
|
||||
|
||||
Route::get('forgot-password', ForgotPasswordComponent::class)->name('password.request');
|
||||
|
||||
Route::get('reset-password', ResetPasswordComponent::class)->name('password.reset');
|
||||
});
|
||||
|
||||
Route::post('logout', LogoutComponent::class)->name('logout')->middleware('auth');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user