From 01997dccc47b1105ad6f2626ded4705d0ae2363b Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Wed, 10 Jun 2026 23:33:19 +0700 Subject: [PATCH] Add user settings management features including Appearance, Password, and Profile controllers for handling user preferences. Implement corresponding requests for validation and create views for each setting. Enhance middleware to manage appearance settings across the application. Update routes for new settings functionality and integrate UI components for user navigation in the settings layout. --- .../Admin/Setting/AppearanceController.php | 36 +++++ .../Admin/Setting/PasswordController.php | 29 ++++ .../Admin/Setting/ProfileController.php | 37 +++++ app/Http/Middleware/HandleAppearance.php | 21 +++ app/Http/Middleware/HandleInertiaRequests.php | 1 + .../Admin/Setting/UpdateAppearanceRequest.php | 21 +++ .../Admin/Setting/UpdatePasswordRequest.php | 22 +++ .../Admin/Setting/UpdateProfileRequest.php | 28 ++++ app/Services/Setting/ProfileService.php | 30 ++++ bootstrap/app.php | 2 + resources/js/components/UserNav.vue | 11 +- resources/js/composables/useAppearance.ts | 17 +++ resources/js/layouts/SettingsLayout.vue | 59 ++++++++ .../js/pages/admin/setting/Appearance.vue | 121 ++++++++++++++++ resources/js/pages/admin/setting/Password.vue | 89 ++++++++++++ resources/js/pages/admin/setting/Profile.vue | 137 ++++++++++++++++++ resources/js/types/global.d.ts | 1 + resources/js/types/settings.ts | 41 ++++++ resources/views/app.blade.php | 17 ++- routes/web.php | 14 ++ server.php | 1 - 21 files changed, 730 insertions(+), 5 deletions(-) create mode 100644 app/Http/Controllers/Admin/Setting/AppearanceController.php create mode 100644 app/Http/Controllers/Admin/Setting/PasswordController.php create mode 100644 app/Http/Controllers/Admin/Setting/ProfileController.php create mode 100644 app/Http/Middleware/HandleAppearance.php create mode 100644 app/Http/Requests/Admin/Setting/UpdateAppearanceRequest.php create mode 100644 app/Http/Requests/Admin/Setting/UpdatePasswordRequest.php create mode 100644 app/Http/Requests/Admin/Setting/UpdateProfileRequest.php create mode 100644 app/Services/Setting/ProfileService.php create mode 100644 resources/js/composables/useAppearance.ts create mode 100644 resources/js/layouts/SettingsLayout.vue create mode 100644 resources/js/pages/admin/setting/Appearance.vue create mode 100644 resources/js/pages/admin/setting/Password.vue create mode 100644 resources/js/pages/admin/setting/Profile.vue create mode 100644 resources/js/types/settings.ts diff --git a/app/Http/Controllers/Admin/Setting/AppearanceController.php b/app/Http/Controllers/Admin/Setting/AppearanceController.php new file mode 100644 index 0000000..7ebeba5 --- /dev/null +++ b/app/Http/Controllers/Admin/Setting/AppearanceController.php @@ -0,0 +1,36 @@ + request()->cookie('appearance', 'system'), + ]); + } + + public function update(UpdateAppearanceRequest $request): RedirectResponse + { + $appearance = $request->string('appearance')->toString(); + + Inertia::flash('success', 'Tampilan berhasil diperbarui.'); + + return redirect() + ->route('admin.setting.appearance') + ->withCookie(Cookie::create('appearance') + ->withValue($appearance) + ->withExpires(now()->addYear()) + ->withPath('/') + ->withHttpOnly(false) + ->withSameSite('lax')); + } +} diff --git a/app/Http/Controllers/Admin/Setting/PasswordController.php b/app/Http/Controllers/Admin/Setting/PasswordController.php new file mode 100644 index 0000000..8c7e46e --- /dev/null +++ b/app/Http/Controllers/Admin/Setting/PasswordController.php @@ -0,0 +1,29 @@ +user(); + $user->password = Hash::make($request->string('password')->toString()); + $user->save(); + + Inertia::flash('success', 'Kata sandi berhasil diperbarui.'); + + return redirect()->route('admin.setting.password'); + } +} diff --git a/app/Http/Controllers/Admin/Setting/ProfileController.php b/app/Http/Controllers/Admin/Setting/ProfileController.php new file mode 100644 index 0000000..8779ddd --- /dev/null +++ b/app/Http/Controllers/Admin/Setting/ProfileController.php @@ -0,0 +1,37 @@ +user()->load('profile'); + + return Inertia::render('admin/setting/Profile', [ + 'genders' => Gender::selectOptions(), + 'user' => $user, + ]); + } + + public function update(UpdateProfileRequest $request): RedirectResponse + { + $this->profileService->update($request->validated()); + + Inertia::flash('success', 'Profil berhasil diperbarui.'); + + return redirect()->route('admin.setting.profile'); + } +} diff --git a/app/Http/Middleware/HandleAppearance.php b/app/Http/Middleware/HandleAppearance.php new file mode 100644 index 0000000..15c2394 --- /dev/null +++ b/app/Http/Middleware/HandleAppearance.php @@ -0,0 +1,21 @@ +cookie('appearance', 'system')); + + return $next($request); + } +} diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index c9e1368..b6674f7 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -55,6 +55,7 @@ public function share(Request $request): array ], 'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true', + 'appearance' => $request->cookie('appearance', 'system'), ]; } } diff --git a/app/Http/Requests/Admin/Setting/UpdateAppearanceRequest.php b/app/Http/Requests/Admin/Setting/UpdateAppearanceRequest.php new file mode 100644 index 0000000..cb8af1c --- /dev/null +++ b/app/Http/Requests/Admin/Setting/UpdateAppearanceRequest.php @@ -0,0 +1,21 @@ +check(); + } + + public function rules(): array + { + return [ + 'appearance' => ['required', Rule::in(['light', 'dark', 'system'])], + ]; + } +} diff --git a/app/Http/Requests/Admin/Setting/UpdatePasswordRequest.php b/app/Http/Requests/Admin/Setting/UpdatePasswordRequest.php new file mode 100644 index 0000000..14d771c --- /dev/null +++ b/app/Http/Requests/Admin/Setting/UpdatePasswordRequest.php @@ -0,0 +1,22 @@ +check(); + } + + public function rules(): array + { + return [ + 'current_password' => ['required', 'current_password'], + 'password' => ['required', 'confirmed', Password::defaults()], + ]; + } +} diff --git a/app/Http/Requests/Admin/Setting/UpdateProfileRequest.php b/app/Http/Requests/Admin/Setting/UpdateProfileRequest.php new file mode 100644 index 0000000..9c07909 --- /dev/null +++ b/app/Http/Requests/Admin/Setting/UpdateProfileRequest.php @@ -0,0 +1,28 @@ +check(); + } + + public function rules(): array + { + return [ + 'email' => ['required', 'email', 'max:100', Rule::unique('users', 'email')->ignore($this->user()?->id)], + 'username' => ['required', 'string', 'max:20', 'alpha_dash', Rule::unique('users', 'username')->ignore($this->user()?->id)], + 'full_name' => ['required', 'string', 'max:200'], + 'phone_number' => ['nullable', 'string', 'regex:/^08\d{8,11}$/'], + 'gender' => ['nullable', Rule::enum(Gender::class)], + 'birth_date' => ['nullable', 'date', 'before:today'], + 'address' => ['nullable', 'string'], + ]; + } +} diff --git a/app/Services/Setting/ProfileService.php b/app/Services/Setting/ProfileService.php new file mode 100644 index 0000000..7b89e11 --- /dev/null +++ b/app/Services/Setting/ProfileService.php @@ -0,0 +1,30 @@ +user(); + + DB::transaction(function () use ($user, $validated): void { + $user->email = $validated['email']; + $user->username = $validated['username']; + $user->save(); + + $user->profile()->updateOrCreate( + ['user_id' => $user->id], + [ + 'full_name' => $validated['full_name'], + 'phone_number' => $validated['phone_number'] ?? null, + 'gender' => $validated['gender'] ?? null, + 'birth_date' => $validated['birth_date'] ?? null, + 'address' => $validated['address'] ?? null, + ], + ); + }); + } +} diff --git a/bootstrap/app.php b/bootstrap/app.php index 8c18807..b9b2d94 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,5 +1,6 @@ web(append: [ + HandleAppearance::class, HandleInertiaRequests::class, AddLinkHeadersForPreloadedAssets::class, ]); diff --git a/resources/js/components/UserNav.vue b/resources/js/components/UserNav.vue index 62a3e87..f1d8b97 100644 --- a/resources/js/components/UserNav.vue +++ b/resources/js/components/UserNav.vue @@ -1,6 +1,6 @@ + + diff --git a/resources/js/pages/admin/setting/Appearance.vue b/resources/js/pages/admin/setting/Appearance.vue new file mode 100644 index 0000000..8b9502f --- /dev/null +++ b/resources/js/pages/admin/setting/Appearance.vue @@ -0,0 +1,121 @@ + + + diff --git a/resources/js/pages/admin/setting/Password.vue b/resources/js/pages/admin/setting/Password.vue new file mode 100644 index 0000000..f1f99ad --- /dev/null +++ b/resources/js/pages/admin/setting/Password.vue @@ -0,0 +1,89 @@ + + + diff --git a/resources/js/pages/admin/setting/Profile.vue b/resources/js/pages/admin/setting/Profile.vue new file mode 100644 index 0000000..9e5f16e --- /dev/null +++ b/resources/js/pages/admin/setting/Profile.vue @@ -0,0 +1,137 @@ + + +