refactor(tier): merubah cara menampilkan data nya menjadi di foreach bukan tabel lagi dan menyesuaikan validasinya
This commit is contained in:
parent
2a5c3c344f
commit
0b9e118ce0
@ -1,57 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire\Datatable\Studio\Loyalty;
|
|
||||||
|
|
||||||
use App\Models\Tier;
|
|
||||||
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 TiersTable extends DataTableComponent
|
|
||||||
{
|
|
||||||
use WithAppendColumn, WithConfiguration, WithPrependColumn;
|
|
||||||
|
|
||||||
protected $model = Tier::class;
|
|
||||||
|
|
||||||
public function columns(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
Column::make('Nama', 'name')->searchable(),
|
|
||||||
|
|
||||||
Column::make('Min. Poin', 'min_points')->searchable()->sortable(),
|
|
||||||
|
|
||||||
Column::make('Maks. Poin', 'max_points')->searchable()->sortable(),
|
|
||||||
|
|
||||||
Column::make('Aksi')
|
|
||||||
->label(function ($row) {
|
|
||||||
$actions = '';
|
|
||||||
|
|
||||||
if (auth()->user()->can('update tier')) {
|
|
||||||
$actions .= view('components.datatables.edit-modal', [
|
|
||||||
'id' => $row->hash,
|
|
||||||
'method' => 'update',
|
|
||||||
'modalTitle' => 'Ubah Tier',
|
|
||||||
])->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth()->user()->can('delete tier')) {
|
|
||||||
$actions .= view('components.datatables.delete', [
|
|
||||||
'id' => $row->hash,
|
|
||||||
'deleteRoute' => route('studio.loyalty.tier.delete', $row->hash),
|
|
||||||
])->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $actions;
|
|
||||||
})
|
|
||||||
->html(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function builder(): Builder
|
|
||||||
{
|
|
||||||
return Tier::select('id', 'name', 'min_points', 'max_points');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Livewire\Forms\Studio\Loyalty;
|
namespace App\Livewire\Forms\Studio\Loyalty;
|
||||||
|
|
||||||
use App\Models\Tier;
|
use App\Models\Tier;
|
||||||
|
use App\Rules\UnsignedInteger;
|
||||||
use Livewire\Form;
|
use Livewire\Form;
|
||||||
|
|
||||||
class TierForm extends Form
|
class TierForm extends Form
|
||||||
@ -19,8 +20,8 @@ public function rules(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => ['required', 'string', 'max:50'],
|
'name' => ['required', 'string', 'max:50'],
|
||||||
'min_points' => ['required', 'numeric'],
|
'min_points' => ['required', new UnsignedInteger],
|
||||||
'max_points' => ['nullable', 'numeric'],
|
'max_points' => ['nullable', new UnsignedInteger],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,13 +47,24 @@ public function store()
|
|||||||
{
|
{
|
||||||
$this->validate();
|
$this->validate();
|
||||||
|
|
||||||
Tier::create($this->pull());
|
return Tier::create($this->prepareSavedData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update()
|
public function update()
|
||||||
{
|
{
|
||||||
$this->validate();
|
$this->validate();
|
||||||
|
|
||||||
$this->tier->update($this->pull());
|
$this->tier->update($this->prepareSavedData());
|
||||||
|
|
||||||
|
return $this->tier;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function prepareSavedData()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => $this->name,
|
||||||
|
'min_points' => replaceCurrency($this->min_points),
|
||||||
|
'max_points' => replaceCurrency($this->max_points),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,12 +19,27 @@ class Tier extends Component
|
|||||||
{
|
{
|
||||||
use WithAuthorization, WithCloseModal, WithConfirmation, WithToast, WithUpdatedData;
|
use WithAuthorization, WithCloseModal, WithConfirmation, WithToast, WithUpdatedData;
|
||||||
|
|
||||||
|
public array $tiers = [];
|
||||||
|
|
||||||
public TierForm $form;
|
public TierForm $form;
|
||||||
|
|
||||||
public string $method = 'create';
|
public string $method = 'create';
|
||||||
|
|
||||||
public string $modalTitle = '';
|
public string $modalTitle = '';
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->tiers = TierModel::orderBy('min_points', 'asc')
|
||||||
|
->get()
|
||||||
|
->map(fn($tier) => [
|
||||||
|
'hash' => $tier->hash,
|
||||||
|
'name' => $tier->name,
|
||||||
|
'min_points' => currency($tier->min_points, ''),
|
||||||
|
'max_points' => currency($tier->max_points, ''),
|
||||||
|
])
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
#[On('modal:open')]
|
#[On('modal:open')]
|
||||||
public function openModal(string $method, string $modalTitle, ?string $id = null)
|
public function openModal(string $method, string $modalTitle, ?string $id = null)
|
||||||
{
|
{
|
||||||
@ -43,9 +58,19 @@ public function create()
|
|||||||
{
|
{
|
||||||
$this->canOrAbort('create tier');
|
$this->canOrAbort('create tier');
|
||||||
|
|
||||||
$this->form->store();
|
$tier = $this->form->store();
|
||||||
|
|
||||||
$this->dispatch('refreshDatatable');
|
$tiers = $this->tiers;
|
||||||
|
$tiers[] = [
|
||||||
|
'hash' => $tier->hash,
|
||||||
|
'name' => $tier->name,
|
||||||
|
'min_points' => currency($tier->min_points, ''),
|
||||||
|
'max_points' => currency($tier->max_points, ''),
|
||||||
|
];
|
||||||
|
|
||||||
|
usort($tiers, fn($a, $b) => replaceCurrency($a['min_points']) <=> replaceCurrency($b['min_points']));
|
||||||
|
|
||||||
|
$this->tiers = $tiers;
|
||||||
|
|
||||||
$this->toast('Tier berhasil ditambahkan.');
|
$this->toast('Tier berhasil ditambahkan.');
|
||||||
|
|
||||||
@ -56,9 +81,22 @@ public function update()
|
|||||||
{
|
{
|
||||||
$this->canOrAbort('update tier');
|
$this->canOrAbort('update tier');
|
||||||
|
|
||||||
$this->form->update();
|
$tier = $this->form->update();
|
||||||
|
|
||||||
$this->dispatch('refreshDatatable');
|
// update array tiers
|
||||||
|
$tiers = $this->tiers;
|
||||||
|
foreach ($tiers as $index => $item) {
|
||||||
|
if ($item['hash'] === $tier->hash) {
|
||||||
|
$tiers[$index] = [
|
||||||
|
'hash' => $tier->hash,
|
||||||
|
'name' => $tier->name,
|
||||||
|
'min_points' => currency($tier->min_points, ''),
|
||||||
|
'max_points' => currency($tier->max_points, ''),
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->tiers = $tiers;
|
||||||
|
|
||||||
$this->toast('Tier berhasil diperbarui.');
|
$this->toast('Tier berhasil diperbarui.');
|
||||||
|
|
||||||
@ -69,7 +107,9 @@ public function delete(TierModel $tier)
|
|||||||
{
|
{
|
||||||
$tier->delete();
|
$tier->delete();
|
||||||
|
|
||||||
$this->dispatch('refreshDatatable');
|
// update array tiers
|
||||||
|
$tiers = array_values(array_filter($this->tiers, fn($item) => $item['hash'] !== $tier->hash));
|
||||||
|
$this->tiers = $tiers;
|
||||||
|
|
||||||
$this->toast('Tier berhasil dihapus.');
|
$this->toast('Tier berhasil dihapus.');
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
@if (auth()->user()->can('create tier'))
|
@can('create tier')
|
||||||
<div>
|
<div>
|
||||||
<flux:modal.trigger name="form-modal">
|
<flux:modal.trigger name="form-modal">
|
||||||
<flux:button variant="primary" class="text-sm"
|
<flux:button variant="primary" class="text-sm"
|
||||||
@ -11,11 +11,58 @@
|
|||||||
</flux:button>
|
</flux:button>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endcan
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<livewire:datatable.studio.loyalty.tiers-table />
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
||||||
|
@foreach ($tiers as $tier)
|
||||||
|
<flux:card
|
||||||
|
class="hover:shadow-lg transition-shadow duration-200 bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div class="flex items-start justify-between">
|
||||||
|
<flux:heading size="lg">{{ $tier['name'] }}
|
||||||
|
</flux:heading>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-1">
|
||||||
|
<div class="flex justify-between text-sm">
|
||||||
|
<span class="text-gray-500 dark:text-gray-400">Min. Poin:</span>
|
||||||
|
<span class="font-medium">{{ $tier['min_points'] }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between text-sm">
|
||||||
|
<span class="text-gray-500 dark:text-gray-400">Maks. Poin:</span>
|
||||||
|
<span class="font-medium">{{ $tier['max_points'] }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex gap-2 pt-2 border-t border-gray-200 dark:border-gray-700">
|
||||||
|
@can('update tier')
|
||||||
|
<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 Tier', 'id': '{{ $tier['hash'] }}'})">
|
||||||
|
Ubah
|
||||||
|
</flux:button>
|
||||||
|
</flux:tooltip>
|
||||||
|
</flux:modal.trigger>
|
||||||
|
@endcan
|
||||||
|
|
||||||
|
@can('delete tier')
|
||||||
|
<flux:modal.trigger name="delete">
|
||||||
|
<flux:tooltip content="Hapus">
|
||||||
|
<flux:button variant="danger" icon="trash" size="sm"
|
||||||
|
wire:click="$dispatch('fn:confirmDelete', {id: '{{ $tier['hash'] }}'})">
|
||||||
|
Hapus
|
||||||
|
</flux:button>
|
||||||
|
</flux:tooltip>
|
||||||
|
</flux:modal.trigger>
|
||||||
|
@endcan
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</flux:card>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@include('components.confirmation.delete')
|
@include('components.confirmation.delete')
|
||||||
@ -33,14 +80,14 @@
|
|||||||
<flux:field>
|
<flux:field>
|
||||||
<flux:label>Min. Poin <span class="text-red-500 ms-1">*</span></flux:label>
|
<flux:label>Min. Poin <span class="text-red-500 ms-1">*</span></flux:label>
|
||||||
<flux:input placeholder="Masukkan minimal poin" wire:model.live.debounce.500ms="form.min_points"
|
<flux:input placeholder="Masukkan minimal poin" wire:model.live.debounce.500ms="form.min_points"
|
||||||
autocomplete="off" />
|
autocomplete="off" x-mask:dynamic="$money($input, ',')" />
|
||||||
<flux:error name="form.min_points" />
|
<flux:error name="form.min_points" />
|
||||||
</flux:field>
|
</flux:field>
|
||||||
|
|
||||||
<flux:field>
|
<flux:field>
|
||||||
<flux:label>Maks. Poin </flux:label>
|
<flux:label>Maks. Poin </flux:label>
|
||||||
<flux:input placeholder="Masukkan maksimal poin" wire:model.live.debounce.500ms="form.max_points"
|
<flux:input placeholder="Masukkan maksimal poin" wire:model.live.debounce.500ms="form.max_points"
|
||||||
autocomplete="off" />
|
autocomplete="off" x-mask:dynamic="$money($input, ',')" />
|
||||||
<flux:error name="form.max_points" />
|
<flux:error name="form.max_points" />
|
||||||
</flux:field>
|
</flux:field>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user