diff --git a/app/Livewire/Auth/Register.php b/app/Livewire/Auth/Register.php new file mode 100644 index 0000000..1152b1d --- /dev/null +++ b/app/Livewire/Auth/Register.php @@ -0,0 +1,92 @@ + 'Daftar Akun', +])] +class Register extends Component +{ + public RegisterForm $form; + + public array $steps = []; + + public int $currentStep = 1; + + public int $totalSteps = 2; + + public function mount() + { + $this->steps = [ + ['id' => 1, 'name' => 'Kredensial'], + ['id' => 2, 'name' => 'Informasi'], + ]; + } + + public function updateStep(int $value) + { + if ($this->currentStep === 1) { + $this->form->validateStep1(); + } + + $this->currentStep = $value; + } + + public function nextStep() + { + match ($this->currentStep) { + 1 => $this->form->validateStep1(), + 2 => $this->form->validateStep2(), + default => null, + }; + + if ($this->currentStep < $this->totalSteps) { + $this->currentStep++; + } + } + + public function prevStep() + { + if ($this->currentStep > 1) { + $this->currentStep--; + } + } + + public function updated(string $propertyName, $value) + { + $field = Str::replace('form.', '', $propertyName); + + if (array_key_exists($field, $this->form->rulesStep1())) { + $this->validateOnly($propertyName, $this->form->rulesStep1()); + } + + if (array_key_exists($field, $this->form->rulesStep2())) { + $this->validateOnly($propertyName, $this->form->rulesStep2()); + } + } + + public function register() + { + $this->form->auth(); + + Flux::toast( + heading: 'Berhasil', + text: 'Selamat, akun Anda berhasil didaftarkan. Silakan cek email Anda untuk melakukan verifikasi.', + variant: 'success', + duration: 3000 + ); + + $this->redirectIntended('/customer/dashboard/overview', navigate: true); + } + + public function render() + { + return view('livewire.auth.register'); + } +} diff --git a/app/Livewire/Forms/RegisterForm.php b/app/Livewire/Forms/RegisterForm.php new file mode 100644 index 0000000..b4c1f5b --- /dev/null +++ b/app/Livewire/Forms/RegisterForm.php @@ -0,0 +1,140 @@ + ['required', 'email', 'max:100', Rule::unique('users', 'email')], + 'username' => ['required', 'alpha_num', 'min:5', 'max:20', Rule::unique('users', 'username')], + 'password' => [ + 'required', + 'string', + 'min:8', + Password::min(8)->letters()->mixedCase() + ->numbers() + ->symbols() + ->uncompromised(), + ], + ]; + } + + public function rulesStep2(): array + { + return [ + 'name' => ['required', 'string', 'max:50'], + 'phone_number' => ['required', 'string', new PhoneNumber], + 'gender' => ['required', Rule::in(Gender::values())], + 'referral_code' => ['nullable', 'string', Rule::exists('referral_codes', 'code')], + ]; + } + + public function validateStep1() + { + $this->validate($this->rulesStep1()); + } + + public function validateStep2() + { + $this->validate($this->rulesStep2()); + } + + public function validateAll() + { + $this->validate(array_merge( + $this->rulesStep1(), + $this->rulesStep2() + )); + } + + public function validationAttributes(): array + { + return [ + 'username' => 'nama pengguna', + 'password' => 'kata sandi', + 'name' => 'nama', + 'phone_number' => 'nomor telepon', + 'gender' => 'jenis kelamin', + ]; + } + + public function auth() + { + $this->validateAll(); + + $tier = Tier::orderBy('min_points')->first(); + $maxUser = User::max('id') + 1; + $referralCode = ReferralCode::where('code', $this->referral_code)->first(); + + DB::transaction(function () use ($tier, $maxUser, $referralCode) { + $user = User::create([ + 'email' => $this->email, + 'username' => $this->username, + 'password' => Hash::make($this->password), + 'status' => UserStatus::ACTIVE, + ]); + + Customer::create([ + 'user_id' => $user->id, + 'name' => $this->name, + 'phone_number' => $this->phone_number, + 'gender' => $this->gender, + ]); + + Membership::create([ + 'user_id' => $user->id, + 'tier_id' => $tier->id, + 'total_points' => 0, + ]); + + ReferralCode::create([ + 'user_id' => $user->id, + 'code' => generateReferralCode($this->username, $maxUser), + ]); + + if ($this->referral_code) { + ReferralUsage::create([ + 'user_id' => $user->id, + 'referral_code_id' => $referralCode->id, + ]); + + $referralCode->update(['uses_count', $referralCode->uses_count + 1]); + } + + auth()->login($user); + + $user->sendEmailVerificationNotification(); + }); + } +} diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 4ef026a..b2daeb4 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -18,6 +18,7 @@ public function up(): void $table->string('username', 20)->unique(); $table->string('password', 97); $table->enum('status', [UserStatus::values()])->default(UserStatus::ACTIVE)->comment(UserStatus::comment()); + $table->timestamp('email_verified_at')->nullable(); $table->timestamp('last_login_at')->nullable(); $table->timestamp('last_password_change_at')->nullable(); $table->timestamps(); diff --git a/resources/views/livewire/auth/login.blade.php b/resources/views/livewire/auth/login.blade.php index d12ddd5..b5f947a 100644 --- a/resources/views/livewire/auth/login.blade.php +++ b/resources/views/livewire/auth/login.blade.php @@ -36,6 +36,11 @@ class="size-8 rounded shrink-0 bg-accent text-accent-foreground flex items-cente Masuk + + Nikmati berbagai keuntungan! Daftar + sekarang. + + diff --git a/resources/views/livewire/auth/register.blade.php b/resources/views/livewire/auth/register.blade.php new file mode 100644 index 0000000..743ad18 --- /dev/null +++ b/resources/views/livewire/auth/register.blade.php @@ -0,0 +1,130 @@ +
+
+
+
+ + +
+ YD +
+
+
+
+ + Halo! + + Silakan ikuti langkah-langkah berikut untuk membuat akun dan nikmati keuntungannya dengan menjadi + member. + + +
    + @foreach ($steps as $step) +
  • + + + {{ $step['id'] }} + + +
    + Step + + {{ $step['name'] }} + +
    +
  • + @endforeach +
