refactor(voucher): menyesuaikanroute dan penempatan file di dalam folder, serta membuat fungsi untuk voucher

This commit is contained in:
Yoga Pangestu 2025-12-05 19:07:26 +07:00
parent 6f06677d72
commit f874c36486
5 changed files with 104 additions and 108 deletions

View File

@ -0,0 +1,79 @@
<?php
namespace App\Livewire\Home;
use App\Models\Outlet;
use App\Models\Voucher as VoucherModel;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Livewire\WithPagination;
#[Layout('components.layouts.home', [
'title' => 'Voucher',
])]
class Voucher extends Component
{
use WithPagination;
public $outlets;
public string $search = '';
public ?string $outlet_id = null;
public ?string $sort = null;
public function mount()
{
$this->outlets = Outlet::query()->operational()->pluck('name', 'id');
}
public function updatedSearch()
{
$this->resetPage();
}
public function updatedOutletId()
{
$this->resetPage();
}
public function updatedSort()
{
$this->resetPage();
}
public function render()
{
$vouchers = VoucherModel::where(function ($query) {
$query->where('name', 'like', '%'.$this->search.'%')
->orWhere('code', 'like', '%'.$this->search.'%');
})
->when($this->outlet_id, function ($query) {
$query->whereHas('outlets', function ($q) {
$q->where('outlets.id', $this->outlet_id);
});
})
->when($this->sort, function ($query) {
match ($this->sort) {
'latest' => $query->orderBy('created_at', 'desc'),
'biggest' => $query->orderBy('discount_amount', 'desc'),
'ending-soon' => $query->orderByRaw('end_date IS NULL')
->orderBy('end_date', 'asc'),
};
})
->active()
->latest()
->paginate(3)
->through(function (VoucherModel $voucher) {
$voucher->min_purchase_formatted = currency($voucher->min_purchase, 'Rp');
$voucher->end_date = formatDate($voucher->end_date);
return $voucher;
});
return view('livewire.home.vouchers', [
'vouchers' => $vouchers,
]);
}
}

View File

@ -1,17 +0,0 @@
<?php
namespace App\Livewire\Home\Voucher;
use Livewire\Attributes\Layout;
use Livewire\Component;
#[Layout('components.layouts.home', [
'title' => 'Voucher',
])]
class Index extends Component
{
public function render()
{
return view('livewire.home.voucher.index');
}
}

View File

