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 @@