refactor(formula): mengubah cara menampilkan data dari mengunakan datatable menjadi menggunakan foreach

This commit is contained in:
Yoga Pangestu 2025-10-14 14:12:49 +07:00
parent 730122e7cc
commit db3d9edb18
4 changed files with 92 additions and 76 deletions

View File

@ -1,63 +0,0 @@
<?php
namespace App\Livewire\Datatable\Studio\Master;
use App\Models\Formula;
use App\Traits\Datatable\WithAppendColumn;
use App\Traits\Datatable\WithConfiguration;
use App\Traits\Datatable\WithPrependColumn;
use Illuminate\Database\Eloquent\Builder;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;
class FormulasTable extends DataTableComponent
{
use WithAppendColumn, WithConfiguration, WithPrependColumn;
protected $model = Formula::class;
public function columns(): array
{
return [
Column::make('Kualitas', 'quality')->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');
}
}

View File

@ -20,8 +20,8 @@ public function rules(): array
{
return [
'quality' => ['required', 'string', 'max:20'],
'size' => ['required', 'numeric', new UnsignedInteger],
'volume' => ['required', 'numeric', new UnsignedInteger],
'size' => ['required', new UnsignedInteger],
'volume' => ['required', new UnsignedInteger],
];
}
@ -39,14 +39,14 @@ public function setFormula(Formula $formula)
$this->quality = $formula->quality;
$this->size = $formula->size;
$this->volume = $formula->volume;
$this->volume = replaceCurrency($formula->volume);
}
public function store()
{
$this->validate();
Formula::create($this->prepareSavedData());
return Formula::create($this->prepareSavedData());
}
public function update()
@ -54,6 +54,8 @@ public function update()
$this->validate();
$this->formula->update($this->prepareSavedData());
return $this->formula;
}
private function prepareSavedData()
@ -61,7 +63,7 @@ private function prepareSavedData()
return [
'quality' => $this->quality,
'size' => $this->size,
'volume' => $this->volume,
'volume' => replaceCurrency($this->volume),
];
}
}

View File

@ -22,6 +22,8 @@ class Formula extends Component
public FormulaForm $form;
public array $formulas = [];
public string $method = 'create';
public string $modalTitle = '';
@ -32,6 +34,16 @@ class Formula extends Component
public function mount()
{
$this->formulas = FormulaModel::orderBy('size')->get()
->groupBy('size')
->map(function ($items) {
return $items->map(fn ($item) => [
'hash' => $item->hash,
'quality' => $item->quality,
'volume' => $item->volume,
]);
})->toArray();
$this->sizes = Bottle::distinct()->orderBy('size')->pluck('size')->toArray();
}
@ -53,9 +65,16 @@ public function create()
{
$this->canOrAbort('create formula');
$this->form->store();
$formula = $this->form->store();
$this->dispatch('refreshDatatable');
// push new formula to array
$size = $formula->size;
$this->formulas[$size] ??= [];
$this->formulas[$size][] = [
'hash' => $formula->hash,
'quality' => $formula->quality,
'volume' => $formula->volume,
];
$this->toast('Rumus berhasil ditambahkan.');
@ -66,9 +85,21 @@ public function update()
{
$this->canOrAbort('update formula');
$this->form->update();
$formula = $this->form->update();
$this->dispatch('refreshDatatable');
// update array formulas
foreach ($this->formulas as $key => &$items) {
$index = array_search($formula->hash, array_column($items, 'hash'));
if ($index !== false) {
$this->formulas[$key][$index] = [
'hash' => $formula->hash,
'quality' => $formula->quality,
'volume' => $formula->volume,
];
break;
}
}
unset($items);
$this->toast('Rumus berhasil diperbarui.');
@ -79,7 +110,18 @@ public function delete(FormulaModel $formula)
{
$formula->delete();
$this->dispatch('refreshDatatable');
// update array formulas
$size = $formula->size;
if (isset($this->formulas[$size])) {
$this->formulas[$size] = array_values(array_filter(
$this->formulas[$size],
fn ($item) => $item['hash'] !== $formula->hash
));
if (empty($this->formulas[$size])) {
unset($this->formulas[$size]);
}
}
$this->toast('Rumus berhasil dihapus.');

View File

@ -15,7 +15,39 @@
</div>
<div class="mt-6">
<livewire:datatable.studio.master.formulas-table />
<div class="mt-6 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-6 gap-4">
@foreach ($formulas as $key => $formula)
<flux:card class="space-y-2">
<flux:heading size="xl">Ukuran {{ $key }} ml</flux:heading>
@foreach ($formula as $item)
<flux:callout variant="secondary" inline>
<div class="flex items-center space-x-1">
<flux:callout.heading>{{ $item['quality'] }}</flux:callout.heading>
<flux:text class="text-xs text-gray-400">({{ $item['volume'] }} ml)</flux:text>
</div>
<x-slot name="actions">
<flux:modal.trigger name="form-modal">
<flux:tooltip content="Ubah">
<flux:button variant="primary" color="yellow" icon="pencil-square"
size="sm"
wire:click="$dispatch('modal:open', {method: 'update', 'modalTitle': 'Ubah Rumus', 'id': '{{ $item['hash'] }}'})">
</flux:button>
</flux:tooltip>
</flux:modal.trigger>
<flux:modal.trigger name="delete">
<flux:tooltip content="Hapus">
<flux:button variant="danger" icon="trash" size="sm"
wire:click="$dispatch('fn:confirmDelete', {id: '{{ $item['hash'] }}'})">
</flux:button>
</flux:tooltip>
</flux:modal.trigger>
</x-slot>
</flux:callout>
@endforeach
</flux:card>
@endforeach
</div>
</div>
@include('components.confirmation.delete')
@ -49,8 +81,11 @@
<flux:field>
<flux:label>Volume <span class="text-red-500 ms-1">*</span></flux:label>
<flux:input placeholder="Masukkan volume" wire:model.live.debounce.500ms="form.volume"
autocomplete="off" />
<flux:input.group>
<flux:input placeholder="Masukkan volume" x-mask:dynamic="$money($input, ',')"
wire:model.live.debounce.500ms="form.volume" autocomplete="off" />
<flux:input.group.suffix>ml</flux:input.group.suffix>
</flux:input.group>
<flux:error name="form.volume" />
</flux:field>