@ -300,8 +300,8 @@ public function boot(): void
[ [
'title' => 'Voucher', 'title' => 'Voucher',
'type' => 'link', 'type' => 'link',
'route' => 'voucher.index', 'route' => 'voucher',
'match' => 'voucher.*', 'match' => 'voucher',
], ],
[ [
'title' => 'Artikel', 'title' => 'Artikel',

View File

@ -13,21 +13,21 @@
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path> d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg> </svg>
<input type="text" placeholder="Cari kode voucher..." aria-label="Cari kode voucher" <input type="text" placeholder="Cari voucher..." aria-label="Cari voucher"
wire:model.live.debounce.500ms="search"
class="w-full py-3 pl-11 pr-4 rounded-lg border border-home-foreground/10 text-home-foreground placeholder-home-foreground/50 focus:outline-none focus:ring-2 focus:ring-home-foreground focus:border-transparent transition"> class="w-full py-3 pl-11 pr-4 rounded-lg border border-home-foreground/10 text-home-foreground placeholder-home-foreground/50 focus:outline-none focus:ring-2 focus:ring-home-foreground focus:border-transparent transition">
</div> </div>
</div> </div>
<select aria-label="Filter Outlet" <select wire:model.live="outlet_id" aria-label="Filter Outlet"
class="px-4 py-3 rounded-lg border border-home-foreground/10 bg-white text-home-foreground font-medium focus:outline-none focus:ring-2 focus:ring-home-foreground focus:border-transparent transition cursor-pointer min-w-fit"> class="px-4 py-3 rounded-lg border border-home-foreground/10 bg-white text-home-foreground font-medium focus:outline-none focus:ring-2 focus:ring-home-foreground focus:border-transparent transition cursor-pointer min-w-fit">
<option value="">Filter Outlet</option> <option value="">Filter Outlet</option>
<option value="jakarta">Jakarta</option> @foreach ($outlets as $key => $value)
<option value="bandung">Bandung</option> <option value="{{ $key }}">{{ $value }}</option>
<option value="surabaya">Surabaya</option> @endforeach
<option value="medan">Medan</option>
</select> </select>
<select aria-label="Urutkan Voucher" <select wire:model.live="sort" aria-label="Urutkan Voucher"
class="px-4 py-3 rounded-lg border border-home-foreground/10 bg-white text-home-foreground font-medium focus:outline-none focus:ring-2 focus:ring-home-foreground focus:border-transparent transition cursor-pointer min-w-fit"> class="px-4 py-3 rounded-lg border border-home-foreground/10 bg-white text-home-foreground font-medium focus:outline-none focus:ring-2 focus:ring-home-foreground focus:border-transparent transition cursor-pointer min-w-fit">
<option value="">Urutkan</option> <option value="">Urutkan</option>
<option value="latest">Terbaru</option> <option value="latest">Terbaru</option>
@ -37,72 +37,6 @@ class="px-4 py-3 rounded-lg border border-home-foreground/10 bg-white text-home-
</section> </section>
<section class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <section class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@php
$vouchers = [
[
'tag' => 'DISKON 30%',
'title' => 'Diskon Member Premium',
'desc' => 'Hemat hingga Rp150.000 untuk pembelian',
'code' => 'PREMIUM30',
'min' => 'Rp500.000',
'valid' => '15 Des 2024',
'date_iso' => '2024-12-15',
'quota' => '245/500',
],
[
'tag' => 'GRATIS ONGKIR',
'title' => 'Gratis Ongkir ke Seluruh Indonesia',
'desc' => 'Tanpa minimum pembelian untuk wilayah tertentu',
'code' => 'GRATIS500',
'min' => 'Rp100.000',
'valid' => '20 Des 2024',
'date_iso' => '2024-12-20',
'quota' => '189/300',
],
[
'tag' => 'CASHBACK 20%',
'title' => 'Cashback Pembelian Parfum',
'desc' => 'Dapatkan kembali 20% untuk setiap pembelian',
'code' => 'CASHBACK20',
'min' => 'Rp200.000',
'valid' => '25 Des 2024',
'date_iso' => '2024-12-25',
'quota' => '412/600',
],
[
'tag' => 'DISKON 25%',
'title' => 'Flash Sale Parfum Pria',
'desc' => 'Hemat untuk koleksi parfum pria pilihan',
'code' => 'FLASHPRIA',
'min' => 'Rp300.000',
'valid' => '18 Des 2024',
'date_iso' => '2024-12-18',
'quota' => '67/200',
],
[
'tag' => 'DISKON 20%',
'title' => 'Flash Sale Parfum Wanita',
'desc' => 'Hemat untuk koleksi parfum wanita favorit',
'code' => 'FLASHWOM',
'min' => 'Rp250.000',
'valid' => '22 Des 2024',
'date_iso' => '2024-12-22',
'quota' => '328/450',
],
[
'tag' => 'BELI 2 GRATIS 1',
'title' => 'Beli 2 Gratis 1 Aromatherapy',
'desc' => 'Promo spesial untuk produk aromatherapy',
'code' => 'BELI2GRAT',
'min' => 'Rp150.000',
'valid' => '28 Des 2024',
'date_iso' => '2024-12-28',
'quota' => '156/300',
],
];
@endphp
@foreach ($vouchers as $voucher) @foreach ($vouchers as $voucher)
<article <article
class="bg-white rounded-2xl border border-home-foreground/10 overflow-hidden hover:shadow-lg transition-shadow"> class="bg-white rounded-2xl border border-home-foreground/10 overflow-hidden hover:shadow-lg transition-shadow">
@ -113,29 +47,31 @@ class="bg-white rounded-2xl border border-home-foreground/10 overflow-hidden hov
<div class="relative"> <div class="relative">
<div <div
class="inline-block bg-home-foreground text-white px-3 py-1 rounded-full text-xs font-bold mb-3"> class="inline-block bg-home-foreground text-white px-3 py-1 rounded-full text-xs font-bold mb-3">
{{ $voucher['tag'] }}</div> {{ $voucher->tags }}</div>
<h3 class="text-xl font-bold text-home-foreground mb-1">{{ $voucher['title'] }}</h3> <h3 class="text-xl font-bold text-home-foreground mb-1">{{ $voucher->name }}</h3>
<p class="text-sm text-home-foreground/60 mb-4">{{ $voucher['desc'] }}</p> <p class="text-sm text-home-foreground/60 mb-4">{{ $voucher->summary }}</p>
<div class="bg-white rounded-lg p-3 mb-4 border border-home-foreground/20"> <div class="bg-white rounded-lg p-3 mb-4 border border-home-foreground/20">
<p class="text-xs text-home-foreground/60 mb-1">Kode Voucher:</p> <p class="text-xs text-home-foreground/60 mb-1">Kode Voucher:</p>
<p class="text-lg font-bold text-home-foreground font-mono tracking-widest"> <p class="text-lg font-bold text-home-foreground font-mono tracking-widest">
{{ $voucher['code'] }}</p> {{ $voucher->code }}</p>
</div> </div>
<div class="space-y-2 text-sm mb-4"> <div class="space-y-2 text-sm mb-4">
<div class="flex justify-between"> <div class="flex justify-between">
<span class="text-home-foreground/60">Min. Pembelian:</span> <span class="text-home-foreground/60">Min. Pembelian:</span>
<span class="font-semibold text-home-foreground">{{ $voucher['min'] }}</span> <span
class="font-semibold text-home-foreground">{{ $voucher->min_purchase_formatted }}</span>
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
<span class="text-home-foreground/60">Berlaku:</span> <span class="text-home-foreground/60">Berlaku s.d.:</span>
<time datetime="{{ $voucher['date_iso'] }}" <time datetime="{{ $voucher->end_date }}"
class="font-semibold text-home-foreground">{{ $voucher['valid'] }}</time> class="font-semibold text-home-foreground">{{ $voucher->end_date }}</time>
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
<span class="text-home-foreground/60">Sisa Voucher:</span> <span class="text-home-foreground/60">Sisa Voucher:</span>
<span class="font-semibold text-home-foreground">{{ $voucher['quota'] }}</span> <span class="font-semibold text-home-foreground">{{ $voucher->available_count }} /
{{ $voucher->quota ?? '∞' }}</span>
</div> </div>
</div> </div>
</div> </div>
@ -154,7 +90,9 @@ class="flex-1 border-2 border-home-foreground text-home-foreground font-bold py-
</article> </article>
@endforeach @endforeach
<div class="mt-8 flex justify-center">
{{ $vouchers->links() }}
</div>
</section> </section>
</main> </main>
</div> </div>

View File

@ -5,7 +5,7 @@
use App\Livewire\Home\Index as HomeComponent; use App\Livewire\Home\Index as HomeComponent;
use App\Livewire\Home\Outlet as OutletComponent; use App\Livewire\Home\Outlet as OutletComponent;
use App\Livewire\Home\Product\Index as ProductComponent; use App\Livewire\Home\Product\Index as ProductComponent;
use App\Livewire\Home\Voucher\Index as VoucherIndex; use App\Livewire\Home\Voucher as VoucherComponent;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::get('/', HomeComponent::class)->name('homepage'); Route::get('/', HomeComponent::class)->name('homepage');
@ -22,11 +22,7 @@
}); });
}); });
Route::prefix('vouchers') Route::get('/vouchers', VoucherComponent::class)->name('voucher');
->name('voucher.')
->group(function () {
Route::get('/', VoucherIndex::class)->name('index');
});
Route::prefix('articles') Route::prefix('articles')
->name('article.') ->name('article.')