diff --git a/app/Livewire/Datatable/MembershipsTable.php b/app/Livewire/Datatable/MembershipsTable.php new file mode 100644 index 0000000..b1d7b26 --- /dev/null +++ b/app/Livewire/Datatable/MembershipsTable.php @@ -0,0 +1,59 @@ +searchable(), + + Column::make('Min. Pembelian', 'min_purchase') + ->format(fn ($value) => currency($value, 'Rp')) + ->searchable() + ->sortable(), + + Column::make('Diskon', 'discount_percentage') + ->format(fn ($value) => percentage($value)) + ->searchable() + ->sortable(), + + Column::make('Aksi') + ->label(function ($row) { + $actions = ''; + + $actions .= view('components.datatables.edit-modal', [ + 'id' => $row->id, + 'method' => 'update', + 'modalTitle' => 'Ubah Membership', + ])->render(); + + $actions .= view('components.datatables.delete', [ + 'id' => $row->id, + 'deleteRoute' => route('studio.loyalty.membership.delete', $row->id), + ])->render(); + + return $actions; + }) + ->html(), + ]; + } + + public function builder(): Builder + { + return Membership::select('id', 'name', 'discount_percentage', 'min_purchase'); + } +} diff --git a/app/Livewire/Forms/MembershipForm.php b/app/Livewire/Forms/MembershipForm.php new file mode 100644 index 0000000..7957642 --- /dev/null +++ b/app/Livewire/Forms/MembershipForm.php @@ -0,0 +1,73 @@ + ['required', 'string', 'max:50'], + 'min_purchase' => ['required', 'regex:/^[0-9.]+$/', 'max:99999999999'], + 'discount_percentage' => ['required', 'numeric', 'between:0,100'], + 'terms_conditions' => ['nullable', 'string'], + ]; + } + + public function validationAttributes(): array + { + return [ + 'name' => 'nama', + 'min_purchase' => 'min. pembelian', + 'discount_percentage' => 'persentase diskon', + 'terms_conditions' => 'syarat dan ketentuan', + ]; + } + + public function setMembership(Membership $membership) + { + $this->membership = $membership; + + $this->name = $membership->name; + $this->min_purchase = currency($membership->min_purchase); + $this->terms_conditions = $membership->terms_conditions; + $this->discount_percentage = $membership->discount_percentage; + } + + public function store() + { + $this->validate(); + + Membership::create([ + 'name' => $this->name, + 'min_purchase' => replaceCurrency($this->min_purchase), + 'discount_percentage' => $this->discount_percentage, + 'terms_conditions' => $this->terms_conditions, + ]); + } + + public function update() + { + $this->validate(); + + $this->membership->update([ + 'name' => $this->name, + 'min_purchase' => replaceCurrency($this->min_purchase), + 'discount_percentage' => $this->discount_percentage, + 'terms_conditions' => $this->terms_conditions, + ]); + } +} diff --git a/app/Livewire/Studio/Loyalty/Membership.php b/app/Livewire/Studio/Loyalty/Membership.php new file mode 100644 index 0000000..4f9b55b --- /dev/null +++ b/app/Livewire/Studio/Loyalty/Membership.php @@ -0,0 +1,93 @@ +resetValidation(); + $this->resetErrorBag(); + + $this->method = $method; + $this->modalTitle = $modalTitle; + + if ($id) { + $this->form->setMembership(MembershipModel::findOrFail($id)); + } + } + + public function create() + { + $this->form->store(); + + $this->dispatch('refreshDatatable'); + + Flux::toast( + heading: 'Berhasil', + text: 'Membership berhasil ditambahkan.', + variant: 'success', + duration: 3000 + ); + + Flux::modals()->close(); + } + + public function update() + { + $this->form->update(); + + $this->dispatch('refreshDatatable'); + + Flux::toast( + heading: 'Berhasil', + text: 'Membership berhasil diperbarui.', + variant: 'success', + duration: 3000 + ); + + Flux::modals()->close(); + } + + public function delete(MembershipModel $membership) + { + $membership->delete(); + + $this->dispatch('refreshDatatable'); + + Flux::toast( + heading: 'Berhasil', + text: 'Membership berhasil dihapus.', + variant: 'success', + ); + + Flux::modals()->close(); + } + + public function render() + { + return view('livewire.studio.loyalty.memberships', [ + 'pageTitle' => 'Membership', + ]); + } +} diff --git a/app/Models/Membership.php b/app/Models/Membership.php new file mode 100644 index 0000000..f41246b --- /dev/null +++ b/app/Models/Membership.php @@ -0,0 +1,22 @@ + 'int', + 'discount_percent' => 'decimal:2', + ]; + } +} diff --git a/database/migrations/2025_09_24_141358_create_memberships_table.php b/database/migrations/2025_09_24_141358_create_memberships_table.php new file mode 100644 index 0000000..a0dbd40 --- /dev/null +++ b/database/migrations/2025_09_24_141358_create_memberships_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('name', 50); + $table->text('terms_conditions')->nullable(); + $table->unsignedInteger('min_purchase'); + $table->decimal('discount_percentage', 5, 2); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('memberships'); + } +}; diff --git a/resources/views/components/datatables/edit-modal.blade.php b/resources/views/components/datatables/edit-modal.blade.php new file mode 100644 index 0000000..35ede06 --- /dev/null +++ b/resources/views/components/datatables/edit-modal.blade.php @@ -0,0 +1,7 @@ + + + + + + diff --git a/resources/views/components/partials/studio/_sidebar.blade.php b/resources/views/components/partials/studio/_sidebar.blade.php index e4c6394..c8b89be 100644 --- a/resources/views/components/partials/studio/_sidebar.blade.php +++ b/resources/views/components/partials/studio/_sidebar.blade.php @@ -24,11 +24,14 @@ class="px-2 hidden dark:flex" /> - Inbox - +
+
Loyalty +
+
+ Membership + +
+
diff --git a/resources/views/livewire/studio/loyalty/memberships.blade.php b/resources/views/livewire/studio/loyalty/memberships.blade.php new file mode 100644 index 0000000..7c79709 --- /dev/null +++ b/resources/views/livewire/studio/loyalty/memberships.blade.php @@ -0,0 +1,64 @@ + +
+
+ {{ $pageTitle }} +
+
+ + Tambah + + +
+
+ +
+ +
+ + @include('components.confirmation.delete') + +
+ {{ $modalTitle }} + + + + + Min. Belanja + + Rp + + + + + + + + + Persentase Diskon + + + + % + + + + + + + +
+ + + Simpan + +
+
+
+ +
diff --git a/routes/web.php b/routes/web.php index 8847a45..0dd863f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,6 +3,7 @@ use App\Livewire\Auth\Login; use App\Livewire\Auth\Logout; use App\Livewire\Studio\Dashboard\Overview; +use App\Livewire\Studio\Loyalty\Membership as MembershipComponent; 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; @@ -48,4 +49,11 @@ Route::get('users/{user}/edit', UserEdit::class)->name('edit'); Route::get('users/{user}/delete', UserCreate::class)->name('delete'); }); + + Route::prefix('loyalty') + ->as('studio.loyalty.membership.') + ->group(function () { + Route::get('memberships', MembershipComponent::class)->name('index'); + Route::delete('memberships/{membership}/delete', MembershipComponent::class)->name('delete'); + }); });