+ + @if ($currentStep === 1) +
+ + Email + + Pastikan email aktif karena akan digunakan untuk verifikasi. + + + + + + + + + + +
+ @endif + + @if ($currentStep === 2) +
+ + + + + + @foreach (\App\Enums\Gender::cases() as $gender) + + {{ $gender->label() }} + + @endforeach + + + +
+ @endif + +
+ @if ($currentStep > 1) + + Sebelumnya + + @else +
+ @endif + + @if ($currentStep < $totalSteps) + + Selanjutnya + + @else + + Daftar Sekarang + + @endif +
+ + + Sudah punya akun? Masuk sekarang. + + +
+
+ +
+
+
+ + + + + +
+ +
+ Bergabunglah dengan ribuan pelanggan yang puas dengan produk parfum berkualitas kami. +
+
+
+
diff --git a/routes/web.php b/routes/web.php index 511b246..8c3418b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -2,6 +2,7 @@ use App\Livewire\Auth\Login; use App\Livewire\Auth\Logout; +use App\Livewire\Auth\Register; use App\Livewire\Studio\Catalog\Brand as BrandComponent; use App\Livewire\Studio\Catalog\Category as CategoryComponent; use App\Livewire\Studio\Dashboard\Overview; @@ -16,6 +17,8 @@ use App\Livewire\Studio\Master\User\Create as UserCreate; use App\Livewire\Studio\Master\User\Edit as UserEdit; use App\Livewire\Studio\Master\User\Index as UserIndex; +use Illuminate\Foundation\Auth\EmailVerificationRequest; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; require __DIR__.'/customer.php'; @@ -28,9 +31,27 @@ ->prefix('auth') ->group(function () { Route::get('login', Login::class)->name('login'); + Route::get('register', Register::class)->name('register'); }); + Route::get('logout', Logout::class)->name('logout')->middleware('auth'); +Route::get('/email/verify', function () { + return view('auth.verify-email'); +})->middleware('auth')->name('verification.notice'); + +Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) { + $request->fulfill(); + + return redirect('/'); +})->middleware(['auth', 'signed'])->name('verification.verify'); + +Route::post('/email/verification-notification', function (Request $request) { + $request->user()->sendEmailVerificationNotification(); + + return back()->with('message', 'Verification link sent!'); +})->middleware(['auth', 'throttle:6,1'])->name('verification.send'); + Route::middleware('auth') ->prefix('studio') ->group(function () { diff --git a/vite.config.js b/vite.config.js index 29fbfe9..808c862 100644 --- a/vite.config.js +++ b/vite.config.js @@ -6,7 +6,7 @@ export default defineConfig({ plugins: [ laravel({ input: ['resources/css/app.css', 'resources/js/app.js'], - refresh: true, + // refresh: true, }), tailwindcss(), ],