diff --git a/app/Livewire/Settings/Appearance.php b/app/Livewire/Settings/Appearance.php
deleted file mode 100644
index 7550e32..0000000
--- a/app/Livewire/Settings/Appearance.php
+++ /dev/null
@@ -1,12 +0,0 @@
-validate([
- 'password' => $this->currentPasswordRules(),
- ]);
-
- tap(Auth::user(), $logout(...))->delete();
-
- $this->redirect('/', navigate: true);
- }
-}
diff --git a/app/Livewire/Settings/Profile.php b/app/Livewire/Settings/Profile.php
deleted file mode 100644
index db7bf31..0000000
--- a/app/Livewire/Settings/Profile.php
+++ /dev/null
@@ -1,81 +0,0 @@
-name = Auth::user()->name;
- $this->email = Auth::user()->email;
- }
-
- /**
- * Update the profile information for the currently authenticated user.
- */
- public function updateProfileInformation(): void
- {
- $user = Auth::user();
-
- $validated = $this->validate($this->profileRules($user->id));
-
- $user->fill($validated);
-
- if ($user->isDirty('email')) {
- $user->email_verified_at = null;
- }
-
- $user->save();
-
- Flux::toast(variant: 'success', text: __('Profile updated.'));
- }
-
- /**
- * Send an email verification notification to the current user.
- */
- public function resendVerificationNotification(): void
- {
- $user = Auth::user();
-
- if ($user->hasVerifiedEmail()) {
- $this->redirectIntended(default: route('dashboard', absolute: false));
-
- return;
- }
-
- $user->sendEmailVerificationNotification();
-
- Flux::toast(text: __('A new verification link has been sent to your email address.'));
- }
-
- #[Computed]
- public function hasUnverifiedEmail(): bool
- {
- return Auth::user() instanceof MustVerifyEmail && ! Auth::user()->hasVerifiedEmail();
- }
-
- #[Computed]
- public function showDeleteUser(): bool
- {
- return ! Auth::user() instanceof MustVerifyEmail
- || (Auth::user() instanceof MustVerifyEmail && Auth::user()->hasVerifiedEmail());
- }
-}
diff --git a/app/Livewire/Settings/Security.php b/app/Livewire/Settings/Security.php
deleted file mode 100644
index 3edf160..0000000
--- a/app/Livewire/Settings/Security.php
+++ /dev/null
@@ -1,225 +0,0 @@
-canManageTwoFactor = Features::canManageTwoFactorAuthentication();
-
- if ($this->canManageTwoFactor) {
- if (Fortify::confirmsTwoFactorAuthentication() && is_null(auth()->user()->two_factor_confirmed_at)) {
- $disableTwoFactorAuthentication(auth()->user());
- }
-
- $this->twoFactorEnabled = auth()->user()->hasEnabledTwoFactorAuthentication();
- $this->requiresConfirmation = Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm');
- }
- }
-
- /**
- * Update the password for the currently authenticated user.
- */
- public function updatePassword(): void
- {
- try {
- $validated = $this->validate([
- 'current_password' => $this->currentPasswordRules(),
- 'password' => $this->passwordRules(),
- ]);
- } catch (ValidationException $e) {
- $this->reset('current_password', 'password', 'password_confirmation');
-
- throw $e;
- }
-
- Auth::user()->update([
- 'password' => $validated['password'],
- ]);
-
- $this->reset('current_password', 'password', 'password_confirmation');
-
- Flux::toast(variant: 'success', text: __('Password updated.'));
- }
-
- /**
- * Enable two-factor authentication for the user.
- */
- public function enable(EnableTwoFactorAuthentication $enableTwoFactorAuthentication): void
- {
- $enableTwoFactorAuthentication(auth()->user());
-
- if (! $this->requiresConfirmation) {
- $this->twoFactorEnabled = auth()->user()->hasEnabledTwoFactorAuthentication();
- }
-
- $this->loadSetupData();
-
- $this->showModal = true;
- }
-
- /**
- * Load the two-factor authentication setup data for the user.
- */
- private function loadSetupData(): void
- {
- $user = auth()->user();
-
- try {
- $this->qrCodeSvg = $user?->twoFactorQrCodeSvg();
- $this->manualSetupKey = decrypt($user->two_factor_secret);
- } catch (Exception) {
- $this->addError('setupData', 'Failed to fetch setup data.');
-
- $this->reset('qrCodeSvg', 'manualSetupKey');
- }
- }
-
- /**
- * Show the two-factor verification step if necessary.
- */
- public function showVerificationIfNecessary(): void
- {
- if ($this->requiresConfirmation) {
- $this->showVerificationStep = true;
-
- $this->resetErrorBag();
-
- return;
- }
-
- $this->closeModal();
- }
-
- /**
- * Close the two-factor authentication modal.
- */
- public function closeModal(): void
- {
- $this->reset(
- 'code',
- 'manualSetupKey',
- 'qrCodeSvg',
- 'showModal',
- 'showVerificationStep',
- );
-
- $this->resetErrorBag();
-
- if (! $this->requiresConfirmation) {
- $this->twoFactorEnabled = auth()->user()->hasEnabledTwoFactorAuthentication();
- }
- }
-
- /**
- * Confirm two-factor authentication for the user.
- */
- public function confirmTwoFactor(ConfirmTwoFactorAuthentication $confirmTwoFactorAuthentication): void
- {
- $this->validate();
-
- $confirmTwoFactorAuthentication(auth()->user(), $this->code);
-
- $this->closeModal();
-
- $this->twoFactorEnabled = true;
- }
-
- /**
- * Reset two-factor verification state.
- */
- public function resetVerification(): void
- {
- $this->reset('code', 'showVerificationStep');
-
- $this->resetErrorBag();
- }
-
- /**
- * Disable two-factor authentication for the user.
- */
- public function disable(DisableTwoFactorAuthentication $disableTwoFactorAuthentication): void
- {
- $disableTwoFactorAuthentication(auth()->user());
-
- $this->twoFactorEnabled = false;
- }
-
- /**
- * Get the current modal configuration state.
- */
- public function getModalConfigProperty(): array
- {
- if ($this->twoFactorEnabled) {
- return [
- 'title' => __('Two-factor authentication enabled'),
- 'description' => __('Two-factor authentication is now enabled. Scan the QR code or enter the setup key in your authenticator app.'),
- 'buttonText' => __('Close'),
- ];
- }
-
- if ($this->showVerificationStep) {
- return [
- 'title' => __('Verify authentication code'),
- 'description' => __('Enter the 6-digit code from your authenticator app.'),
- 'buttonText' => __('Continue'),
- ];
- }
-
- return [
- 'title' => __('Enable two-factor authentication'),
- 'description' => __('To finish enabling two-factor authentication, scan the QR code or enter the setup key in your authenticator app.'),
- 'buttonText' => __('Continue'),
- ];
- }
-}
diff --git a/app/Livewire/Settings/TwoFactor/RecoveryCodes.php b/app/Livewire/Settings/TwoFactor/RecoveryCodes.php
deleted file mode 100644
index ae0acba..0000000
--- a/app/Livewire/Settings/TwoFactor/RecoveryCodes.php
+++ /dev/null
@@ -1,50 +0,0 @@
-loadRecoveryCodes();
- }
-
- /**
- * Load the recovery codes for the user.
- */
- private function loadRecoveryCodes(): void
- {
- $user = auth()->user();
-
- if ($user->hasEnabledTwoFactorAuthentication() && $user->two_factor_recovery_codes) {
- try {
- $this->recoveryCodes = json_decode(decrypt($user->two_factor_recovery_codes), true);
- } catch (Exception) {
- $this->addError('recoveryCodes', 'Failed to load recovery codes');
-
- $this->recoveryCodes = [];
- }
- }
- }
-
- /**
- * Generate new recovery codes for the user.
- */
- public function regenerateRecoveryCodes(GenerateNewRecoveryCodes $generateNewRecoveryCodes): void
- {
- $generateNewRecoveryCodes(auth()->user());
-
- $this->loadRecoveryCodes();
- }
-}
diff --git a/resources/views/components/settings/layout.blade.php b/resources/views/components/settings/layout.blade.php
deleted file mode 100644
index 3a65247..0000000
--- a/resources/views/components/settings/layout.blade.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- {{ __('Profile') }}
- {{ __('Security') }}
- {{ __('Appearance') }}
-
-
-
-
-
-
-
{{ $heading ?? '' }}
-
{{ $subheading ?? '' }}
-
-
- {{ $slot }}
-
-
-
diff --git a/resources/views/livewire/settings/appearance.blade.php b/resources/views/livewire/settings/appearance.blade.php
deleted file mode 100644
index 86c7ec7..0000000
--- a/resources/views/livewire/settings/appearance.blade.php
+++ /dev/null
@@ -1,13 +0,0 @@
-
- @include('partials.settings-heading')
-
- {{ __('Appearance settings') }}
-
-
-
- {{ __('Light') }}
- {{ __('Dark') }}
- {{ __('System') }}
-
-
-
diff --git a/resources/views/livewire/settings/delete-user-form.blade.php b/resources/views/livewire/settings/delete-user-form.blade.php
deleted file mode 100644
index a641407..0000000
--- a/resources/views/livewire/settings/delete-user-form.blade.php
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
- {{ __('Delete account') }}
- {{ __('Delete your account and all of its resources') }}
-
-
-
-
- {{ __('Delete account') }}
-
-
-
-
-
-
-
diff --git a/resources/views/livewire/settings/profile.blade.php b/resources/views/livewire/settings/profile.blade.php
deleted file mode 100644
index 6e9da81..0000000
--- a/resources/views/livewire/settings/profile.blade.php
+++ /dev/null
@@ -1,36 +0,0 @@
-
- @include('partials.settings-heading')
-
- {{ __('Profile settings') }}
-
-
-
-
- @if ($this->showDeleteUser)
-
- @endif
-
-
diff --git a/resources/views/livewire/settings/security.blade.php b/resources/views/livewire/settings/security.blade.php
deleted file mode 100644
index 7beea38..0000000
--- a/resources/views/livewire/settings/security.blade.php
+++ /dev/null
@@ -1,233 +0,0 @@
-
- @include('partials.settings-heading')
-
- {{ __('Security settings') }}
-
-
-
-
- @if ($canManageTwoFactor)
-
- {{ __('Two-factor authentication') }}
- {{ __('Manage your two-factor authentication settings') }}
-
-
- @if ($twoFactorEnabled)
-
-
- {{ __('You will be prompted for a secure, random pin during login, which you can retrieve from the TOTP-supported application on your phone.') }}
-
-
-
-
- {{ __('Disable 2FA') }}
-
-
-
-
-
- @else
-
-
- {{ __('When you enable two-factor authentication, you will be prompted for a secure pin during login. This pin can be retrieved from a TOTP-supported application on your phone.') }}
-
-
-
- {{ __('Enable 2FA') }}
-
-
- @endif
-
-
-
-
-
-
-
-
-
- @for ($i = 1; $i <= 5; $i++)
-
- @endfor
-
-
-
- @for ($i = 1; $i <= 5; $i++)
-
- @endfor
-
-
-
-
-
-
-
- {{ $this->modalConfig['title'] }}
- {{ $this->modalConfig['description'] }}
-
-
-
- @if ($showVerificationStep)
-
-
-
-
-
-
-
- {{ __('Back') }}
-
-
-
- {{ __('Confirm') }}
-
-
-
- @else
- @error('setupData')
-
- @enderror
-
-
-
- @empty($qrCodeSvg)
-
-
-
- @else
-
-
- {!! $qrCodeSvg !!}
-
-
- @endempty
-
-
-
-
-
- {{ $this->modalConfig['buttonText'] }}
-
-
-
-
-
-
-
- {{ __('or, enter the code manually') }}
-
-
-
-
-
- @empty($manualSetupKey)
-
-
-
- @else
-
-
-
-
-
-
- @endempty
-
-
-
- @endif
-
-
- @endif
-
-
diff --git a/resources/views/livewire/settings/two-factor/recovery-codes.blade.php b/resources/views/livewire/settings/two-factor/recovery-codes.blade.php
deleted file mode 100644
index 9ed2674..0000000
--- a/resources/views/livewire/settings/two-factor/recovery-codes.blade.php
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
- {{ __('2FA recovery codes') }}
-
-
- {{ __('Recovery codes let you regain access if you lose your 2FA device. Store them in a secure password manager.') }}
-
-
-
-
-
-
- {{ __('View recovery codes') }}
-
-
-
- {{ __('Hide recovery codes') }}
-
-
- @if (filled($recoveryCodes))
-
- {{ __('Regenerate codes') }}
-
- @endif
-
-
-
-
- @error('recoveryCodes')
-
- @enderror
-
- @if (filled($recoveryCodes))
-
- @foreach($recoveryCodes as $code)
-
- {{ $code }}
-
- @endforeach
-
-
- {{ __('Each recovery code can be used once to access your account and will be removed after use. If you need more, click Regenerate codes above.') }}
-
- @endif
-
-
-
-
diff --git a/routes/settings.php b/routes/settings.php
deleted file mode 100644
index d533e34..0000000
--- a/routes/settings.php
+++ /dev/null
@@ -1,28 +0,0 @@
-group(function () {
- Route::redirect('settings', 'settings/profile');
-
- Route::livewire('settings/profile', Profile::class)->name('profile.edit');
-});
-
-Route::middleware(['auth', 'verified'])->group(function () {
- Route::livewire('settings/appearance', Appearance::class)->name('appearance.edit');
-
- Route::livewire('settings/security', Security::class)
- ->middleware(
- when(
- Features::canManageTwoFactorAuthentication()
- && Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword'),
- ['password.confirm'],
- [],
- ),
- )
- ->name('security.edit');
-});
diff --git a/routes/web.php b/routes/web.php
index 6b8bdc7..0ba2f7e 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -2,8 +2,6 @@
use Illuminate\Support\Facades\Route;
-require __DIR__.'/settings.php';
-
// Named dashboard route so route('dashboard') resolves; Vue Router handles rendering
Route::get('/dashboard', fn () => view('app'))->middleware(['auth', 'verified'])->name('dashboard');
diff --git a/tests/Feature/Settings/ProfileUpdateTest.php b/tests/Feature/Settings/ProfileUpdateTest.php
deleted file mode 100644
index e0b3742..0000000
--- a/tests/Feature/Settings/ProfileUpdateTest.php
+++ /dev/null
@@ -1,75 +0,0 @@
-actingAs($user = User::factory()->create());
-
- $this->get(route('profile.edit'))->assertOk();
-});
-
-test('profile information can be updated', function () {
- $user = User::factory()->create();
-
- $this->actingAs($user);
-
- $response = Livewire::test('pages::settings.profile')
- ->set('name', 'Test User')
- ->set('email', 'test@example.com')
- ->call('updateProfileInformation');
-
- $response->assertHasNoErrors();
-
- $user->refresh();
-
- expect($user->name)->toEqual('Test User');
- expect($user->email)->toEqual('test@example.com');
- expect($user->email_verified_at)->toBeNull();
-});
-
-test('email verification status is unchanged when email address is unchanged', function () {
- $user = User::factory()->create();
-
- $this->actingAs($user);
-
- $response = Livewire::test('pages::settings.profile')
- ->set('name', 'Test User')
- ->set('email', $user->email)
- ->call('updateProfileInformation');
-
- $response->assertHasNoErrors();
-
- expect($user->refresh()->email_verified_at)->not->toBeNull();
-});
-
-test('user can delete their account', function () {
- $user = User::factory()->create();
-
- $this->actingAs($user);
-
- $response = Livewire::test('pages::settings.delete-user-modal')
- ->set('password', 'password')
- ->call('deleteUser');
-
- $response
- ->assertHasNoErrors()
- ->assertRedirect('/');
-
- expect($user->fresh())->toBeNull();
- expect(auth()->check())->toBeFalse();
-});
-
-test('correct password must be provided to delete account', function () {
- $user = User::factory()->create();
-
- $this->actingAs($user);
-
- $response = Livewire::test('pages::settings.delete-user-modal')
- ->set('password', 'wrong-password')
- ->call('deleteUser');
-
- $response->assertHasErrors(['password']);
-
- expect($user->fresh())->not->toBeNull();
-});
\ No newline at end of file
diff --git a/tests/Feature/Settings/SecurityTest.php b/tests/Feature/Settings/SecurityTest.php
deleted file mode 100644
index fbf95c5..0000000
--- a/tests/Feature/Settings/SecurityTest.php
+++ /dev/null
@@ -1,104 +0,0 @@
-skipUnlessFortifyHas(Features::twoFactorAuthentication());
-
- Features::twoFactorAuthentication([
- 'confirm' => true,
- 'confirmPassword' => true,
- ]);
-});
-
-test('security settings page can be rendered', function () {
- $user = User::factory()->create();
-
- $this->actingAs($user)
- ->withSession(['auth.password_confirmed_at' => time()])
- ->get(route('security.edit'))
- ->assertOk()
- ->assertSee('Two-factor authentication')
- ->assertSee('Enable 2FA');
-});
-
-test('security settings page requires password confirmation when enabled', function () {
- $user = User::factory()->create();
-
- $response = $this->actingAs($user)
- ->get(route('security.edit'));
-
- $response->assertRedirect(route('password.confirm'));
-});
-
-test('security settings page renders without two factor when feature is disabled', function () {
- config(['fortify.features' => []]);
-
- $user = User::factory()->create();
-
- $this->actingAs($user)
- ->withSession(['auth.password_confirmed_at' => time()])
- ->get(route('security.edit'))
- ->assertOk()
- ->assertSee('Update password')
- ->assertDontSee('Two-factor authentication');
-});
-
-test('two factor authentication disabled when confirmation abandoned between requests', function () {
- $user = User::factory()->create();
-
- $user->forceFill([
- 'two_factor_secret' => encrypt('test-secret'),
- 'two_factor_recovery_codes' => encrypt(json_encode(['code1', 'code2'])),
- 'two_factor_confirmed_at' => null,
- ])->save();
-
- $this->actingAs($user);
-
- $component = Livewire::test('pages::settings.security');
-
- $component->assertSet('twoFactorEnabled', false);
-
- $this->assertDatabaseHas('users', [
- 'id' => $user->id,
- 'two_factor_secret' => null,
- 'two_factor_recovery_codes' => null,
- ]);
-});
-
-test('password can be updated', function () {
- $user = User::factory()->create([
- 'password' => Hash::make('password'),
- ]);
-
- $this->actingAs($user);
-
- $response = Livewire::test('pages::settings.security')
- ->set('current_password', 'password')
- ->set('password', 'new-password')
- ->set('password_confirmation', 'new-password')
- ->call('updatePassword');
-
- $response->assertHasNoErrors();
-
- expect(Hash::check('new-password', $user->refresh()->password))->toBeTrue();
-});
-
-test('correct password must be provided to update password', function () {
- $user = User::factory()->create([
- 'password' => Hash::make('password'),
- ]);
-
- $this->actingAs($user);
-
- $response = Livewire::test('pages::settings.security')
- ->set('current_password', 'wrong-password')
- ->set('password', 'new-password')
- ->set('password_confirmation', 'new-password')
- ->call('updatePassword');
-
- $response->assertHasErrors(['current_password']);
-});
\ No newline at end of file