refactor(auth): menggunakan class form, menyesuaikan view dan test atas pemindahan tersebut
This commit is contained in:
parent
13dfa28d6e
commit
8dcc57673d
@ -2,10 +2,11 @@
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use App\Livewire\Forms\Auth\ForgotPasswordForm;
|
||||
use App\Traits\WithToast;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\View\View;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth', [
|
||||
@ -15,15 +16,14 @@ class ForgotPassword extends Component
|
||||
{
|
||||
use WithToast;
|
||||
|
||||
#[Validate(['required', 'string'])]
|
||||
public string $email = '';
|
||||
public ForgotPasswordForm $form;
|
||||
|
||||
public function sendLink()
|
||||
public function sendLink(): mixed
|
||||
{
|
||||
$this->validate();
|
||||
$this->form->validate();
|
||||
|
||||
$status = Password::sendResetLink(
|
||||
$this->only('email')
|
||||
['form.email' => $this->form->email]
|
||||
);
|
||||
|
||||
return $status === Password::ResetLinkSent
|
||||
@ -31,7 +31,7 @@ public function sendLink()
|
||||
: $this->toast(__($status), 'Gagal', 'danger');
|
||||
}
|
||||
|
||||
public function render()
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.auth.forgot-password');
|
||||
}
|
||||
|
||||
@ -3,9 +3,12 @@
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use App\Enums\UserStatus;
|
||||
use App\Livewire\Forms\Auth\LoginForm;
|
||||
use App\Models\User;
|
||||
use App\Traits\WithToast;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\View\View;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.auth', [
|
||||
@ -15,13 +18,9 @@ class Login extends Component
|
||||
{
|
||||
use WithToast;
|
||||
|
||||
#[Validate(['required', 'string'], attribute: 'nama pengguna atau email')]
|
||||
public string $login = '';
|
||||
public LoginForm $form;
|
||||
|
||||
#[Validate('required', attribute: 'kata sandi')]
|
||||
public string $password = '';
|
||||
|
||||
public function mount()
|
||||
public function mount(): void
|
||||
{
|
||||
if (! request()->has('message')) {
|
||||
return;
|
||||
@ -36,9 +35,9 @@ public function mount()
|
||||
JS);
|
||||
}
|
||||
|
||||
public function auth()
|
||||
public function auth(): void
|
||||
{
|
||||
$this->validate();
|
||||
$this->form->validate();
|
||||
|
||||
if (! $this->attemptLogin()) {
|
||||
$this->toast('Oops! Nama pengguna, email, atau kata sandi tidak sesuai.', 'Gagal', 'danger');
|
||||
@ -49,7 +48,7 @@ public function auth()
|
||||
$user = auth()->user();
|
||||
|
||||
if (! $this->userIsActive($user)) {
|
||||
auth()->logout();
|
||||
Auth::logout();
|
||||
|
||||
$this->toast(
|
||||
'Akun Anda belum aktif. Mohon periksa email untuk mengaktifkan akun, dan hubungi kami jika memerlukan bantuan lebih lanjut.',
|
||||
@ -67,22 +66,22 @@ public function auth()
|
||||
$this->redirectByRole($user->roles->pluck('name')->toArray());
|
||||
}
|
||||
|
||||
protected function attemptLogin()
|
||||
protected function attemptLogin(): bool
|
||||
{
|
||||
$field = filter_var($this->login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
|
||||
$field = filter_var($this->form->login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
|
||||
|
||||
return auth()->attempt([
|
||||
$field => $this->login,
|
||||
'password' => $this->password,
|
||||
return Auth::attempt([
|
||||
$field => $this->form->login,
|
||||
'password' => $this->form->password,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function userIsActive($user)
|
||||
protected function userIsActive(?User $user): bool
|
||||
{
|
||||
return $user?->status === UserStatus::ACTIVE;
|
||||
}
|
||||
|
||||
protected function redirectByRole(array $roles)
|
||||
protected function redirectByRole(array $roles): void
|
||||
{
|
||||
if (array_intersect($roles, ['Developer', 'Owner', 'Leader', 'Admin'])) {
|
||||
$this->redirectIntended('/studio/dashboard/overview', navigate: true);
|
||||
@ -105,7 +104,7 @@ protected function redirectByRole(array $roles)
|
||||
$this->redirectIntended('/login', navigate: true);
|
||||
}
|
||||
|
||||
public function render()
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.auth.login');
|
||||
}
|
||||
|
||||
@ -2,11 +2,12 @@
|
||||
|
||||
namespace App\Livewire\Auth;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Livewire\Component;
|
||||
|
||||
class Logout extends Component
|
||||
{
|
||||
public function logout()
|
||||
public function logout(): void
|
||||
{
|
||||
auth()->logout();
|
||||
|
||||
@ -16,7 +17,7 @@ public function logout()
|
||||
$this->redirectRoute('login');
|
||||
}
|
||||
|
||||
public function render()
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.auth.logout');
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
use App\Traits\WithToast;
|
||||
use App\Traits\WithUpdatedData;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
@ -27,7 +28,7 @@ class Register extends Component
|
||||
|
||||
public int $totalSteps = 2;
|
||||
|
||||
public function mount()
|
||||
public function mount(): void
|
||||
{
|
||||
$this->steps = [
|
||||
['id' => 1, 'name' => 'Kredensial'],
|
||||
@ -35,7 +36,7 @@ public function mount()
|
||||
];
|
||||
}
|
||||
|
||||
public function updateStep(int $value)
|
||||
public function updateStep(int $value): void
|
||||
{
|
||||
if ($this->shouldValidateBeforeChangingStep()) {
|
||||
$this->form->validateStep1();
|
||||
@ -44,7 +45,7 @@ public function updateStep(int $value)
|
||||
$this->currentStep = $value;
|
||||
}
|
||||
|
||||
public function nextStep()
|
||||
public function nextStep(): void
|
||||
{
|
||||
match ($this->currentStep) {
|
||||
1 => $this->form->validateStep1(),
|
||||
@ -57,19 +58,19 @@ public function nextStep()
|
||||
}
|
||||
}
|
||||
|
||||
public function prevStep()
|
||||
public function prevStep(): void
|
||||
{
|
||||
if ($this->currentStep > 1) {
|
||||
$this->currentStep--;
|
||||
}
|
||||
}
|
||||
|
||||
public function updated(string $propertyName, $value)
|
||||
public function updated(string $propertyName, mixed $value): void
|
||||
{
|
||||
$this->validateUpdatedField($propertyName);
|
||||
}
|
||||
|
||||
public function register()
|
||||
public function register(): void
|
||||
{
|
||||
$this->form->auth();
|
||||
|
||||
@ -78,7 +79,7 @@ public function register()
|
||||
$this->redirectAfterRegistration();
|
||||
}
|
||||
|
||||
public function render()
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.auth.register');
|
||||
}
|
||||
@ -86,7 +87,7 @@ public function render()
|
||||
/**
|
||||
* Determine whether validation is required before changing step.
|
||||
*/
|
||||
protected function shouldValidateBeforeChangingStep()
|
||||
protected function shouldValidateBeforeChangingStep(): bool
|
||||
{
|
||||
return $this->currentStep === 1;
|
||||
}
|
||||
@ -94,7 +95,7 @@ protected function shouldValidateBeforeChangingStep()
|
||||
/**
|
||||
* Validate updated field based on current form step rules.
|
||||
*/
|
||||
protected function validateUpdatedField(string $propertyName)
|
||||
protected function validateUpdatedField(string $propertyName): void
|
||||
{
|
||||
$field = Str::replace('form.', '', $propertyName);
|
||||
|
||||
@ -110,7 +111,7 @@ protected function validateUpdatedField(string $propertyName)
|
||||
/**
|
||||
* Show success toast after registration.
|
||||
*/
|
||||
protected function sendRegistrationSuccessToast()
|
||||
protected function sendRegistrationSuccessToast(): void
|
||||
{
|
||||
$this->toast('Selamat, akun Anda berhasil didaftarkan. Silakan periksa email Anda untuk melakukan verifikasi.');
|
||||
}
|
||||
@ -118,7 +119,7 @@ protected function sendRegistrationSuccessToast()
|
||||
/**
|
||||
* Dispatch notification to privileged users when a new member registers.
|
||||
*/
|
||||
protected function notifyPrivilegedUsersAboutNewMember()
|
||||
protected function notifyPrivilegedUsersAboutNewMember(): void
|
||||
{
|
||||
$userIds = User::role(['Developer', 'Owner'])->pluck('id')->toArray();
|
||||
|
||||
@ -135,7 +136,7 @@ protected function notifyPrivilegedUsersAboutNewMember()
|
||||
/**
|
||||
* Redirect user after successful registration.
|
||||
*/
|
||||
protected function redirectAfterRegistration()
|
||||
protected function redirectAfterRegistration(): void
|
||||
{
|
||||
$this->redirectIntended('/member/overview', navigate: true);
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
use App\Livewire\Forms\Auth\ResetPasswordForm;
|
||||
use App\Traits\WithToast;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\View\View;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Url;
|
||||
use Livewire\Component;
|
||||
@ -19,17 +20,17 @@ class ResetPassword extends Component
|
||||
public ResetPasswordForm $form;
|
||||
|
||||
#[Url]
|
||||
public $token = '';
|
||||
public string $token = '';
|
||||
|
||||
#[Url]
|
||||
public $email = '';
|
||||
public string $email = '';
|
||||
|
||||
public function mount()
|
||||
public function mount(): void
|
||||
{
|
||||
$this->form->setTokenAndEmail($this->token, $this->email);
|
||||
}
|
||||
|
||||
public function resetPassword()
|
||||
public function resetPassword(): mixed
|
||||
{
|
||||
$status = $this->form->store();
|
||||
|
||||
@ -40,7 +41,7 @@ public function resetPassword()
|
||||
: $this->toast(__($status), 'Gagal', 'danger');
|
||||
}
|
||||
|
||||
public function render()
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.auth.reset-password');
|
||||
}
|
||||
|
||||
24
app/Livewire/Forms/Auth/ForgotPasswordForm.php
Normal file
24
app/Livewire/Forms/Auth/ForgotPasswordForm.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Forms\Auth;
|
||||
|
||||
use Livewire\Form;
|
||||
|
||||
class ForgotPasswordForm extends Form
|
||||
{
|
||||
public string $email = '';
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'email' => ['required', 'string', 'email'],
|
||||
];
|
||||
}
|
||||
|
||||
public function validationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'email' => 'email',
|
||||
];
|
||||
}
|
||||
}
|
||||
28
app/Livewire/Forms/Auth/LoginForm.php
Normal file
28
app/Livewire/Forms/Auth/LoginForm.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Forms\Auth;
|
||||
|
||||
use Livewire\Form;
|
||||
|
||||
class LoginForm extends Form
|
||||
{
|
||||
public string $login = '';
|
||||
|
||||
public string $password = '';
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'login' => ['required', 'string'],
|
||||
'password' => ['required'],
|
||||
];
|
||||
}
|
||||
|
||||
public function validationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'login' => 'nama pengguna atau email',
|
||||
'password' => 'kata sandi',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -62,17 +62,17 @@ public function rulesStep2(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function validateStep1()
|
||||
public function validateStep1(): void
|
||||
{
|
||||
$this->validate($this->rulesStep1());
|
||||
}
|
||||
|
||||
public function validateStep2()
|
||||
public function validateStep2(): void
|
||||
{
|
||||
$this->validate($this->rulesStep2());
|
||||
}
|
||||
|
||||
public function validateAll()
|
||||
public function validateAll(): void
|
||||
{
|
||||
$this->validate(array_merge(
|
||||
$this->rulesStep1(),
|
||||
@ -91,7 +91,7 @@ public function validationAttributes(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function auth()
|
||||
public function auth(): string
|
||||
{
|
||||
$this->validateAll();
|
||||
|
||||
@ -99,7 +99,7 @@ public function auth()
|
||||
$maxUser = User::max('id') + 1;
|
||||
$referralCode = ReferralCode::where('code', $this->referral_code)->first();
|
||||
|
||||
DB::transaction(function () use ($tier, $maxUser, $referralCode, &$customer) {
|
||||
DB::transaction(function () use ($tier, $maxUser, $referralCode, &$customer): void {
|
||||
$user = User::create([
|
||||
'email' => $this->email,
|
||||
'username' => $this->username,
|
||||
|
||||
@ -18,7 +18,7 @@ class ResetPasswordForm extends Form
|
||||
|
||||
public string $password_confirmation = '';
|
||||
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'token' => 'required',
|
||||
@ -36,13 +36,13 @@ public function validationAttributes(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function setTokenAndEmail(string $token, string $email)
|
||||
public function setTokenAndEmail(string $token, string $email): void
|
||||
{
|
||||
$this->token = $token;
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
public function store()
|
||||
public function store(): string
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
|
||||
@ -20,9 +20,9 @@ class="size-8 rounded shrink-0 bg-accent text-accent-foreground flex items-cente
|
||||
<div class="flex flex-col gap-6">
|
||||
<flux:field>
|
||||
<flux:label>Email <span class="text-red-500 ms-1">*</span></flux:label>
|
||||
<flux:input wire:model="email" type="text" placeholder="info.pangestuyoga@gmail.com"
|
||||
<flux:input wire:model="form.email" type="text" placeholder="info.pangestuyoga@gmail.com"
|
||||
autocomplete="off" />
|
||||
<flux:error name="email" />
|
||||
<flux:error name="form.email" />
|
||||
</flux:field>
|
||||
|
||||
<flux:button variant="primary" class="w-full cursor-pointer" wire:click="sendLink">Kirim Tautan
|
||||
|
||||
@ -20,9 +20,9 @@ class="size-8 rounded shrink-0 bg-accent text-accent-foreground flex items-cente
|
||||
<div class="flex flex-col gap-6">
|
||||
<flux:field>
|
||||
<flux:label>Nama Pengguna atau Email <span class="text-red-500 ms-1">*</span></flux:label>
|
||||
<flux:input wire:model="login" type="text" placeholder="johndoe / info.pangestuyoga@gmail.com"
|
||||
<flux:input wire:model="form.login" type="text" placeholder="johndoe / info.pangestuyoga@gmail.com"
|
||||
autocomplete="off" />
|
||||
<flux:error name="login" />
|
||||
<flux:error name="form.login" />
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
@ -34,9 +34,9 @@ class="size-8 rounded shrink-0 bg-accent text-accent-foreground flex items-cente
|
||||
sandi?</flux:link>
|
||||
</div>
|
||||
|
||||
<flux:input wire:model="password" type="password" placeholder="********" viewable />
|
||||
<flux:input wire:model="form.password" type="password" placeholder="********" viewable />
|
||||
|
||||
<flux:error name="password" />
|
||||
<flux:error name="form.password" />
|
||||
</flux:field>
|
||||
|
||||
<flux:button variant="primary" class="w-full cursor-pointer" wire:click="auth">Masuk</flux:button>
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
function attemptSendResetLink(string $email)
|
||||
{
|
||||
return Livewire::test(ForgotPassword::class)
|
||||
->set('email', $email)
|
||||
->set('form.email', $email)
|
||||
->call('sendLink');
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ function mockPasswordResetStatus(string $status, string $email = 'user@example.c
|
||||
{
|
||||
Password::shouldReceive('sendResetLink')
|
||||
->once()
|
||||
->with(['email' => $email])
|
||||
->with(['form.email' => $email])
|
||||
->andReturn($status);
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ function mockPasswordResetStatus(string $status, string $email = 'user@example.c
|
||||
it('renders forgot password component successfully', function () {
|
||||
Livewire::test(ForgotPassword::class)
|
||||
->assertViewIs('livewire.auth.forgot-password')
|
||||
->assertSet('email', '');
|
||||
->assertSet('form.email', '');
|
||||
});
|
||||
|
||||
/*
|
||||
@ -48,9 +48,9 @@ function mockPasswordResetStatus(string $status, string $email = 'user@example.c
|
||||
|
||||
it('validates email field is required', function () {
|
||||
Livewire::test(ForgotPassword::class)
|
||||
->set('email', '')
|
||||
->set('form.email', '')
|
||||
->call('sendLink')
|
||||
->assertHasErrors(['email' => 'required']);
|
||||
->assertHasErrors(['form.email' => 'required']);
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
@ -46,8 +46,8 @@ function makeUser(?string $role = null, bool $isActive = true): User
|
||||
function attemptLogin(string $login, string $password)
|
||||
{
|
||||
return Livewire::test(Login::class)
|
||||
->set('login', $login)
|
||||
->set('password', $password)
|
||||
->set('form.login', $login)
|
||||
->set('form.password', $password)
|
||||
->call('auth');
|
||||
}
|
||||
|
||||
@ -60,14 +60,14 @@ function attemptLogin(string $login, string $password)
|
||||
it('renders login component successfully', function () {
|
||||
Livewire::test(Login::class)
|
||||
->assertViewIs('livewire.auth.login')
|
||||
->assertSet('login', '')
|
||||
->assertSet('password', '');
|
||||
->assertSet('form.login', '')
|
||||
->assertSet('form.password', '');
|
||||
});
|
||||
|
||||
it('mounts component without query parameters', function () {
|
||||
Livewire::test(Login::class)
|
||||
->assertSet('login', '')
|
||||
->assertSet('password', '');
|
||||
->assertSet('form.login', '')
|
||||
->assertSet('form.password', '');
|
||||
});
|
||||
|
||||
it('mounts component with message query parameter', function () {
|
||||
@ -75,8 +75,8 @@ function attemptLogin(string $login, string $password)
|
||||
|
||||
Livewire::withQueryParams(['message' => $message])
|
||||
->test(Login::class)
|
||||
->assertSet('login', '')
|
||||
->assertSet('password', '');
|
||||
->assertSet('form.login', '')
|
||||
->assertSet('form.password', '');
|
||||
});
|
||||
|
||||
/*
|
||||
@ -87,26 +87,26 @@ function attemptLogin(string $login, string $password)
|
||||
|
||||
it('validates required fields', function () {
|
||||
Livewire::test(Login::class)
|
||||
->set('login', '')
|
||||
->set('password', '')
|
||||
->set('form.login', '')
|
||||
->set('form.password', '')
|
||||
->call('auth')
|
||||
->assertHasErrors(['login', 'password']);
|
||||
->assertHasErrors(['form.login', 'form.password']);
|
||||
});
|
||||
|
||||
it('validates login field is required', function () {
|
||||
Livewire::test(Login::class)
|
||||
->set('login', '')
|
||||
->set('password', 'password123')
|
||||
->set('form.login', '')
|
||||
->set('form.password', 'password123')
|
||||
->call('auth')
|
||||
->assertHasErrors(['login']);
|
||||
->assertHasErrors(['form.login']);
|
||||
});
|
||||
|
||||
it('validates password field is required', function () {
|
||||
Livewire::test(Login::class)
|
||||
->set('login', 'testuser')
|
||||
->set('password', '')
|
||||
->set('form.login', 'testuser')
|
||||
->set('form.password', '')
|
||||
->call('auth')
|
||||
->assertHasErrors(['password']);
|
||||
->assertHasErrors(['form.password']);
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
Loading…
Reference in New Issue
Block a user