fix(voucher): Correctly handle empty nullable fields in voucher form and refactor voucher management with Livewire 3 navigation and delete authorization.

This commit is contained in:
Yoga Pangestu 2025-12-11 21:39:30 +07:00
parent ff775920ef
commit d2f101d49a
5 changed files with 38 additions and 22 deletions

View File

@ -122,7 +122,6 @@ public function columns(): array
if (auth()->user()->can('delete voucher')) { if (auth()->user()->can('delete voucher')) {
$actions .= view('components.actions.table.delete', [ $actions .= view('components.actions.table.delete', [
'id' => $row->hash, 'id' => $row->hash,
'deleteRoute' => route('studio.loyalty.voucher.delete', $row->hash),
])->render(); ])->render();
} }

View File

@ -125,9 +125,9 @@ public function store(): void
$data = $this->prepareSavedData(); $data = $this->prepareSavedData();
foreach (['min_purchase', 'max_discount', 'quota', 'limit_per_user'] as $field) { foreach (['min_purchase', 'max_discount', 'quota', 'limit_per_user'] as $key) {
if ($this->$field === '') { if ($data[$key] === '') {
$this->$field = null; $data[$key] = null;
} }
} }
@ -163,7 +163,7 @@ private function prepareSavedData(): array
'min_purchase' => replaceCurrency($this->min_purchase), 'min_purchase' => replaceCurrency($this->min_purchase),
'max_discount' => $this->type == VoucherType::PERCENTAGE->value ? replaceCurrency($this->max_discount) : null, 'max_discount' => $this->type == VoucherType::PERCENTAGE->value ? replaceCurrency($this->max_discount) : null,
'quota' => $this->quota, 'quota' => $this->quota,
'available_count' => $this->quota ?? 0, 'available_count' => empty($this->quota) ? 0 : $this->quota,
'limit_per_user' => $this->limit_per_user, 'limit_per_user' => $this->limit_per_user,
'summary' => $this->summary, 'summary' => $this->summary,
'start_date' => $this->start_date, 'start_date' => $this->start_date,

View File

@ -10,6 +10,7 @@
use App\Traits\WithOutletSelector; use App\Traits\WithOutletSelector;
use App\Traits\WithToast; use App\Traits\WithToast;
use App\Traits\WithUpdatedData; use App\Traits\WithUpdatedData;
use Illuminate\Contracts\View\View;
use Livewire\Attributes\Title; use Livewire\Attributes\Title;
use Livewire\Component; use Livewire\Component;
@ -22,12 +23,12 @@ class Create extends Component
public array $outlets; public array $outlets;
public function mount() public function mount(): void
{ {
$this->outlets = Outlet::pluck('name', 'id')->toArray(); $this->outlets = Outlet::pluck('name', 'id')->toArray();
} }
public function save() public function save(): void
{ {
$this->canOrAbort('create voucher'); $this->canOrAbort('create voucher');
@ -41,12 +42,12 @@ public function save()
], ],
); );
$this->toast('Voucher berhasil ditambahkan.'); $this->redirectRoute('studio.loyalty.voucher.index', [
'notification' => 'Voucher berhasil ditambahkan.',
$this->redirectRoute('studio.loyalty.voucher.index'); ], navigate: true);
} }
public function render() public function render(): View
{ {
return view('livewire.studio.loyalty.voucher.form', [ return view('livewire.studio.loyalty.voucher.form', [
'pageTitle' => 'Tambah Voucher', 'pageTitle' => 'Tambah Voucher',

View File

@ -9,6 +9,7 @@
use App\Traits\WithOutletSelector; use App\Traits\WithOutletSelector;
use App\Traits\WithToast; use App\Traits\WithToast;
use App\Traits\WithUpdatedData; use App\Traits\WithUpdatedData;
use Illuminate\Contracts\View\View;
use Livewire\Attributes\Title; use Livewire\Attributes\Title;
use Livewire\Component; use Livewire\Component;
@ -21,25 +22,25 @@ class Edit extends Component
public array $outlets; public array $outlets;
public function mount(Voucher $voucher) public function mount(Voucher $voucher): void
{ {
$this->form->setVoucher($voucher); $this->form->setVoucher($voucher);
$this->outlets = Outlet::pluck('name', 'id')->toArray(); $this->outlets = Outlet::pluck('name', 'id')->toArray();
} }
public function save() public function save(): void
{ {
$this->canOrAbort('update voucher'); $this->canOrAbort('update voucher');
$this->form->update(); $this->form->update();
$this->toast('Voucher berhasil diperbarui.'); $this->redirectRoute('studio.loyalty.voucher.index', [
'notification' => 'Voucher berhasil diperbarui.',
$this->redirectRoute('studio.loyalty.voucher.index'); ], navigate: true);
} }
public function render() public function render(): View
{ {
return view('livewire.studio.loyalty.voucher.form', [ return view('livewire.studio.loyalty.voucher.form', [
'pageTitle' => 'Ubah Voucher', 'pageTitle' => 'Ubah Voucher',

View File

@ -4,21 +4,35 @@
use App\Models\Voucher; use App\Models\Voucher;
use App\Traits\Notification\WithSubscribeNotification; use App\Traits\Notification\WithSubscribeNotification;
use App\Traits\WithAuthorization;
use App\Traits\WithConfirmation; use App\Traits\WithConfirmation;
use App\Traits\WithToast; use App\Traits\WithToast;
use Flux\Flux; use Flux\Flux;
use Illuminate\Contracts\View\View;
use Livewire\Attributes\Title; use Livewire\Attributes\Title;
use Livewire\Component; use Livewire\Component;
#[Title('Voucher')] #[Title('Voucher')]
class Index extends Component class Index extends Component
{ {
use WithConfirmation, WithSubscribeNotification, WithToast; use WithAuthorization, WithConfirmation, WithSubscribeNotification, WithToast;
public array $stats = []; public array $stats = [];
public function mount() public function mount(): void
{ {
$hasNotification = request()->get('notification');
if ($hasNotification) {
$this->js(<<<'JS'
const url = new URL(window.location);
url.search = '';
window.history.replaceState({}, '', url);
JS);
$this->toast($hasNotification);
}
$this->stats = [ $this->stats = [
[ [
'title' => 'Total Voucher', 'title' => 'Total Voucher',
@ -39,18 +53,19 @@ public function mount()
]; ];
} }
public function delete(Voucher $voucher) public function delete(Voucher $voucher): void
{ {
$this->canOrAbbort('delete voucher');
$voucher->delete(); $voucher->delete();
$this->dispatch('refreshDatatable'); $this->dispatch('refreshDatatable');
$this->toast('Voucher berhasil dihapus.'); $this->toast('Voucher berhasil dihapus.');
Flux::modals()->close(); Flux::modals()->close();
} }
public function render() public function render(): View
{ {
return view('livewire.studio.loyalty.voucher.index', [ return view('livewire.studio.loyalty.voucher.index', [
'pageTitle' => 'Voucher', 'pageTitle' => 'Voucher',