feat(formula): membuat crud formula
This commit is contained in:
parent
7ac13a5f13
commit
7594e7abac
63
app/Livewire/Datatable/Studio/Master/FormulasTable.php
Normal file
63
app/Livewire/Datatable/Studio/Master/FormulasTable.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
67
app/Livewire/Forms/Studio/Master/FormulaForm.php
Normal file
67
app/Livewire/Forms/Studio/Master/FormulaForm.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Forms\Studio\Master;
|
||||
|
||||
use App\Models\Formula;
|
||||
use App\Rules\UnsignedInteger;
|
||||
use Livewire\Form;
|
||||
|
||||
class FormulaForm extends Form
|
||||
{
|
||||
public ?Formula $formula = null;
|
||||
|
||||
public string $quality = '';
|
||||
|
||||
public string $size = '';
|
||||
|
||||
public string $volume = '';
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'quality' => ['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,
|
||||
];
|
||||
}
|
||||
}
|
||||
95
app/Livewire/Studio/Master/Formula.php
Normal file
95
app/Livewire/Studio/Master/Formula.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Studio\Master;
|
||||
|
||||
use App\Livewire\Forms\Studio\Master\FormulaForm;
|
||||
use App\Models\Bottle;
|
||||
use App\Models\Formula as FormulaModel;
|
||||
use App\Traits\WithAuthorization;
|
||||
use App\Traits\WithCloseModal;
|
||||
use App\Traits\WithConfirmation;
|
||||
use App\Traits\WithToast;
|
||||
use App\Traits\WithUpdatedData;
|
||||
use Flux\Flux;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Attributes\Title;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Title('Rumus')]
|
||||
class Formula extends Component
|
||||
{
|
||||
use WithAuthorization, WithCloseModal, WithConfirmation, WithToast, WithUpdatedData;
|
||||
|
||||
public FormulaForm $form;
|
||||
|
||||
public string $method = 'create';
|
||||
|
||||
public string $modalTitle = '';
|
||||
|
||||
public array $qualities = ['Premium', 'Super Premium', 'Murni'];
|
||||
|
||||
public array $sizes = [];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->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',
|
||||
]);
|
||||
}
|
||||
}
|
||||
23
app/Models/Formula.php
Normal file
23
app/Models/Formula.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Veelasky\LaravelHashId\Eloquent\HashableId;
|
||||
|
||||
class Formula extends Model
|
||||
{
|
||||
use HasFactory, HashableId, SoftDeletes;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'size' => 'int',
|
||||
'volume' => 'int',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -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',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
<?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('formulas', function (Blueprint $table) {
|
||||
$table->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');
|
||||
}
|
||||
};
|
||||
@ -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',
|
||||
|
||||
65
resources/views/livewire/studio/master/formulas.blade.php
Normal file
65
resources/views/livewire/studio/master/formulas.blade.php
Normal file
@ -0,0 +1,65 @@
|
||||
<flux:main>
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
||||
</div>
|
||||
@if (auth()->user()->can('create formula'))
|
||||
<div>
|
||||
<flux:modal.trigger name="form-modal">
|
||||
<flux:button variant="primary" class="text-sm"
|
||||
wire:click="$dispatch('modal:open', {method: 'create', 'modalTitle': 'Tambah Rumus'})">Tambah
|
||||
</flux:button>
|
||||
</flux:modal.trigger>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<livewire:datatable.studio.master.formulas-table />
|
||||
</div>
|
||||
|
||||
@include('components.confirmation.delete')
|
||||
<flux:modal name="form-modal" class="w-[95%] max-w-sm md:max-w-xl mx-auto" @close="closeModal('form-modal')">
|
||||
<div class="p-4 space-y-6">
|
||||
<flux:heading size="lg">{{ $modalTitle }}</flux:heading>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>Kualitas <span class="text-red-500 ms-1">*</span></flux:label>
|
||||
<flux:select variant="listbox" searchable placeholder="Pilih Kualitas"
|
||||
wire:model.live.debounce.500ms="form.quality">
|
||||
@foreach ($qualities as $key => $value)
|
||||
<flux:select.option value="{{ $value }}">{{ $value }}
|
||||
</flux:select.option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
<flux:error name="form.quality" />
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>Ukuran <span class="text-red-500 ms-1">*</span></flux:label>
|
||||
<flux:select variant="listbox" searchable placeholder="Pilih Ukuran"
|
||||
wire:model.live.debounce.500ms="form.size">
|
||||
@foreach ($sizes as $key => $value)
|
||||
<flux:select.option value="{{ $value }}">{{ $value }} ml
|
||||
</flux:select.option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
<flux:error name="form.size" />
|
||||
</flux:field>
|
||||
|
||||
<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:error name="form.volume" />
|
||||
</flux:field>
|
||||
|
||||
<div class="flex">
|
||||
<flux:spacer />
|
||||
<flux:button variant="primary" class="sm:w-auto cursor-pointer" wire:click="{{ $method }}">
|
||||
Simpan
|
||||
</flux:button>
|
||||
</div>
|
||||
</div>
|
||||
</flux:modal>
|
||||
</flux:main>
|
||||
@ -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 () {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user