refactor: migrate general settings to spatie/laravel-settings and rename properties for consistency
This commit is contained in:
parent
044dffefa8
commit
3fcdaa7475
@ -8,7 +8,6 @@
|
|||||||
use App\Enums\PriceType;
|
use App\Enums\PriceType;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\Manage\Order\OrderRequest;
|
use App\Http\Requests\Admin\Manage\Order\OrderRequest;
|
||||||
use App\Models\GeneralSetting;
|
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\OrderItem;
|
use App\Models\OrderItem;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
@ -122,7 +121,6 @@ public function show(Order $order): Response
|
|||||||
|
|
||||||
return Inertia::render('admin/manage/order/show', [
|
return Inertia::render('admin/manage/order/show', [
|
||||||
'order' => $order,
|
'order' => $order,
|
||||||
'setting' => GeneralSetting::first(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\System\GeneralSettingRequest;
|
use App\Http\Requests\Admin\System\GeneralSettingRequest;
|
||||||
use App\Models\GeneralSetting;
|
use App\Settings\GeneralSettings;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
use Inertia\Response;
|
use Inertia\Response;
|
||||||
|
|
||||||
@ -13,37 +14,47 @@ class GeneralSettingController extends Controller
|
|||||||
{
|
{
|
||||||
public function index(): Response
|
public function index(): Response
|
||||||
{
|
{
|
||||||
return Inertia::render('admin/system/settings/index', [
|
return Inertia::render('admin/system/settings/index');
|
||||||
'setting' => GeneralSetting::first(),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(GeneralSettingRequest $request): RedirectResponse
|
public function update(GeneralSettingRequest $request, GeneralSettings $settings): RedirectResponse
|
||||||
{
|
{
|
||||||
$validated = $request->validated();
|
$validated = $request->validated();
|
||||||
|
|
||||||
$setting = GeneralSetting::first();
|
$settings->site_name = $validated['site_name'];
|
||||||
if ($setting) {
|
$settings->site_description = $validated['site_description'];
|
||||||
$setting->update($validated);
|
$settings->site_address = $validated['site_address'];
|
||||||
} else {
|
$settings->site_phone = $validated['site_phone'];
|
||||||
$setting = GeneralSetting::create($validated);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->hasFile('logo_light')) {
|
if ($request->hasFile('logo_light')) {
|
||||||
$setting->addMediaFromRequest('logo_light')->toMediaCollection('logo_light');
|
if ($settings->logo_light) {
|
||||||
|
Storage::disk('public')->delete($settings->logo_light);
|
||||||
|
}
|
||||||
|
$settings->logo_light = $request->file('logo_light')->store('settings', 'public');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->hasFile('logo_dark')) {
|
if ($request->hasFile('logo_dark')) {
|
||||||
$setting->addMediaFromRequest('logo_dark')->toMediaCollection('logo_dark');
|
if ($settings->logo_dark) {
|
||||||
|
Storage::disk('public')->delete($settings->logo_dark);
|
||||||
|
}
|
||||||
|
$settings->logo_dark = $request->file('logo_dark')->store('settings', 'public');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->hasFile('icon_light')) {
|
if ($request->hasFile('icon_light')) {
|
||||||
$setting->addMediaFromRequest('icon_light')->toMediaCollection('icon_light');
|
if ($settings->icon_light) {
|
||||||
|
Storage::disk('public')->delete($settings->icon_light);
|
||||||
|
}
|
||||||
|
$settings->icon_light = $request->file('icon_light')->store('settings', 'public');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->hasFile('icon_dark')) {
|
if ($request->hasFile('icon_dark')) {
|
||||||
$setting->addMediaFromRequest('icon_dark')->toMediaCollection('icon_dark');
|
if ($settings->icon_dark) {
|
||||||
|
Storage::disk('public')->delete($settings->icon_dark);
|
||||||
}
|
}
|
||||||
|
$settings->icon_dark = $request->file('icon_dark')->store('settings', 'public');
|
||||||
|
}
|
||||||
|
|
||||||
|
$settings->save();
|
||||||
|
|
||||||
return redirect()->back()->with('success', 'Pengaturan berhasil diperbarui');
|
return redirect()->back()->with('success', 'Pengaturan berhasil diperbarui');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Category;
|
use App\Models\Category;
|
||||||
use App\Models\GeneralSetting;
|
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
|
|
||||||
class HomepageController extends Controller
|
class HomepageController extends Controller
|
||||||
@ -14,7 +13,6 @@ public function __invoke()
|
|||||||
$categorySlug = request('category');
|
$categorySlug = request('category');
|
||||||
|
|
||||||
return inertia('homepage', [
|
return inertia('homepage', [
|
||||||
'setting' => GeneralSetting::first(),
|
|
||||||
'categories' => Category::active()->get(),
|
'categories' => Category::active()->get(),
|
||||||
'bestSellers' => Product::with(['categories' => fn ($q) => $q->active(), 'prices'])
|
'bestSellers' => Product::with(['categories' => fn ($q) => $q->active(), 'prices'])
|
||||||
->when($search, function ($query, $search) {
|
->when($search, function ($query, $search) {
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
use App\Models\GeneralSetting;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Inertia\Middleware;
|
use Inertia\Middleware;
|
||||||
|
|
||||||
@ -39,7 +38,6 @@ public function share(Request $request): array
|
|||||||
return [
|
return [
|
||||||
...parent::share($request),
|
...parent::share($request),
|
||||||
'name' => config('app.name'),
|
'name' => config('app.name'),
|
||||||
'setting' => GeneralSetting::first(),
|
|
||||||
'auth' => [
|
'auth' => [
|
||||||
'user' => $request->user() ? $request->user()->load('profile') : null,
|
'user' => $request->user() ? $request->user()->load('profile') : null,
|
||||||
'roles' => $request->user() ? $request->user()->getRoleNames() : [],
|
'roles' => $request->user() ? $request->user()->getRoleNames() : [],
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests\Admin\System;
|
namespace App\Http\Requests\Admin\System;
|
||||||
|
|
||||||
use App\Models\GeneralSetting;
|
|
||||||
use Illuminate\Contracts\Validation\ValidationRule;
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
@ -23,16 +22,14 @@ public function authorize(): bool
|
|||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$settingExists = GeneralSetting::exists();
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'name' => ['required', 'string', 'max:50'],
|
'site_name' => ['required', 'string', 'max:50'],
|
||||||
'description' => ['required', 'string'],
|
'site_description' => ['required', 'string'],
|
||||||
'address' => ['required', 'string'],
|
'site_address' => ['required', 'string'],
|
||||||
'phone' => ['required', 'string', 'max:20'],
|
'site_phone' => ['required', 'string', 'max:20'],
|
||||||
'logo_light' => [$settingExists ? 'nullable' : 'required', 'image', 'max:2048'],
|
'logo_light' => ['nullable', 'image', 'max:2048'],
|
||||||
'logo_dark' => ['nullable', 'image', 'max:2048'],
|
'logo_dark' => ['nullable', 'image', 'max:2048'],
|
||||||
'icon_light' => [$settingExists ? 'nullable' : 'required', 'image', 'max:1024'],
|
'icon_light' => ['nullable', 'image', 'max:1024'],
|
||||||
'icon_dark' => ['nullable', 'image', 'max:1024'],
|
'icon_dark' => ['nullable', 'image', 'max:1024'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,111 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Spatie\Activitylog\LogOptions;
|
|
||||||
use Spatie\Activitylog\Models\Activity;
|
|
||||||
use Spatie\Activitylog\Traits\LogsActivity;
|
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
|
||||||
|
|
||||||
#[Guarded(['id'])]
|
|
||||||
#[Appends(['logo_light_url', 'logo_dark_url', 'icon_light_url', 'icon_dark_url'])]
|
|
||||||
class GeneralSetting extends Model implements HasMedia
|
|
||||||
{
|
|
||||||
use HasFactory, InteractsWithMedia, LogsActivity;
|
|
||||||
|
|
||||||
public function registerMediaCollections(): void
|
|
||||||
{
|
|
||||||
$this->addMediaCollection('logo_light')
|
|
||||||
->singleFile();
|
|
||||||
|
|
||||||
$this->addMediaCollection('logo_dark')
|
|
||||||
->singleFile();
|
|
||||||
|
|
||||||
$this->addMediaCollection('icon_light')
|
|
||||||
->singleFile();
|
|
||||||
|
|
||||||
$this->addMediaCollection('icon_dark')
|
|
||||||
->singleFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function logoLightUrl(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMediaUrl('logo_light') ?: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function logoDarkUrl(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMediaUrl('logo_dark') ?: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function iconLightUrl(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMediaUrl('icon_light') ?: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function iconDarkUrl(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn () => $this->getFirstMediaUrl('icon_dark') ?: null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getActivitylogOptions(): LogOptions
|
|
||||||
{
|
|
||||||
return LogOptions::defaults()
|
|
||||||
->logOnly(['name', 'description', 'address', 'phone'])
|
|
||||||
->logOnlyDirty()
|
|
||||||
->useLogName('Pengaturan Umum');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function tapActivity(Activity $activity, string $eventName)
|
|
||||||
{
|
|
||||||
$activity->description = match ($eventName) {
|
|
||||||
'created' => 'TAMBAH',
|
|
||||||
'updated' => 'UBAH',
|
|
||||||
'deleted' => 'HAPUS',
|
|
||||||
default => $activity->description,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isset($activity->properties['attributes'])) {
|
|
||||||
$attributeMap = [
|
|
||||||
'name' => 'Nama Aplikasi',
|
|
||||||
'description' => 'Deskripsi',
|
|
||||||
'address' => 'Alamat',
|
|
||||||
'phone' => 'No. Telepon',
|
|
||||||
];
|
|
||||||
|
|
||||||
$properties = $activity->properties->toArray();
|
|
||||||
|
|
||||||
$localizeValues = function ($attrs) use ($attributeMap) {
|
|
||||||
$newAttrs = [];
|
|
||||||
foreach ($attrs as $key => $value) {
|
|
||||||
$label = $attributeMap[$key] ?? $key;
|
|
||||||
$newAttrs[$label] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $newAttrs;
|
|
||||||
};
|
|
||||||
|
|
||||||
$properties['attributes'] = $localizeValues($properties['attributes']);
|
|
||||||
|
|
||||||
if (isset($properties['old'])) {
|
|
||||||
$properties['old'] = $localizeValues($properties['old']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$activity->properties = collect($properties);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
75
app/Providers/ViewServiceProvider.php
Normal file
75
app/Providers/ViewServiceProvider.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View Service Provider
|
||||||
|
*
|
||||||
|
* This provider handles global data sharing for both Inertia and Blade views.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Settings\GeneralSettings;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Facades\View;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Inertia\Inertia;
|
||||||
|
|
||||||
|
class ViewServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register any application services.
|
||||||
|
*/
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap any application services.
|
||||||
|
*/
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
if ($this->app->runningInConsole() && ! $this->app->environment('testing')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Share settings with Inertia
|
||||||
|
Inertia::share('setting', function () {
|
||||||
|
try {
|
||||||
|
$settings = app(GeneralSettings::class);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'site_name' => $settings->site_name,
|
||||||
|
'site_description' => $settings->site_description,
|
||||||
|
'site_address' => $settings->site_address,
|
||||||
|
'site_phone' => $settings->site_phone,
|
||||||
|
'logo_light_url' => $settings->logo_light ? Storage::url($settings->logo_light) : null,
|
||||||
|
'logo_dark_url' => $settings->logo_dark ? Storage::url($settings->logo_dark) : null,
|
||||||
|
'icon_light_url' => $settings->icon_light ? Storage::url($settings->icon_light) : null,
|
||||||
|
'icon_dark_url' => $settings->icon_dark ? Storage::url($settings->icon_dark) : null,
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Share settings with Blade views
|
||||||
|
View::composer('*', function ($view) {
|
||||||
|
try {
|
||||||
|
$settings = app(GeneralSettings::class);
|
||||||
|
$view->with('setting', [
|
||||||
|
'site_name' => $settings->site_name,
|
||||||
|
'site_description' => $settings->site_description,
|
||||||
|
'site_address' => $settings->site_address,
|
||||||
|
'site_phone' => $settings->site_phone,
|
||||||
|
'logo_light_url' => $settings->logo_light ? Storage::url($settings->logo_light) : null,
|
||||||
|
'logo_dark_url' => $settings->logo_dark ? Storage::url($settings->logo_dark) : null,
|
||||||
|
'icon_light_url' => $settings->icon_light ? Storage::url($settings->icon_light) : null,
|
||||||
|
'icon_dark_url' => $settings->icon_dark ? Storage::url($settings->icon_dark) : null,
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$view->with('setting', []);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
29
app/Settings/GeneralSettings.php
Normal file
29
app/Settings/GeneralSettings.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Settings;
|
||||||
|
|
||||||
|
use Spatie\LaravelSettings\Settings;
|
||||||
|
|
||||||
|
class GeneralSettings extends Settings
|
||||||
|
{
|
||||||
|
public string $site_name;
|
||||||
|
|
||||||
|
public string $site_description;
|
||||||
|
|
||||||
|
public string $site_address;
|
||||||
|
|
||||||
|
public string $site_phone;
|
||||||
|
|
||||||
|
public ?string $logo_light;
|
||||||
|
|
||||||
|
public ?string $logo_dark;
|
||||||
|
|
||||||
|
public ?string $icon_light;
|
||||||
|
|
||||||
|
public ?string $icon_dark;
|
||||||
|
|
||||||
|
public static function group(): string
|
||||||
|
{
|
||||||
|
return 'general';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
use App\Providers\AppServiceProvider;
|
use App\Providers\AppServiceProvider;
|
||||||
use App\Providers\FortifyServiceProvider;
|
use App\Providers\FortifyServiceProvider;
|
||||||
|
use App\Providers\ViewServiceProvider;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
AppServiceProvider::class,
|
AppServiceProvider::class,
|
||||||
FortifyServiceProvider::class,
|
FortifyServiceProvider::class,
|
||||||
|
ViewServiceProvider::class,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
"spatie/laravel-activitylog": "^4.12",
|
"spatie/laravel-activitylog": "^4.12",
|
||||||
"spatie/laravel-medialibrary": "^11.21",
|
"spatie/laravel-medialibrary": "^11.21",
|
||||||
"spatie/laravel-permission": "^7.3",
|
"spatie/laravel-permission": "^7.3",
|
||||||
|
"spatie/laravel-settings": "^3.8",
|
||||||
"spatie/laravel-sluggable": "^3.8"
|
"spatie/laravel-sluggable": "^3.8"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|||||||
405
composer.lock
generated
405
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "1e97290615923580b9a565671ca7bfae",
|
"content-hash": "a42046c1187875d3d873b061a01fa885",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "archtechx/enums",
|
"name": "archtechx/enums",
|
||||||
@ -445,6 +445,54 @@
|
|||||||
},
|
},
|
||||||
"time": "2024-07-08T12:26:09+00:00"
|
"time": "2024-07-08T12:26:09+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": "doctrine/inflector",
|
"name": "doctrine/inflector",
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
@ -3976,6 +4024,117 @@
|
|||||||
},
|
},
|
||||||
"time": "2025-09-24T15:06:41+00:00"
|
"time": "2025-09-24T15:06:41+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",
|
"name": "phpoption/phpoption",
|
||||||
"version": "1.9.5",
|
"version": "1.9.5",
|
||||||
@ -5316,6 +5475,91 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-04-07T15:19:42+00:00"
|
"time": "2026-04-07T15:19:42+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "spatie/laravel-settings",
|
||||||
|
"version": "3.8.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/spatie/laravel-settings.git",
|
||||||
|
"reference": "09b788ee96d205699420dedb8a6aa8c4c8af84fe"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/spatie/laravel-settings/zipball/09b788ee96d205699420dedb8a6aa8c4c8af84fe",
|
||||||
|
"reference": "09b788ee96d205699420dedb8a6aa8c4c8af84fe",
|
||||||
|
"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.8.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://spatie.be/open-source/support-us",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/spatie",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-04-28T07:05:06+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/laravel-sluggable",
|
"name": "spatie/laravel-sluggable",
|
||||||
"version": "3.8.1",
|
"version": "3.8.1",
|
||||||
@ -8245,54 +8489,6 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-03-29T15:46:14+00:00"
|
"time": "2026-03-29T15:46:14+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",
|
"name": "fakerphp/faker",
|
||||||
"version": "v1.24.1",
|
"version": "v1.24.1",
|
||||||
@ -9630,59 +9826,6 @@
|
|||||||
},
|
},
|
||||||
"time": "2022-02-21T01:04:05+00:00"
|
"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",
|
"name": "phpdocumentor/reflection-docblock",
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
@ -9748,64 +9891,6 @@
|
|||||||
},
|
},
|
||||||
"time": "2026-03-18T20:49:53+00:00"
|
"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",
|
"name": "phpunit/php-code-coverage",
|
||||||
"version": "12.5.6",
|
"version": "12.5.6",
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create(config('settings.repositories.database.table') ?? 'settings', function (Blueprint $table): void {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
$table->string('group');
|
||||||
|
$table->string('name');
|
||||||
|
$table->boolean('locked')->default(false);
|
||||||
|
$table->json('payload');
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->unique(['group', 'name']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
return new class extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*/
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
Schema::create('general_settings', function (Blueprint $table) {
|
|
||||||
$table->id();
|
|
||||||
$table->string('name', 50);
|
|
||||||
$table->text('description');
|
|
||||||
$table->text('address');
|
|
||||||
$table->string('phone', 20);
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*/
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('general_settings');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\GeneralSetting;
|
use App\Settings\GeneralSettings;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class GeneralSettingSeeder extends Seeder
|
class GeneralSettingSeeder extends Seeder
|
||||||
@ -12,11 +12,11 @@ class GeneralSettingSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
GeneralSetting::updateOrCreate([
|
$settings = app(GeneralSettings::class);
|
||||||
'name' => 'VN Grup',
|
$settings->site_name = 'VN Grup';
|
||||||
'description' => 'VN Grup adalah Toko Baju Daster Online yang menghadirkan koleksi baju daster berkualitas tinggi untuk wanita yang mengutamakan kenyamanan tanpa mengorbankan gaya. Kami menyediakan berbagai macam daster dengan desain yang beragam, mulai dari yang sederhana dan klasik hingga yang modern dan trendi, cocok untuk berbagai kebutuhan, baik di rumah maupun saat bersantai di luar.',
|
$settings->site_description = 'VN Grup adalah Toko Baju Daster Online yang menghadirkan koleksi baju daster berkualitas tinggi untuk wanita yang mengutamakan kenyamanan tanpa mengorbankan gaya. Kami menyediakan berbagai macam daster dengan desain yang beragam, mulai dari yang sederhana dan klasik hingga yang modern dan trendi, cocok untuk berbagai kebutuhan, baik di rumah maupun saat bersantai di luar.';
|
||||||
'address' => 'Jl. Raya Pabuaran-Cipeunduy, Kec. Pabuaran, Kab. Subang, Jawa Barat',
|
$settings->site_address = 'Jl. Raya Pabuaran-Cipeunduy, Kec. Pabuaran, Kab. Subang, Jawa Barat';
|
||||||
'phone' => '089679965828',
|
$settings->site_phone = '089679965828';
|
||||||
]);
|
$settings->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||||
|
|
||||||
|
return new class extends SettingsMigration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$this->migrator->add('general.site_name', 'VN Grup');
|
||||||
|
$this->migrator->add('general.site_description', 'VN Grup adalah Toko Baju Daster Online yang menghadirkan koleksi baju daster berkualitas tinggi untuk wanita yang mengutamakan kenyamanan tanpa mengorbankan gaya.');
|
||||||
|
$this->migrator->add('general.site_address', 'Jl. Raya Pabuaran-Cipeunduy, Kec. Pabuaran, Kab. Subang, Jawa Barat');
|
||||||
|
$this->migrator->add('general.site_phone', '089679965828');
|
||||||
|
$this->migrator->add('general.logo_light', null);
|
||||||
|
$this->migrator->add('general.logo_dark', null);
|
||||||
|
$this->migrator->add('general.icon_light', null);
|
||||||
|
$this->migrator->add('general.icon_dark', null);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -9,20 +9,20 @@ export default function AppLogo() {
|
|||||||
{setting?.logo_light_url ? (
|
{setting?.logo_light_url ? (
|
||||||
<img
|
<img
|
||||||
src={setting.logo_light_url}
|
src={setting.logo_light_url}
|
||||||
alt={setting.name}
|
alt={setting.site_name}
|
||||||
className="max-h-8 w-auto dark:hidden"
|
className="max-h-8 w-auto dark:hidden"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{setting?.logo_dark_url ? (
|
{setting?.logo_dark_url ? (
|
||||||
<img
|
<img
|
||||||
src={setting.logo_dark_url}
|
src={setting.logo_dark_url}
|
||||||
alt={setting.name}
|
alt={setting.site_name}
|
||||||
className="hidden max-h-8 w-auto dark:block"
|
className="hidden max-h-8 w-auto dark:block"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{!setting?.logo_light_url && !setting?.logo_dark_url && (
|
{!setting?.logo_light_url && !setting?.logo_dark_url && (
|
||||||
<span className="truncate font-semibold tracking-tight">
|
<span className="truncate font-semibold tracking-tight">
|
||||||
{setting?.name || 'VN Grup'}
|
{setting?.site_name || 'VN Grup'}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -62,17 +62,17 @@ export default function OrderShow({ order, setting }: ShowProps) {
|
|||||||
<img src={setting.logo_light_url} alt="Logo" className="h-10 w-auto" />
|
<img src={setting.logo_light_url} alt="Logo" className="h-10 w-auto" />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary text-2xl font-bold text-primary-foreground">
|
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary text-2xl font-bold text-primary-foreground">
|
||||||
{setting?.name?.charAt(0) || 'V'}
|
{setting?.site_name?.charAt(0) || 'V'}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-2xl font-bold text-foreground">{setting?.name || 'VN Grup'}</h2>
|
<h2 className="text-2xl font-bold text-foreground">{setting?.site_name || 'VN Grup'}</h2>
|
||||||
<p className="text-sm text-muted-foreground italic">Your Style, Our Passion</p>
|
<p className="text-sm text-muted-foreground italic">Your Style, Our Passion</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="max-w-xs space-y-1 text-sm text-muted-foreground">
|
<div className="max-w-xs space-y-1 text-sm text-muted-foreground">
|
||||||
<p>{setting?.address || 'Alamat Toko Belum Diatur'}</p>
|
<p>{setting?.site_address || 'Alamat Toko Belum Diatur'}</p>
|
||||||
<p>{setting?.phone || '-'}</p>
|
<p>{setting?.site_phone || '-'}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ export default function OrderShow({ order, setting }: ShowProps) {
|
|||||||
<div className="rounded-xl bg-muted/30 p-4 space-y-2 border border-dashed">
|
<div className="rounded-xl bg-muted/30 p-4 space-y-2 border border-dashed">
|
||||||
<h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">Catatan:</h4>
|
<h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">Catatan:</h4>
|
||||||
<p className="text-xs text-muted-foreground leading-relaxed">
|
<p className="text-xs text-muted-foreground leading-relaxed">
|
||||||
Terima kasih telah berbelanja di {setting?.name || 'VN Grup'}.
|
Terima kasih telah berbelanja di {setting?.site_name || 'VN Grup'}.
|
||||||
Barang yang sudah dibeli tidak dapat ditukar atau dikembalikan kecuali ada perjanjian sebelumnya.
|
Barang yang sudah dibeli tidak dapat ditukar atau dikembalikan kecuali ada perjanjian sebelumnya.
|
||||||
Simpan invoice ini sebagai bukti pembelian yang sah.
|
Simpan invoice ini sebagai bukti pembelian yang sah.
|
||||||
</p>
|
</p>
|
||||||
@ -181,7 +181,7 @@ export default function OrderShow({ order, setting }: ShowProps) {
|
|||||||
|
|
||||||
<div className="pt-10 text-center text-sm text-muted-foreground print:pt-20">
|
<div className="pt-10 text-center text-sm text-muted-foreground print:pt-20">
|
||||||
<p className="font-medium">Semoga hari Anda menyenangkan!</p>
|
<p className="font-medium">Semoga hari Anda menyenangkan!</p>
|
||||||
<p className="text-[10px] mt-1 opacity-50">Generated by {setting?.name || 'VN Grup'} System</p>
|
<p className="text-[10px] mt-1 opacity-50">Generated by {setting?.site_name || 'VN Grup'} System</p>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@ -17,10 +17,10 @@ export default function SettingIndex({
|
|||||||
setting: GeneralSetting | null;
|
setting: GeneralSetting | null;
|
||||||
}) {
|
}) {
|
||||||
const { data, setData, post, processing, errors } = useForm({
|
const { data, setData, post, processing, errors } = useForm({
|
||||||
name: setting?.name || '',
|
site_name: setting?.site_name || '',
|
||||||
description: setting?.description || '',
|
site_description: setting?.site_description || '',
|
||||||
address: setting?.address || '',
|
site_address: setting?.site_address || '',
|
||||||
phone: setting?.phone || '',
|
site_phone: setting?.site_phone || '',
|
||||||
logo_light: null as File | null,
|
logo_light: null as File | null,
|
||||||
logo_dark: null as File | null,
|
logo_dark: null as File | null,
|
||||||
icon_light: null as File | null,
|
icon_light: null as File | null,
|
||||||
@ -107,41 +107,41 @@ export default function SettingIndex({
|
|||||||
<CardContent className="space-y-6">
|
<CardContent className="space-y-6">
|
||||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||||
<Field>
|
<Field>
|
||||||
<Label htmlFor="phone" required>
|
<Label htmlFor="site_phone" required>
|
||||||
No. Telepon
|
No. Telepon
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="phone"
|
id="site_phone"
|
||||||
value={data.phone || ''}
|
value={data.site_phone || ''}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setData('phone', e.target.value)
|
setData('site_phone', e.target.value)
|
||||||
}
|
}
|
||||||
placeholder="0812xxxx"
|
placeholder="0812xxxx"
|
||||||
/>
|
/>
|
||||||
<FieldError
|
<FieldError
|
||||||
error={errors.phone}
|
error={errors.site_phone}
|
||||||
label="No. Telepon"
|
label="No. Telepon"
|
||||||
className="text-xs"
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
<Field>
|
<Field>
|
||||||
<Label htmlFor="name" required>
|
<Label htmlFor="site_name" required>
|
||||||
Nama Aplikasi
|
Nama Aplikasi
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="name"
|
id="site_name"
|
||||||
name="name"
|
name="site_name"
|
||||||
value={data.name}
|
value={data.site_name}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setData('name', e.target.value)
|
setData('site_name', e.target.value)
|
||||||
}
|
}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
placeholder="Contoh: VN Grup Dress"
|
placeholder="Contoh: VN Grup Dress"
|
||||||
maxLength={100}
|
maxLength={100}
|
||||||
/>
|
/>
|
||||||
<FieldError
|
<FieldError
|
||||||
error={errors.name}
|
error={errors.site_name}
|
||||||
label="Nama Aplikasi"
|
label="Nama Aplikasi"
|
||||||
className="text-xs"
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
@ -149,15 +149,15 @@ export default function SettingIndex({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Field>
|
<Field>
|
||||||
<Label htmlFor="description" required>
|
<Label htmlFor="site_description" required>
|
||||||
Deskripsi
|
Deskripsi
|
||||||
</Label>
|
</Label>
|
||||||
<Textarea
|
<Textarea
|
||||||
id="description"
|
id="site_description"
|
||||||
value={data.description || ''}
|
value={data.site_description || ''}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setData(
|
setData(
|
||||||
'description',
|
'site_description',
|
||||||
e.target.value,
|
e.target.value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -165,27 +165,27 @@ export default function SettingIndex({
|
|||||||
rows={4}
|
rows={4}
|
||||||
/>
|
/>
|
||||||
<FieldError
|
<FieldError
|
||||||
error={errors.description}
|
error={errors.site_description}
|
||||||
label="Deskripsi"
|
label="Deskripsi"
|
||||||
className="mt-1 text-xs"
|
className="mt-1 text-xs"
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
<Field>
|
<Field>
|
||||||
<Label htmlFor="address" required>
|
<Label htmlFor="site_address" required>
|
||||||
Alamat
|
Alamat
|
||||||
</Label>
|
</Label>
|
||||||
<Textarea
|
<Textarea
|
||||||
id="address"
|
id="site_address"
|
||||||
value={data.address || ''}
|
value={data.site_address || ''}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setData('address', e.target.value)
|
setData('site_address', e.target.value)
|
||||||
}
|
}
|
||||||
placeholder="Alamat lengkap toko"
|
placeholder="Alamat lengkap toko"
|
||||||
rows={3}
|
rows={3}
|
||||||
/>
|
/>
|
||||||
<FieldError
|
<FieldError
|
||||||
error={errors.address}
|
error={errors.site_address}
|
||||||
label="Alamat"
|
label="Alamat"
|
||||||
className="mt-1 text-xs"
|
className="mt-1 text-xs"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -141,11 +141,11 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
{setting?.logo_light_url ? (
|
{setting?.logo_light_url ? (
|
||||||
<img
|
<img
|
||||||
src={setting.logo_light_url}
|
src={setting.logo_light_url}
|
||||||
alt={setting.name}
|
alt={setting.site_name}
|
||||||
className="max-h-8 w-auto"
|
className="max-h-8 w-auto"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
setting?.name || 'VN Grup'
|
setting?.site_name || 'VN Grup'
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
<p className="mb-4 text-sm font-medium opacity-60">{formatCurrency(item.retail_price)}</p>
|
<p className="mb-4 text-sm font-medium opacity-60">{formatCurrency(item.retail_price)}</p>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={`https://wa.me/628123456789?text=${encodeURIComponent(`Halo ${setting?.name || 'VN Grup'}, saya ingin memesan ${item.name} seharga ${formatCurrency(item.retail_price)}. Mohon info detail pembayarannya.`)}`}
|
href={`https://wa.me/628123456789?text=${encodeURIComponent(`Halo ${setting?.site_name || 'VN Grup'}, saya ingin memesan ${item.name} seharga ${formatCurrency(item.retail_price)}. Mohon info detail pembayarannya.`)}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="inline-flex items-center gap-2 border border-[#1e4a6d] px-6 py-2 text-[8px] font-bold uppercase tracking-widest transition-all hover:bg-[#1e4a6d] hover:text-white"
|
className="inline-flex items-center gap-2 border border-[#1e4a6d] px-6 py-2 text-[8px] font-bold uppercase tracking-widest transition-all hover:bg-[#1e4a6d] hover:text-white"
|
||||||
@ -412,10 +412,10 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
{/* Brand Info */}
|
{/* Brand Info */}
|
||||||
<div className="lg:col-span-6">
|
<div className="lg:col-span-6">
|
||||||
<div className="mb-6 flex items-center gap-2 text-xl font-bold uppercase tracking-tighter">
|
<div className="mb-6 flex items-center gap-2 text-xl font-bold uppercase tracking-tighter">
|
||||||
{setting?.logo_light_url ? <img src={setting.logo_light_url} alt={setting.name} className="max-h-8" /> : (setting?.name || 'VN Grup')}
|
{setting?.logo_light_url ? <img src={setting.logo_light_url} alt={setting.site_name} className="max-h-8" /> : (setting?.site_name || 'VN Grup')}
|
||||||
</div>
|
</div>
|
||||||
<p className="mb-8 text-sm leading-relaxed opacity-60">
|
<p className="mb-8 text-sm leading-relaxed opacity-60">
|
||||||
{setting?.description || 'Menghadirkan produk esensial yang tak lekang oleh waktu dengan fokus pada kualitas, keberlanjutan, dan gaya yang abadi.'}
|
{setting?.site_description || 'Menghadirkan produk esensial yang tak lekang oleh waktu dengan fokus pada kualitas, keberlanjutan, dan gaya yang abadi.'}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex gap-4">
|
<div className="flex gap-4">
|
||||||
<Facebook size={18} className="cursor-pointer hover:opacity-50" />
|
<Facebook size={18} className="cursor-pointer hover:opacity-50" />
|
||||||
@ -443,13 +443,13 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
<Search size={14} className="rotate-45" />
|
<Search size={14} className="rotate-45" />
|
||||||
</div>
|
</div>
|
||||||
<p className="leading-relaxed whitespace-pre-line">
|
<p className="leading-relaxed whitespace-pre-line">
|
||||||
{setting?.address || 'Jl. Raya Utama No. 123, \n Kec. Lengkong, Kota Bandung, \n Jawa Barat 40262'}
|
{setting?.site_address || 'Jl. Raya Utama No. 123, \n Kec. Lengkong, Kota Bandung, \n Jawa Barat 40262'}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Phone size={14} />
|
<Phone size={14} />
|
||||||
<a href={`https://wa.me/${(setting?.phone || '+628123456789').replace(/\D/g, '')}`} target="_blank" className="hover:underline">
|
<a href={`https://wa.me/${(setting?.site_phone || '+628123456789').replace(/\D/g, '')}`} target="_blank" className="hover:underline">
|
||||||
{setting?.phone || '+62 812 3456 789'}
|
{setting?.site_phone || '+62 812 3456 789'}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -458,7 +458,7 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
|
|
||||||
{/* Bottom Bar */}
|
{/* Bottom Bar */}
|
||||||
<div className="px-6 py-6 text-center text-[10px] font-bold uppercase tracking-widest lg:px-12 lg:text-left">
|
<div className="px-6 py-6 text-center text-[10px] font-bold uppercase tracking-widest lg:px-12 lg:text-left">
|
||||||
<p className="opacity-50">© {new Date().getFullYear()} {setting?.name || 'VN Grup'}.</p>
|
<p className="opacity-50">© {new Date().getFullYear()} {setting?.site_name || 'VN Grup'}.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -564,7 +564,7 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
|
|
||||||
<div className="mt-auto pt-8 border-t border-[#1e4a6d]/10">
|
<div className="mt-auto pt-8 border-t border-[#1e4a6d]/10">
|
||||||
<a
|
<a
|
||||||
href={`https://wa.me/628123456789?text=${encodeURIComponent(`Halo ${setting?.name || 'VN Grup'}, saya tertarik dengan produk ${selectedProduct?.name} seharga ${formatCurrency(selectedProduct?.retail_price || 0)}. Bisa tanya-tanya dulu?`)}`}
|
href={`https://wa.me/628123456789?text=${encodeURIComponent(`Halo ${setting?.site_name || 'VN Grup'}, saya tertarik dengan produk ${selectedProduct?.name} seharga ${formatCurrency(selectedProduct?.retail_price || 0)}. Bisa tanya-tanya dulu?`)}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="w-full bg-[#1e4a6d] py-4 text-[10px] font-bold uppercase tracking-[0.2em] text-white transition-all hover:bg-[#15344e] flex items-center justify-center gap-2"
|
className="w-full bg-[#1e4a6d] py-4 text-[10px] font-bold uppercase tracking-[0.2em] text-white transition-all hover:bg-[#15344e] flex items-center justify-center gap-2"
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
export interface GeneralSetting {
|
export interface GeneralSetting {
|
||||||
id: number;
|
site_name: string;
|
||||||
name: string;
|
site_description: string | null;
|
||||||
description: string | null;
|
site_address: string | null;
|
||||||
address: string | null;
|
site_phone: string | null;
|
||||||
phone: string | null;
|
|
||||||
logo_light_url: string | null;
|
logo_light_url: string | null;
|
||||||
logo_dark_url: string | null;
|
logo_dark_url: string | null;
|
||||||
icon_light_url: string | null;
|
icon_light_url: string | null;
|
||||||
icon_dark_url: string | null;
|
icon_dark_url: string | null;
|
||||||
created_at: string;
|
|
||||||
updated_at: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,12 +31,8 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@php
|
@if ($setting['icon_light_url'] ?? null)
|
||||||
$setting = \App\Models\GeneralSetting::first();
|
<link rel="icon" href="{{ $setting['icon_light_url'] }}" sizes="any">
|
||||||
@endphp
|
|
||||||
|
|
||||||
@if ($setting && $setting->icon_light_url)
|
|
||||||
<link rel="icon" href="{{ $setting->icon_light_url }}" sizes="any">
|
|
||||||
@else
|
@else
|
||||||
<link rel="icon" href="/favicon.ico" sizes="any">
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||||
@endif
|
@endif
|
||||||
@ -47,7 +43,7 @@
|
|||||||
@viteReactRefresh
|
@viteReactRefresh
|
||||||
@vite(['resources/css/app.css', 'resources/js/app.tsx', "resources/js/pages/{$page['component']}.tsx"])
|
@vite(['resources/css/app.css', 'resources/js/app.tsx', "resources/js/pages/{$page['component']}.tsx"])
|
||||||
<x-inertia::head>
|
<x-inertia::head>
|
||||||
<title>{{ config('app.name', 'VN Grup') }}</title>
|
<title>{{ $setting['site_name'] ?? config('app.name', 'VN Grup') }}</title>
|
||||||
</x-inertia::head>
|
</x-inertia::head>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|||||||
@ -4,10 +4,10 @@
|
|||||||
use App\Enums\OrderStatus;
|
use App\Enums\OrderStatus;
|
||||||
use App\Enums\PaymentMethod;
|
use App\Enums\PaymentMethod;
|
||||||
use App\Enums\PriceType;
|
use App\Enums\PriceType;
|
||||||
use App\Models\GeneralSetting;
|
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\OrderItem;
|
use App\Models\OrderItem;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
|
use App\Settings\GeneralSettings;
|
||||||
|
|
||||||
use function Pest\Laravel\actingAs;
|
use function Pest\Laravel\actingAs;
|
||||||
use function Pest\Laravel\assertDatabaseHas;
|
use function Pest\Laravel\assertDatabaseHas;
|
||||||
@ -47,12 +47,12 @@
|
|||||||
]);
|
]);
|
||||||
actingAs($user);
|
actingAs($user);
|
||||||
|
|
||||||
GeneralSetting::create([
|
$settings = app(GeneralSettings::class);
|
||||||
'name' => 'VN Grup',
|
$settings->site_name = 'VN Grup';
|
||||||
'phone' => '08123456789',
|
$settings->site_phone = '08123456789';
|
||||||
'address' => 'Jl. Test No. 1',
|
$settings->site_address = 'Jl. Test No. 1';
|
||||||
'description' => 'Test Description',
|
$settings->site_description = 'Test Description';
|
||||||
]);
|
$settings->save();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can access order index page', function () {
|
it('can access order index page', function () {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\GeneralSetting;
|
use App\Settings\GeneralSettings;
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
@ -49,19 +49,11 @@
|
|||||||
it('can update general settings with logo and icon variants', function () {
|
it('can update general settings with logo and icon variants', function () {
|
||||||
Storage::fake('public');
|
Storage::fake('public');
|
||||||
|
|
||||||
// Ensure a setting exists first for testing update logic in Controller
|
|
||||||
$setting = GeneralSetting::create([
|
|
||||||
'name' => 'Old Name',
|
|
||||||
'description' => 'Old Description',
|
|
||||||
'address' => 'Old Address',
|
|
||||||
'phone' => '000',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'name' => 'VNGrup Dress',
|
'site_name' => 'VNGrup Dress',
|
||||||
'description' => 'Toko baju premium',
|
'site_description' => 'Toko baju premium',
|
||||||
'address' => 'Jakarta, Indonesia',
|
'site_address' => 'Jakarta, Indonesia',
|
||||||
'phone' => '081234567890',
|
'site_phone' => '081234567890',
|
||||||
'logo_light' => UploadedFile::fake()->image('logo_light.png'),
|
'logo_light' => UploadedFile::fake()->image('logo_light.png'),
|
||||||
'logo_dark' => UploadedFile::fake()->image('logo_dark.png'),
|
'logo_dark' => UploadedFile::fake()->image('logo_dark.png'),
|
||||||
'icon_light' => UploadedFile::fake()->image('icon_light.png'),
|
'icon_light' => UploadedFile::fake()->image('icon_light.png'),
|
||||||
@ -72,26 +64,34 @@
|
|||||||
->assertRedirect()
|
->assertRedirect()
|
||||||
->assertSessionHas('success');
|
->assertSessionHas('success');
|
||||||
|
|
||||||
assertDatabaseHas('general_settings', [
|
assertDatabaseHas('settings', [
|
||||||
'id' => $setting->id,
|
'group' => 'general',
|
||||||
'name' => 'VNGrup Dress',
|
'name' => 'site_name',
|
||||||
'phone' => '081234567890',
|
'payload' => json_encode('VNGrup Dress'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$setting->refresh();
|
assertDatabaseHas('settings', [
|
||||||
expect($setting->getFirstMediaUrl('logo_light'))->not->toBeEmpty();
|
'group' => 'general',
|
||||||
expect($setting->getFirstMediaUrl('logo_dark'))->not->toBeEmpty();
|
'name' => 'site_phone',
|
||||||
expect($setting->getFirstMediaUrl('icon_light'))->not->toBeEmpty();
|
'payload' => json_encode('081234567890'),
|
||||||
expect($setting->getFirstMediaUrl('icon_dark'))->not->toBeEmpty();
|
]);
|
||||||
|
|
||||||
|
$settings = app(GeneralSettings::class);
|
||||||
|
expect($settings->logo_light)->not->toBeNull();
|
||||||
|
expect($settings->logo_dark)->not->toBeNull();
|
||||||
|
expect($settings->icon_light)->not->toBeNull();
|
||||||
|
expect($settings->icon_dark)->not->toBeNull();
|
||||||
|
|
||||||
|
Storage::disk('public')->assertExists($settings->logo_light);
|
||||||
|
Storage::disk('public')->assertExists($settings->logo_dark);
|
||||||
|
Storage::disk('public')->assertExists($settings->icon_light);
|
||||||
|
Storage::disk('public')->assertExists($settings->icon_dark);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('validates settings update with new variants', function () {
|
it('validates settings update with new variants', function () {
|
||||||
// If setting doesn't exist, logo_light and icon_light are required
|
|
||||||
GeneralSetting::truncate();
|
|
||||||
|
|
||||||
postJson(route('system.settings.update'), [])
|
postJson(route('system.settings.update'), [])
|
||||||
->assertStatus(422)
|
->assertStatus(422)
|
||||||
->assertJsonValidationErrors(['name', 'description', 'address', 'phone', 'logo_light', 'icon_light']);
|
->assertJsonValidationErrors(['site_name', 'site_description', 'site_address', 'site_phone']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -101,7 +101,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('cannot update settings without permission', function () {
|
it('cannot update settings without permission', function () {
|
||||||
postJson(route('system.settings.update'), ['name' => 'Unauthorized'])
|
postJson(route('system.settings.update'), ['site_name' => 'Unauthorized'])
|
||||||
->assertStatus(403);
|
->assertStatus(403);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user