From 7594e7abac59612bf9503b7205a70e4d7cea24d7 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Mon, 6 Oct 2025 20:16:53 +0700 Subject: [PATCH] feat(formula): membuat crud formula --- .../Datatable/Studio/Master/FormulasTable.php | 63 ++++++++++++ .../Forms/Studio/Master/FormulaForm.php | 67 +++++++++++++ app/Livewire/Studio/Master/Formula.php | 95 +++++++++++++++++++ app/Models/Formula.php | 23 +++++ app/Providers/ViewServiceProvider.php | 7 ++ ...025_10_06_124919_create_formulas_table.php | 31 ++++++ database/seeders/RolePermissionSeeder.php | 5 + .../livewire/studio/master/formulas.blade.php | 65 +++++++++++++ routes/pages/studio.php | 6 ++ 9 files changed, 362 insertions(+) create mode 100644 app/Livewire/Datatable/Studio/Master/FormulasTable.php create mode 100644 app/Livewire/Forms/Studio/Master/FormulaForm.php create mode 100644 app/Livewire/Studio/Master/Formula.php create mode 100644 app/Models/Formula.php create mode 100644 database/migrations/2025_10_06_124919_create_formulas_table.php create mode 100644 resources/views/livewire/studio/master/formulas.blade.php diff --git a/app/Livewire/Datatable/Studio/Master/FormulasTable.php b/app/Livewire/Datatable/Studio/Master/FormulasTable.php new file mode 100644 index 0000000..d0257e8 --- /dev/null +++ b/app/Livewire/Datatable/Studio/Master/FormulasTable.php @@ -0,0 +1,63 @@ +searchable(), + + Column::make('Ukuran', 'size') + ->format(fn ($row, $column) => $row.' ml') + ->searchable() + ->sortable(), + + Column::make('Volume', 'volume') + ->format(fn ($row, $column) => $row.' ml') + ->searchable() + ->sortable(), + + Column::make('Aksi') + ->label(function ($row) { + $actions = ''; + + if (auth()->user()->can('update formula')) { + $actions .= view('components.datatables.edit-modal', [ + 'id' => $row->hash, + 'method' => 'update', + 'modalTitle' => 'Ubah Rumus', + ])->render(); + } + + if (auth()->user()->can('delete formula')) { + $actions .= view('components.datatables.delete', [ + 'id' => $row->hash, + 'deleteRoute' => route('studio.master.formula.delete', $row->hash), + ])->render(); + } + + return $actions; + }) + ->html(), + ]; + } + + public function builder(): Builder + { + return Formula::select('id', 'quality', 'size', 'volume'); + } +} diff --git a/app/Livewire/Forms/Studio/Master/FormulaForm.php b/app/Livewire/Forms/Studio/Master/FormulaForm.php new file mode 100644 index 0000000..4a270ed --- /dev/null +++ b/app/Livewire/Forms/Studio/Master/FormulaForm.php @@ -0,0 +1,67 @@ + ['required', 'string', 'max:20'], + 'size' => ['required', 'numeric', new UnsignedInteger], + 'volume' => ['required', 'numeric', new UnsignedInteger], + ]; + } + + public function validationAttributes(): array + { + return [ + 'quality' => 'kualitas', + 'size' => 'ukuran', + ]; + } + + public function setFormula(Formula $formula) + { + $this->formula = $formula; + + $this->quality = $formula->quality; + $this->size = $formula->size; + $this->volume = $formula->volume; + } + + public function store() + { + $this->validate(); + + Formula::create($this->prepareSavedData()); + } + + public function update() + { + $this->validate(); + + $this->formula->update($this->prepareSavedData()); + } + + private function prepareSavedData() + { + return [ + 'quality' => $this->quality, + 'size' => $this->size, + 'volume' => $this->volume, + ]; + } +} diff --git a/app/Livewire/Studio/Master/Formula.php b/app/Livewire/Studio/Master/Formula.php new file mode 100644 index 0000000..6fd91e9 --- /dev/null +++ b/app/Livewire/Studio/Master/Formula.php @@ -0,0 +1,95 @@ +sizes = Bottle::distinct()->orderBy('size')->pluck('size')->toArray(); + } + + #[On('modal:open')] + public function openModal(string $method, string $modalTitle, ?string $id = null) + { + $this->resetValidation(); + $this->resetErrorBag(); + + $this->method = $method; + $this->modalTitle = $modalTitle; + + if ($id) { + $this->form->setFormula(FormulaModel::byHashOrFail($id)); + } + } + + public function create() + { + $this->canOrAbort('create formula'); + + $this->form->store(); + + $this->dispatch('refreshDatatable'); + + $this->toast('Rumus berhasil ditambahkan.'); + + Flux::modals()->close(); + } + + public function update() + { + $this->canOrAbort('update formula'); + + $this->form->update(); + + $this->dispatch('refreshDatatable'); + + $this->toast('Rumus berhasil diperbarui.'); + + Flux::modals()->close(); + } + + public function delete(FormulaModel $formula) + { + $formula->delete(); + + $this->dispatch('refreshDatatable'); + + $this->toast('Rumus berhasil dihapus.'); + + Flux::modals()->close(); + } + + public function render() + { + return view('livewire.studio.master.formulas', [ + 'pageTitle' => 'Rumus', + ]); + } +} diff --git a/app/Models/Formula.php b/app/Models/Formula.php new file mode 100644 index 0000000..57cabe6 --- /dev/null +++ b/app/Models/Formula.php @@ -0,0 +1,23 @@ + 'int', + 'volume' => 'int', + ]; + } +} diff --git a/app/Providers/ViewServiceProvider.php b/app/Providers/ViewServiceProvider.php index 17f3e34..0ded3e0 100644 --- a/app/Providers/ViewServiceProvider.php +++ b/app/Providers/ViewServiceProvider.php @@ -40,6 +40,13 @@ public function boot(): void 'match' => 'studio.master.user.*', 'can' => 'view user', ], + [ + 'label' => 'Rumus', + 'icon' => 'variable', + 'route' => 'studio.master.formula.index', + 'match' => 'studio.master.formula.*', + 'can' => 'view formula', + ], ], ], [ diff --git a/database/migrations/2025_10_06_124919_create_formulas_table.php b/database/migrations/2025_10_06_124919_create_formulas_table.php new file mode 100644 index 0000000..d3fd1d5 --- /dev/null +++ b/database/migrations/2025_10_06_124919_create_formulas_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('quality', 20); + $table->unsignedInteger('size'); + $table->unsignedInteger('volume'); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('formulas'); + } +}; diff --git a/database/seeders/RolePermissionSeeder.php b/database/seeders/RolePermissionSeeder.php index 4a09e36..e5b377f 100644 --- a/database/seeders/RolePermissionSeeder.php +++ b/database/seeders/RolePermissionSeeder.php @@ -39,6 +39,11 @@ public function run(): void 'update user', 'delete user', + 'view formula', + 'create formula', + 'update formula', + 'delete formula', + 'view tier', 'create tier', 'update tier', diff --git a/resources/views/livewire/studio/master/formulas.blade.php b/resources/views/livewire/studio/master/formulas.blade.php new file mode 100644 index 0000000..d603dd0 --- /dev/null +++ b/resources/views/livewire/studio/master/formulas.blade.php @@ -0,0 +1,65 @@ + +
+
+ {{ $pageTitle }} +
+ @if (auth()->user()->can('create formula')) +
+ + Tambah + + +
+ @endif +
+ +
+ +
+ + @include('components.confirmation.delete') + +
+ {{ $modalTitle }} + + + Kualitas * + + @foreach ($qualities as $key => $value) + {{ $value }} + + @endforeach + + + + + + Ukuran * + + @foreach ($sizes as $key => $value) + {{ $value }} ml + + @endforeach + + + + + + Volume * + + + + +
+ + + Simpan + +
+
+
+
diff --git a/routes/pages/studio.php b/routes/pages/studio.php index 61e859c..36342e9 100644 --- a/routes/pages/studio.php +++ b/routes/pages/studio.php @@ -24,6 +24,7 @@ use App\Livewire\Studio\Manage\Article\Index as ArticleIndex; use App\Livewire\Studio\Manage\Purchase\Create as PurchaseCreate; use App\Livewire\Studio\Manage\Purchase\Index as PurchaseIndex; +use App\Livewire\Studio\Master\Formula as FormulaComponent; use App\Livewire\Studio\Master\Outlet\Create as OutletCreate; use App\Livewire\Studio\Master\Outlet\Edit as OutletEdit; use App\Livewire\Studio\Master\Outlet\Index as OutletIndex; @@ -60,6 +61,11 @@ Route::get('/{user}/edit', UserEdit::class)->name('edit')->middleware('can:update user'); Route::delete('/{user}/delete', UserCreate::class)->name('delete')->middleware('can:delete user'); }); + + Route::prefix('formulas')->name('formula.')->group(function () { + Route::get('/', FormulaComponent::class)->name('index')->middleware('can:view formula'); + Route::delete('/{formula}/delete', FormulaComponent::class)->name('delete')->middleware('can:delete formula'); + }); }); Route::prefix('loyalty')->name('studio.loyalty.')->group(function () {