From 67c27c2954a6ffb47c5d44e81654bfa13154da38 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Thu, 11 Jun 2026 18:30:21 +0700 Subject: [PATCH] Add system settings management features including controllers for managing system, social media, and marketplace settings. Implement request validation for each settings type and create corresponding UI components for user interaction. Update permissions in the Permission and Role enums to manage access to settings functionalities, and enhance the sidebar for navigation to the new settings sections. --- app/Enums/Permission.php | 7 + app/Enums/Role.php | 2 + .../Admin/System/SettingController.php | 59 +++ .../System/Setting/MarketplaceRequest.php | 40 ++ .../System/Setting/SocialMediaRequest.php | 23 + .../Admin/System/Setting/SystemRequest.php | 26 + .../System/Setting/MarketplaceService.php | 63 +++ .../System/Setting/SocialMediaService.php | 30 ++ app/Services/System/Setting/SystemService.php | 48 ++ app/Settings/MarketplaceSettings.php | 51 ++ app/Settings/SocialMediaSettings.php | 19 + app/Settings/SystemSettings.php | 25 + composer.json | 1 + composer.lock | 466 ++++++++++++------ config/settings.php | 107 ++++ ...022_12_14_083707_create_settings_table.php | 25 + .../2026_06_11_085959_create_app_settings.php | 48 ++ resources/js/components/AppSidebar.vue | 19 +- .../admin/setting/ImageUploadField.vue | 91 ++++ .../admin/setting/MarketplaceSection.vue | 279 +++++++++++ .../admin/setting/SocialMediaSection.vue | 81 +++ .../admin/setting/SystemSection.vue | 116 +++++ resources/js/layouts/SettingLayout.vue | 48 ++ .../js/pages/admin/system/setting/Index.vue | 33 ++ resources/js/types/setting.ts | 42 ++ routes/web.php | 21 + 26 files changed, 1609 insertions(+), 161 deletions(-) create mode 100644 app/Http/Controllers/Admin/System/SettingController.php create mode 100644 app/Http/Requests/Admin/System/Setting/MarketplaceRequest.php create mode 100644 app/Http/Requests/Admin/System/Setting/SocialMediaRequest.php create mode 100644 app/Http/Requests/Admin/System/Setting/SystemRequest.php create mode 100644 app/Services/System/Setting/MarketplaceService.php create mode 100644 app/Services/System/Setting/SocialMediaService.php create mode 100644 app/Services/System/Setting/SystemService.php create mode 100644 app/Settings/MarketplaceSettings.php create mode 100644 app/Settings/SocialMediaSettings.php create mode 100644 app/Settings/SystemSettings.php create mode 100644 config/settings.php create mode 100644 database/migrations/2022_12_14_083707_create_settings_table.php create mode 100644 database/settings/2026_06_11_085959_create_app_settings.php create mode 100644 resources/js/components/admin/setting/ImageUploadField.vue create mode 100644 resources/js/components/admin/setting/MarketplaceSection.vue create mode 100644 resources/js/components/admin/setting/SocialMediaSection.vue create mode 100644 resources/js/components/admin/setting/SystemSection.vue create mode 100644 resources/js/layouts/SettingLayout.vue create mode 100644 resources/js/pages/admin/system/setting/Index.vue create mode 100644 resources/js/types/setting.ts diff --git a/app/Enums/Permission.php b/app/Enums/Permission.php index 0205231..5945602 100644 --- a/app/Enums/Permission.php +++ b/app/Enums/Permission.php @@ -77,6 +77,9 @@ enum Permission: string case PAYROLL_ADJUST = 'payroll.adjust'; case PAYROLL_CLOSE = 'payroll.close'; + case SETTINGS_VIEW = 'settings.view'; + case SETTINGS_UPDATE = 'settings.update'; + public function label(): string { return match ($this) { @@ -148,6 +151,9 @@ public function label(): string self::PAYROLL_PAY => 'Bayar Gaji', self::PAYROLL_ADJUST => 'Sesuaikan Gaji', self::PAYROLL_CLOSE => 'Tutup Periode Gaji', + + self::SETTINGS_VIEW => 'Lihat Pengaturan Aplikasi', + self::SETTINGS_UPDATE => 'Ubah Pengaturan Aplikasi', }; } @@ -179,6 +185,7 @@ public function group(): string self::EMPLOYEE_ADVANCES_PAY => 'Kasbon', self::PAYROLL_VIEW, self::PAYROLL_PAY, self::PAYROLL_ADJUST, self::PAYROLL_CLOSE => 'Gaji', + self::SETTINGS_VIEW, self::SETTINGS_UPDATE => 'Pengaturan Aplikasi', }; } diff --git a/app/Enums/Role.php b/app/Enums/Role.php index d99c0a2..246bcbe 100644 --- a/app/Enums/Role.php +++ b/app/Enums/Role.php @@ -141,6 +141,8 @@ public function permissions(): array Permission::PAYROLL_PAY, Permission::PAYROLL_ADJUST, Permission::PAYROLL_CLOSE, + Permission::SETTINGS_VIEW, + Permission::SETTINGS_UPDATE, ], self::ADMIN_BAHAN_BAKU => [ Permission::DASHBOARD_VIEW, diff --git a/app/Http/Controllers/Admin/System/SettingController.php b/app/Http/Controllers/Admin/System/SettingController.php new file mode 100644 index 0000000..3dd6d02 --- /dev/null +++ b/app/Http/Controllers/Admin/System/SettingController.php @@ -0,0 +1,59 @@ + $this->systemService->systemData(), + 'socialMedia' => $this->socialMediaService->socialMediaData(), + 'marketplace' => $this->marketplaceService->marketplaceData(), + ]); + } + + public function updateSystem(SystemRequest $request): RedirectResponse + { + $this->systemService->updateSystem($request->validated()); + + Inertia::flash('success', 'Pengaturan sistem berhasil disimpan.'); + + return redirect()->route('admin.system.setting.index'); + } + + public function updateSocialMedia(SocialMediaRequest $request): RedirectResponse + { + $this->socialMediaService->updateSocialMedia($request->validated()); + + Inertia::flash('success', 'Pengaturan media sosial berhasil disimpan.'); + + return redirect()->route('admin.system.setting.index'); + } + + public function updateMarketplace(MarketplaceRequest $request): RedirectResponse + { + $this->marketplaceService->updateMarketplace($request->validated()); + + Inertia::flash('success', 'Pengaturan marketplace berhasil disimpan.'); + + return redirect()->route('admin.system.setting.index'); + } +} diff --git a/app/Http/Requests/Admin/System/Setting/MarketplaceRequest.php b/app/Http/Requests/Admin/System/Setting/MarketplaceRequest.php new file mode 100644 index 0000000..28381a0 --- /dev/null +++ b/app/Http/Requests/Admin/System/Setting/MarketplaceRequest.php @@ -0,0 +1,40 @@ +user()?->can(Permission::SETTINGS_UPDATE->value) ?? false; + } + + public function rules(): array + { + return [ + 'tiktok_shop_enabled' => ['required', 'boolean'], + 'tiktok_shop_admin_fee' => ['required', 'numeric', 'min:0', 'max:100'], + 'tiktok_shop_transaction_fee' => ['required', 'numeric', 'min:0', 'max:100'], + 'tiktok_shop_payment_fee' => ['required', 'numeric', 'min:0', 'max:100'], + 'tiktok_shop_affiliate_commission' => ['required', 'numeric', 'min:0', 'max:100'], + 'tiktok_shop_shipping_subsidy' => ['required', 'numeric', 'min:0', 'max:100'], + 'tiktok_shop_vat_rate' => ['required', 'numeric', 'min:0', 'max:100'], + 'tiktok_shop_url' => ['nullable', 'url', 'max:500'], + 'tiktok_shop_id' => ['nullable', 'string', 'max:100'], + + 'shopee_enabled' => ['required', 'boolean'], + 'shopee_commission_fee' => ['required', 'numeric', 'min:0', 'max:100'], + 'shopee_transaction_fee' => ['required', 'numeric', 'min:0', 'max:100'], + 'shopee_service_fee' => ['required', 'numeric', 'min:0', 'max:100'], + 'shopee_payment_fee' => ['required', 'numeric', 'min:0', 'max:100'], + 'shopee_affiliate_commission' => ['required', 'numeric', 'min:0', 'max:100'], + 'shopee_shipping_subsidy' => ['required', 'numeric', 'min:0', 'max:100'], + 'shopee_voucher_fee' => ['required', 'numeric', 'min:0', 'max:100'], + 'shopee_shop_url' => ['nullable', 'url', 'max:500'], + 'shopee_shop_id' => ['nullable', 'string', 'max:100'], + ]; + } +} diff --git a/app/Http/Requests/Admin/System/Setting/SocialMediaRequest.php b/app/Http/Requests/Admin/System/Setting/SocialMediaRequest.php new file mode 100644 index 0000000..7d86cce --- /dev/null +++ b/app/Http/Requests/Admin/System/Setting/SocialMediaRequest.php @@ -0,0 +1,23 @@ +user()?->can(Permission::SETTINGS_UPDATE->value) ?? false; + } + + public function rules(): array + { + return [ + 'instagram_url' => ['nullable', 'url', 'max:100'], + 'facebook_url' => ['nullable', 'url', 'max:100'], + 'tiktok_url' => ['nullable', 'url', 'max:100'], + ]; + } +} diff --git a/app/Http/Requests/Admin/System/Setting/SystemRequest.php b/app/Http/Requests/Admin/System/Setting/SystemRequest.php new file mode 100644 index 0000000..49b2169 --- /dev/null +++ b/app/Http/Requests/Admin/System/Setting/SystemRequest.php @@ -0,0 +1,26 @@ +user()?->can(Permission::SETTINGS_UPDATE->value) ?? false; + } + + public function rules(): array + { + return [ + 'app_name' => ['required', 'string', 'max:100'], + 'about_app' => ['nullable', 'string'], + 'email' => ['nullable', 'email', 'max:100'], + 'phone' => ['nullable', 'string', 'max:20'], + 'logo' => ['nullable', 'image', 'max:2048'], + 'login_cover' => ['nullable', 'image', 'max:5120'], + ]; + } +} diff --git a/app/Services/System/Setting/MarketplaceService.php b/app/Services/System/Setting/MarketplaceService.php new file mode 100644 index 0000000..8ac80f0 --- /dev/null +++ b/app/Services/System/Setting/MarketplaceService.php @@ -0,0 +1,63 @@ + $settings->tiktok_shop_enabled, + 'tiktok_shop_admin_fee' => $settings->tiktok_shop_admin_fee, + 'tiktok_shop_transaction_fee' => $settings->tiktok_shop_transaction_fee, + 'tiktok_shop_payment_fee' => $settings->tiktok_shop_payment_fee, + 'tiktok_shop_affiliate_commission' => $settings->tiktok_shop_affiliate_commission, + 'tiktok_shop_shipping_subsidy' => $settings->tiktok_shop_shipping_subsidy, + 'tiktok_shop_vat_rate' => $settings->tiktok_shop_vat_rate, + 'tiktok_shop_url' => $settings->tiktok_shop_url, + 'tiktok_shop_id' => $settings->tiktok_shop_id, + 'shopee_enabled' => $settings->shopee_enabled, + 'shopee_commission_fee' => $settings->shopee_commission_fee, + 'shopee_transaction_fee' => $settings->shopee_transaction_fee, + 'shopee_service_fee' => $settings->shopee_service_fee, + 'shopee_payment_fee' => $settings->shopee_payment_fee, + 'shopee_affiliate_commission' => $settings->shopee_affiliate_commission, + 'shopee_shipping_subsidy' => $settings->shopee_shipping_subsidy, + 'shopee_voucher_fee' => $settings->shopee_voucher_fee, + 'shopee_shop_url' => $settings->shopee_shop_url, + 'shopee_shop_id' => $settings->shopee_shop_id, + ]; + } + + public function updateMarketplace(array $validated): void + { + $settings = app(MarketplaceSettings::class); + + $settings->tiktok_shop_enabled = $validated['tiktok_shop_enabled']; + $settings->tiktok_shop_admin_fee = $validated['tiktok_shop_admin_fee']; + $settings->tiktok_shop_transaction_fee = $validated['tiktok_shop_transaction_fee']; + $settings->tiktok_shop_payment_fee = $validated['tiktok_shop_payment_fee']; + $settings->tiktok_shop_affiliate_commission = $validated['tiktok_shop_affiliate_commission']; + $settings->tiktok_shop_shipping_subsidy = $validated['tiktok_shop_shipping_subsidy']; + $settings->tiktok_shop_vat_rate = $validated['tiktok_shop_vat_rate']; + $settings->tiktok_shop_url = $validated['tiktok_shop_url'] ?? null; + $settings->tiktok_shop_id = $validated['tiktok_shop_id'] ?? null; + + $settings->shopee_enabled = $validated['shopee_enabled']; + $settings->shopee_commission_fee = $validated['shopee_commission_fee']; + $settings->shopee_transaction_fee = $validated['shopee_transaction_fee']; + $settings->shopee_service_fee = $validated['shopee_service_fee']; + $settings->shopee_payment_fee = $validated['shopee_payment_fee']; + $settings->shopee_affiliate_commission = $validated['shopee_affiliate_commission']; + $settings->shopee_shipping_subsidy = $validated['shopee_shipping_subsidy']; + $settings->shopee_voucher_fee = $validated['shopee_voucher_fee']; + $settings->shopee_shop_url = $validated['shopee_shop_url'] ?? null; + $settings->shopee_shop_id = $validated['shopee_shop_id'] ?? null; + + $settings->save(); + } +} diff --git a/app/Services/System/Setting/SocialMediaService.php b/app/Services/System/Setting/SocialMediaService.php new file mode 100644 index 0000000..b46a313 --- /dev/null +++ b/app/Services/System/Setting/SocialMediaService.php @@ -0,0 +1,30 @@ + $settings->instagram_url, + 'facebook_url' => $settings->facebook_url, + 'tiktok_url' => $settings->tiktok_url, + ]; + } + + public function updateSocialMedia(array $validated): void + { + $settings = app(SocialMediaSettings::class); + + $settings->instagram_url = $validated['instagram_url'] ?? null; + $settings->facebook_url = $validated['facebook_url'] ?? null; + $settings->tiktok_url = $validated['tiktok_url'] ?? null; + + $settings->save(); + } +} diff --git a/app/Services/System/Setting/SystemService.php b/app/Services/System/Setting/SystemService.php new file mode 100644 index 0000000..487afc9 --- /dev/null +++ b/app/Services/System/Setting/SystemService.php @@ -0,0 +1,48 @@ + $settings->app_name, + 'about_app' => $settings->about_app, + 'email' => $settings->email, + 'phone' => $settings->phone, + 'logo' => $settings->logo, + 'logo_url' => $settings->logo ? Storage::disk('public')->url($settings->logo) : null, + 'login_cover' => $settings->login_cover, + 'login_cover_url' => $settings->login_cover ? Storage::disk('public')->url($settings->login_cover) : null, + ]; + } + + public function updateSystem(array $validated): void + { + $settings = app(SystemSettings::class); + + $settings->app_name = $validated['app_name']; + $settings->about_app = $validated['about_app'] ?? null; + $settings->email = $validated['email'] ?? null; + $settings->phone = $validated['phone'] ?? null; + + if (isset($validated['logo']) && $validated['logo'] instanceof UploadedFile) { + Storage::disk('public')->delete($settings->logo); + $settings->logo = $validated['logo']->store('settings/system', 'public'); + } + + if (isset($validated['login_cover']) && $validated['login_cover'] instanceof UploadedFile) { + Storage::disk('public')->delete($settings->login_cover); + $settings->login_cover = $validated['login_cover']->store('settings/system', 'public'); + } + + $settings->save(); + } +} diff --git a/app/Settings/MarketplaceSettings.php b/app/Settings/MarketplaceSettings.php new file mode 100644 index 0000000..0157cc0 --- /dev/null +++ b/app/Settings/MarketplaceSettings.php @@ -0,0 +1,51 @@ +=14" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" + }, + "time": "2026-02-07T07:09:04+00:00" + }, { "name": "doctrine/inflector", "version": "2.1.0", @@ -2677,6 +2725,117 @@ ], "time": "2026-02-16T23:10:27+00:00" }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" + }, + "time": "2026-01-06T21:53:42+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.5", @@ -3636,6 +3795,91 @@ ], "time": "2026-05-30T19:30:22+00:00" }, + { + "name": "spatie/laravel-settings", + "version": "3.9.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-settings.git", + "reference": "6c1351cf57c4ae96cd2313ae395c6d367dfeee01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-settings/zipball/6c1351cf57c4ae96cd2313ae395c6d367dfeee01", + "reference": "6c1351cf57c4ae96cd2313ae395c6d367dfeee01", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/database": "^11.0|^12.0|^13.0", + "php": "^8.2", + "phpdocumentor/type-resolver": "^1.5|^2.0", + "spatie/temporary-directory": "^1.3|^2.0" + }, + "require-dev": { + "ext-redis": "*", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^9.0|^10.0|^11.0", + "pestphp/pest": "^2.0|^3.0|^4.0", + "pestphp/pest-plugin-laravel": "^2.0|^3.0|^4.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/laravel-data": "^2.0.0|^4.0.0", + "spatie/pest-plugin-snapshots": "^2.0", + "spatie/phpunit-snapshot-assertions": "^4.2|^5.0", + "spatie/ray": "^1.36" + }, + "suggest": { + "spatie/data-transfer-object": "Allows for DTO casting to settings. (deprecated)" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\LaravelSettings\\LaravelSettingsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\LaravelSettings\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ruben Van Assche", + "email": "ruben@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Store your application settings", + "homepage": "https://github.com/spatie/laravel-settings", + "keywords": [ + "laravel-settings", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-settings/issues", + "source": "https://github.com/spatie/laravel-settings/tree/3.9.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-05-26T13:18:06+00:00" + }, { "name": "spatie/laravel-sluggable", "version": "4.0.2", @@ -3714,6 +3958,67 @@ ], "time": "2026-04-30T17:28:09+00:00" }, + { + "name": "spatie/temporary-directory", + "version": "2.3.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/temporary-directory.git", + "reference": "662e481d6ec07ef29fd05010433428851a42cd07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/662e481d6ec07ef29fd05010433428851a42cd07", + "reference": "662e481d6ec07ef29fd05010433428851a42cd07", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\TemporaryDirectory\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Vanderbist", + "email": "alex@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily create, use and destroy temporary directories", + "homepage": "https://github.com/spatie/temporary-directory", + "keywords": [ + "php", + "spatie", + "temporary-directory" + ], + "support": { + "issues": "https://github.com/spatie/temporary-directory/issues", + "source": "https://github.com/spatie/temporary-directory/tree/2.3.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-01-12T07:42:22+00:00" + }, { "name": "symfony/clock", "version": "v8.1.0", @@ -6646,54 +6951,6 @@ ], "time": "2024-05-06T16:37:16+00:00" }, - { - "name": "doctrine/deprecations", - "version": "1.1.6", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", - "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "phpunit/phpunit": "<=7.5 || >=14" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^12 || ^14", - "phpstan/phpstan": "1.4.10 || 2.1.30", - "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", - "psr/log": "^1 || ^2 || ^3" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.6" - }, - "time": "2026-02-07T07:09:04+00:00" - }, { "name": "fakerphp/faker", "version": "v1.24.1", @@ -8180,59 +8437,6 @@ }, "time": "2022-02-21T01:04:05+00:00" }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, { "name": "phpdocumentor/reflection-docblock", "version": "6.0.3", @@ -8298,64 +8502,6 @@ }, "time": "2026-03-18T20:49:53+00:00" }, - { - "name": "phpdocumentor/type-resolver", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", - "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "psalm/phar": "^4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev", - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" - }, - "time": "2026-01-06T21:53:42+00:00" - }, { "name": "phpunit/php-code-coverage", "version": "12.5.7", diff --git a/config/settings.php b/config/settings.php new file mode 100644 index 0000000..c5045c4 --- /dev/null +++ b/config/settings.php @@ -0,0 +1,107 @@ + [ + + ], + + /* + * The path where the settings classes will be created. + */ + 'setting_class_path' => app_path('Settings'), + + /* + * In these directories settings migrations will be stored and ran when migrating. A settings + * migration created via the make:settings-migration command will be stored in the first path or + * a custom defined path when running the command. + */ + 'migrations_paths' => [ + database_path('settings'), + ], + + /* + * When no repository was set for a settings class the following repository + * will be used for loading and saving settings. + */ + 'default_repository' => 'database', + + /* + * Settings will be stored and loaded from these repositories. + */ + 'repositories' => [ + 'database' => [ + 'type' => DatabaseSettingsRepository::class, + 'model' => null, + 'table' => null, + 'connection' => null, + ], + 'redis' => [ + 'type' => RedisSettingsRepository::class, + 'connection' => null, + 'prefix' => null, + ], + ], + + /* + * The encoder and decoder will determine how settings are stored and + * retrieved in the database. By default, `json_encode` and `json_decode` + * are used. + */ + 'encoder' => null, + 'decoder' => null, + + /* + * The contents of settings classes can be cached through your application, + * settings will be stored within a provided Laravel store and can have an + * additional prefix. + */ + 'cache' => [ + 'enabled' => (bool) env('SETTINGS_CACHE_ENABLED', false), + 'store' => null, + 'prefix' => null, + 'ttl' => null, + + /* + * When enabled, uses Laravel's memoized cache driver (requires Laravel 12.9+) + * to keep resolved values in memory during a single request. + */ + 'memo' => env('SETTINGS_CACHE_MEMO', false), + ], + + /* + * These global casts will be automatically used whenever a property within + * your settings class isn't a default PHP type. + */ + 'global_casts' => [ + DateTimeInterface::class => DateTimeInterfaceCast::class, + DateTimeZone::class => DateTimeZoneCast::class, + // Spatie\DataTransferObject\DataTransferObject::class => Spatie\LaravelSettings\SettingsCasts\DtoCast::class, + Data::class => DataCast::class, + ], + + /* + * The package will look for settings in these paths and automatically + * register them. + */ + 'auto_discover_settings' => [ + app_path('Settings'), + ], + + /* + * Automatically discovered settings classes can be cached, so they don't + * need to be searched each time the application boots up. + */ + 'discovered_settings_cache_path' => base_path('bootstrap/cache'), +]; diff --git a/database/migrations/2022_12_14_083707_create_settings_table.php b/database/migrations/2022_12_14_083707_create_settings_table.php new file mode 100644 index 0000000..33bb8a5 --- /dev/null +++ b/database/migrations/2022_12_14_083707_create_settings_table.php @@ -0,0 +1,25 @@ +id(); + + $table->string('group'); + $table->string('name'); + $table->boolean('locked')->default(false); + $table->json('payload'); + + $table->timestamp('created_at')->useCurrent(); + $table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate(); + + $table->unique(['group', 'name']); + }); + } +}; diff --git a/database/settings/2026_06_11_085959_create_app_settings.php b/database/settings/2026_06_11_085959_create_app_settings.php new file mode 100644 index 0000000..871e447 --- /dev/null +++ b/database/settings/2026_06_11_085959_create_app_settings.php @@ -0,0 +1,48 @@ +migrator->inGroup('system', function (SettingsBlueprint $blueprint): void { + $blueprint->add('app_name', config('app.name', 'DST Collection')); + $blueprint->add('about_app', null); + $blueprint->add('email', null); + $blueprint->add('phone', null); + $blueprint->add('logo', null); + $blueprint->add('login_cover', null); + }); + + $this->migrator->inGroup('social_media', function (SettingsBlueprint $blueprint): void { + $blueprint->add('instagram_url', null); + $blueprint->add('facebook_url', null); + $blueprint->add('tiktok_url', null); + }); + + $this->migrator->inGroup('marketplace', function (SettingsBlueprint $blueprint): void { + $blueprint->add('tiktok_shop_enabled', true); + $blueprint->add('tiktok_shop_admin_fee', 5.0); + $blueprint->add('tiktok_shop_transaction_fee', 1.0); + $blueprint->add('tiktok_shop_payment_fee', 0.7); + $blueprint->add('tiktok_shop_affiliate_commission', 0.0); + $blueprint->add('tiktok_shop_shipping_subsidy', 0.0); + $blueprint->add('tiktok_shop_vat_rate', 11.0); + $blueprint->add('tiktok_shop_url', null); + $blueprint->add('tiktok_shop_id', null); + + $blueprint->add('shopee_enabled', true); + $blueprint->add('shopee_commission_fee', 6.0); + $blueprint->add('shopee_transaction_fee', 2.0); + $blueprint->add('shopee_service_fee', 0.0); + $blueprint->add('shopee_payment_fee', 0.0); + $blueprint->add('shopee_affiliate_commission', 0.0); + $blueprint->add('shopee_shipping_subsidy', 0.0); + $blueprint->add('shopee_voucher_fee', 0.0); + $blueprint->add('shopee_shop_url', null); + $blueprint->add('shopee_shop_id', null); + }); + } +}; diff --git a/resources/js/components/AppSidebar.vue b/resources/js/components/AppSidebar.vue index fe6b569..39c59b1 100644 --- a/resources/js/components/AppSidebar.vue +++ b/resources/js/components/AppSidebar.vue @@ -1,6 +1,6 @@