From 8c7f869c767e94832443e1abda47de71be3c412f Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sat, 18 Oct 2025 19:37:49 +0700 Subject: [PATCH] feat(settings): implement application settings management with contact, general, social, and SEO forms --- .../Forms/Studio/Setting/ContactForm.php | 58 ++++++ .../Forms/Studio/Setting/GeneralForm.php | 47 +++++ app/Livewire/Forms/Studio/Setting/SeoForm.php | 72 +++++++ .../Forms/Studio/Setting/SocialForm.php | 57 ++++++ app/Livewire/Studio/Setting/Application.php | 89 +++++++++ app/Providers/ViewServiceProvider.php | 12 ++ app/Settings/ContactSettings.php | 21 ++ app/Settings/GeneralSettings.php | 21 ++ app/Settings/SeoSettings.php | 31 +++ app/Settings/SocialSettings.php | 25 +++ database/seeders/RolePermissionSeeder.php | 14 ++ ...5_10_18_075855_create_general_settings.php | 21 ++ ...5_10_18_075912_create_contact_settings.php | 19 ++ .../2025_10_18_075924_create_seo_settings.php | 24 +++ ...25_10_18_075931_create_social_settings.php | 22 +++ .../studio/setting/application.blade.php | 186 ++++++++++++++++++ routes/pages/studio.php | 3 + 17 files changed, 722 insertions(+) create mode 100644 app/Livewire/Forms/Studio/Setting/ContactForm.php create mode 100644 app/Livewire/Forms/Studio/Setting/GeneralForm.php create mode 100644 app/Livewire/Forms/Studio/Setting/SeoForm.php create mode 100644 app/Livewire/Forms/Studio/Setting/SocialForm.php create mode 100644 app/Livewire/Studio/Setting/Application.php create mode 100644 app/Settings/ContactSettings.php create mode 100644 app/Settings/GeneralSettings.php create mode 100644 app/Settings/SeoSettings.php create mode 100644 app/Settings/SocialSettings.php create mode 100644 database/settings/2025_10_18_075855_create_general_settings.php create mode 100644 database/settings/2025_10_18_075912_create_contact_settings.php create mode 100644 database/settings/2025_10_18_075924_create_seo_settings.php create mode 100644 database/settings/2025_10_18_075931_create_social_settings.php create mode 100644 resources/views/livewire/studio/setting/application.blade.php diff --git a/app/Livewire/Forms/Studio/Setting/ContactForm.php b/app/Livewire/Forms/Studio/Setting/ContactForm.php new file mode 100644 index 0000000..ae08734 --- /dev/null +++ b/app/Livewire/Forms/Studio/Setting/ContactForm.php @@ -0,0 +1,58 @@ + ['required', 'string', new PhoneNumber], + 'email' => ['nullable', 'email', 'max:100', Rule::unique('users', 'email')], + 'address' => ['required', 'string', 'max:255'], + 'map_embed' => ['nullable', 'string'], + ]; + } + + public function validationAttributes(): array + { + return [ + 'phone_number' => 'nomor telepon', + 'address' => 'alamat', + 'map_embed' => 'map embed', + ]; + } + + public function setSettings(ContactSettings $settings): void + { + $this->address = $settings->address; + $this->phone_number = $settings->phone_number; + $this->email = $settings->email; + $this->map_embed = $settings->map_embed; + } + + public function update(ContactSettings $settings): void + { + $this->validate(); + + $settings->address = $this->address; + $settings->phone_number = $this->phone_number; + $settings->email = $this->email; + $settings->map_embed = $this->map_embed; + + $settings->save(); + } +} diff --git a/app/Livewire/Forms/Studio/Setting/GeneralForm.php b/app/Livewire/Forms/Studio/Setting/GeneralForm.php new file mode 100644 index 0000000..7b2dd10 --- /dev/null +++ b/app/Livewire/Forms/Studio/Setting/GeneralForm.php @@ -0,0 +1,47 @@ + ['required', 'string', 'max:100'], + 'site_tagline' => ['required', 'string', 'max:150'], + 'site_description' => ['required', 'string'], + 'maintenance_mode' => ['required', 'boolean'], + ]; + } + + public function setSettings(GeneralSettings $settings): void + { + $this->site_name = $settings->site_name; + $this->site_tagline = $settings->site_tagline; + $this->site_description = $settings->site_description; + $this->maintenance_mode = $settings->maintenance_mode; + } + + public function update(GeneralSettings $settings): void + { + $this->validate(); + + $settings->site_name = $this->site_name; + $settings->site_tagline = $this->site_tagline; + $settings->site_description = $this->site_description; + $settings->maintenance_mode = $this->maintenance_mode; + + $settings->save(); + } +} diff --git a/app/Livewire/Forms/Studio/Setting/SeoForm.php b/app/Livewire/Forms/Studio/Setting/SeoForm.php new file mode 100644 index 0000000..f03ae5f --- /dev/null +++ b/app/Livewire/Forms/Studio/Setting/SeoForm.php @@ -0,0 +1,72 @@ + ['required', 'string'], + 'meta_keywords' => ['required', 'string'], + 'meta_author' => ['required', 'string', 'max:150'], + 'og_image' => ['nullable', 'string', 'max:255'], + 'og_title' => ['nullable', 'string', 'max:255'], + 'og_description' => ['nullable', 'string'], + 'og_type' => ['nullable', 'string', 'max:50'], + 'twitter_card' => ['nullable', 'string', 'max:50'], + 'canonical_url' => ['nullable', 'string', 'max:255'], + ]; + } + + public function setSettings(SeoSettings $settings): void + { + $this->meta_description = $settings->meta_description; + $this->meta_keywords = $settings->meta_keywords; + $this->meta_author = $settings->meta_author; + $this->og_image = $settings->og_image; + $this->og_title = $settings->og_title; + $this->og_description = $settings->og_description; + $this->og_type = $settings->og_type; + $this->twitter_card = $settings->twitter_card; + $this->canonical_url = $settings->canonical_url; + } + + public function update(SeoSettings $settings): void + { + $this->validate(); + + $settings->meta_description = $this->meta_description; + $settings->meta_keywords = $this->meta_keywords; + $settings->meta_author = $this->meta_author; + $settings->og_image = $this->og_image; + $settings->og_title = $this->og_title; + $settings->og_description = $this->og_description; + $settings->og_type = $this->og_type; + $settings->twitter_card = $this->twitter_card; + $settings->canonical_url = $this->canonical_url; + + $settings->save(); + } +} diff --git a/app/Livewire/Forms/Studio/Setting/SocialForm.php b/app/Livewire/Forms/Studio/Setting/SocialForm.php new file mode 100644 index 0000000..510cf4f --- /dev/null +++ b/app/Livewire/Forms/Studio/Setting/SocialForm.php @@ -0,0 +1,57 @@ + ['nullable', 'url'], + 'instagram' => ['nullable', 'url'], + 'youtube' => ['nullable', 'url'], + 'tiktok' => ['nullable', 'url'], + 'whatsapp' => ['required', 'url'], + 'telegram' => ['nullable', 'url'], + ]; + } + + public function setSettings(SocialSettings $settings): void + { + $this->facebook = $settings->facebook; + $this->instagram = $settings->instagram; + $this->youtube = $settings->youtube; + $this->tiktok = $settings->tiktok; + $this->whatsapp = $settings->whatsapp; + $this->telegram = $settings->telegram; + } + + public function update(SocialSettings $settings): void + { + $this->validate(); + + $settings->facebook = $this->facebook; + $settings->instagram = $this->instagram; + $settings->youtube = $this->youtube; + $settings->tiktok = $this->tiktok; + $settings->whatsapp = $this->whatsapp; + $settings->telegram = $this->telegram; + + $settings->save(); + } +} diff --git a/app/Livewire/Studio/Setting/Application.php b/app/Livewire/Studio/Setting/Application.php new file mode 100644 index 0000000..d6b4cb2 --- /dev/null +++ b/app/Livewire/Studio/Setting/Application.php @@ -0,0 +1,89 @@ +generalForm->setSettings($generalSettings); + + $this->contactForm->setSettings($contactSettings); + + $this->socialForm->setSettings($socialSettings); + + $this->seoForm->setSettings($seoSettings); + } + + public function updateGeneral(GeneralSettings $generalSettings) + { + $this->canOrAbort('update general settings'); + + $this->generalForm->update($generalSettings); + + $this->toast('Pengaturan umum berhasil diperbarui.'); + } + + public function updateContact(ContactSettings $contactSettings) + { + $this->canOrAbort('update contact settings'); + + $this->contactForm->update($contactSettings); + + $this->toast('Pengaturan kontak berhasil diperbarui.'); + } + + public function updateSocial(SocialSettings $socialSettings) + { + $this->canOrAbort('update social settings'); + + $this->socialForm->update($socialSettings); + + $this->toast('Pengaturan media sosial berhasil diperbarui.'); + } + + public function updateSeo(SeoSettings $seoSettings) + { + $this->canOrAbort('update seo settings'); + + $this->seoForm->update($seoSettings); + + $this->toast('Pengaturan SEO berhasil diperbarui.'); + } + + public function render() + { + return view('livewire.studio.setting.application', [ + 'pageTitle' => 'Aplikasi', + ]); + } +} diff --git a/app/Providers/ViewServiceProvider.php b/app/Providers/ViewServiceProvider.php index 0ded3e0..e08c6b1 100644 --- a/app/Providers/ViewServiceProvider.php +++ b/app/Providers/ViewServiceProvider.php @@ -153,6 +153,18 @@ public function boot(): void ], ], ], + [ + 'heading' => 'Pengaturan', + 'items' => [ + [ + 'label' => 'Aplikasi', + 'icon' => 'cog-6-tooth', + 'route' => 'studio.setting.application', + 'match' => 'studio.setting.application', + 'can' => 'view application settings', + ], + ], + ], ]; $view->with('sidebar', $sidebar); diff --git a/app/Settings/ContactSettings.php b/app/Settings/ContactSettings.php new file mode 100644 index 0000000..d586c3d --- /dev/null +++ b/app/Settings/ContactSettings.php @@ -0,0 +1,21 @@ +migrator->add('general.site_name', 'Yadi Parfum'); + $this->migrator->add('general.site_tagline', 'Seungit Pisan'); + $this->migrator->add('general.site_description', 'Yadi Parfum menyediakan parfum refill dan produk pewangi dengan kualitas terbaik.'); + $this->migrator->add('general.logo', null); + $this->migrator->add('general.favicon', null); + $this->migrator->add('general.maintenance_mode', false); + } + + public function down(): void + { + $this->migrator->deleteIfExists('general'); + } +}; diff --git a/database/settings/2025_10_18_075912_create_contact_settings.php b/database/settings/2025_10_18_075912_create_contact_settings.php new file mode 100644 index 0000000..9a8883e --- /dev/null +++ b/database/settings/2025_10_18_075912_create_contact_settings.php @@ -0,0 +1,19 @@ +migrator->add('contact.phone_number', '083816931711'); + $this->migrator->add('contact.email', 'yadiparfum@gmail.com'); + $this->migrator->add('contact.address', 'Jl. Taman Pahlawan No.41, Nagri Kaler, Kec. Purwakarta, Kabupaten Purwakarta, Jawa Barat 41119'); + $this->migrator->add('contact.map_embed', ''); + } + + public function down(): void + { + $this->migrator->deleteIfExists('contact'); + } +}; diff --git a/database/settings/2025_10_18_075924_create_seo_settings.php b/database/settings/2025_10_18_075924_create_seo_settings.php new file mode 100644 index 0000000..3010956 --- /dev/null +++ b/database/settings/2025_10_18_075924_create_seo_settings.php @@ -0,0 +1,24 @@ +migrator->add('seo.meta_description', 'Nikmati pengalaman wangi berkualitas tinggi dengan parfum refill dan produk unggulan dari Yadi Parfum.'); + $this->migrator->add('seo.meta_keywords', 'parfum, refill, wangi, aroma, purwakarta, yadi parfum'); + $this->migrator->add('seo.meta_author', 'Yadi Parfum'); + $this->migrator->add('seo.og_image', ''); + $this->migrator->add('seo.og_title', 'Yadi Parfum'); + $this->migrator->add('seo.og_description', 'Parfum refill berkualitas premium untuk Anda.'); + $this->migrator->add('seo.og_type', 'website'); + $this->migrator->add('seo.twitter_card', 'summary_large_image'); + $this->migrator->add('seo.canonical_url', 'https://yadiparfum.com'); + } + + public function down(): void + { + $this->migrator->deleteIfExists('seo'); + } +}; diff --git a/database/settings/2025_10_18_075931_create_social_settings.php b/database/settings/2025_10_18_075931_create_social_settings.php new file mode 100644 index 0000000..fbfec73 --- /dev/null +++ b/database/settings/2025_10_18_075931_create_social_settings.php @@ -0,0 +1,22 @@ +migrator->add('social.facebook', 'https://web.facebook.com/yadie.aza.188'); + $this->migrator->add('social.instagram', null); + $this->migrator->add('social.twitter', null); + $this->migrator->add('social.youtube', null); + $this->migrator->add('social.tiktok', 'https://www.tiktok.com/@yadiparfum_'); + $this->migrator->add('social.whatsapp', 'https://wa.me/6283816931711'); + $this->migrator->add('social.telegram', null); + } + + public function down(): void + { + $this->migrator->deleteIfExists('social'); + } +}; diff --git a/resources/views/livewire/studio/setting/application.blade.php b/resources/views/livewire/studio/setting/application.blade.php new file mode 100644 index 0000000..b3d3bdf --- /dev/null +++ b/resources/views/livewire/studio/setting/application.blade.php @@ -0,0 +1,186 @@ + + Pengaturan Aplikasi + +
+
+ Umum + Kelola informasi dasar seperti nama situs, tagline, dan detail utama lainnya yang digunakan + di seluruh sistem. +
+
+
+ + Nama Situs * + + + + + + Tagline * + + +
+ + + Deskripsi * + + + + + Mode Pemeliharaan + + + + @can('update general settings') + + Simpan + + @endcan +
+
+ + +
+
+ Kontak + + Atur informasi kontak seperti alamat, nomor telepon, email, dan lokasi peta agar pelanggan + mudah menghubungi Anda. + +
+ +
+
+ + Nomor Telepon * + + + + + +
+ + + Alamat * + + + + + + + @can('update contact settings') + + Simpan + + @endcan +
+
+ + +
+
+ Media Sosial + + Hubungkan situs Anda dengan berbagai platform media sosial untuk memperkuat kehadiran dan interaksi + online. + +
+ +
+
+ + + + + + + + + + + +
+ + @can('update social settings') + + Simpan + + @endcan +
+
+ + +
+
+ SEO + + Optimalkan visibilitas situs di mesin pencari dan media sosial dengan mengatur meta tag, Open Graph, dan + informasi berbagi. + +
+ +
+
+ + Meta Description * + + + + + + Meta Keywords * + + + + +
+ + Meta Author * + + + + + +
+ + + +
+ + + + + +
+
+ + @can('update seo settings') + + Simpan + + @endcan +
+
+
diff --git a/routes/pages/studio.php b/routes/pages/studio.php index 36342e9..fb3dff7 100644 --- a/routes/pages/studio.php +++ b/routes/pages/studio.php @@ -32,6 +32,7 @@ use App\Livewire\Studio\Master\User\Edit as UserEdit; use App\Livewire\Studio\Master\User\Index as UserIndex; use App\Livewire\Studio\Setting\Account as AccountComponent; +use App\Livewire\Studio\Setting\Application as ApplicationComponent; use App\Livewire\Studio\Setting\Password as PasswordComponent; use App\Livewire\Studio\Setting\Profile as ProfileComponent; use Illuminate\Support\Facades\Route; @@ -148,4 +149,6 @@ Route::delete('/{purchase}/delete', PurchaseCreate::class)->name('delete')->middleware('can:delete purchase'); }); }); + + Route::get('/settings/applications', ApplicationComponent::class)->name('studio.setting.application')->middleware('can:view application settings'); });