364 lines
24 KiB
PHP
364 lines
24 KiB
PHP
<div>
|
|
{{-- Hero Section --}}
|
|
<section class="relative h-[500px] flex items-center justify-center overflow-hidden">
|
|
{{-- Background Image --}}
|
|
<div class="absolute inset-0 z-0">
|
|
<img src="https://images.pexels.com/photos/5650052/pexels-photo-5650052.jpeg" alt="Perfume Background"
|
|
class="w-full h-full object-cover">
|
|
<div class="absolute inset-0 bg-black/40"></div>
|
|
</div>
|
|
|
|
{{-- Content --}}
|
|
<div class="relative z-10 container mx-auto px-6 text-center">
|
|
<h1 class="text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-6">{{ $pageTitle }}</h1>
|
|
<p class="text-white/80 text-lg md:text-xl max-w-2xl mx-auto mb-10">
|
|
{{ $pageDesc }}
|
|
</p>
|
|
|
|
{{-- Search Bar --}}
|
|
<div class="max-w-xl mx-auto relative group">
|
|
<input wire:model.live.debounce.500="search" type="search" placeholder="Cari voucher..."
|
|
aria-label="Cari artikel"
|
|
class="w-full py-4 pl-6 pr-14 rounded-full bg-white/10 backdrop-blur-md border border-white/20 text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-home-primary focus:bg-white/20 transition-all shadow-lg text-lg">
|
|
<button
|
|
class="absolute right-2 top-2 bottom-2 w-10 h-10 bg-home-primary rounded-full flex items-center justify-center text-white hover:bg-white hover:text-home-primary transition-all duration-300">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<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>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<main class="px-6 lg:px-32 xl:px-48 py-24 bg-white text-black font-sans">
|
|
<div class="flex flex-col lg:flex-row justify-center gap-4 mb-12" aria-label="Filter">
|
|
<div class="flex flex-col sm:flex-row gap-4">
|
|
<div class="relative">
|
|
<select wire:model.live="outlet_id" aria-label="Filter Outlet"
|
|
class="appearance-none px-6 py-3 pr-10 rounded-xl border border-home-foreground/10 bg-white text-home-foreground font-medium focus:outline-none focus:ring-2 focus:ring-home-primary focus:border-transparent transition cursor-pointer min-w-[180px] shadow-sm">
|
|
<option value="">Semua Outlet</option>
|
|
@foreach ($outlets as $key => $value)
|
|
<option value="{{ $key }}">{{ $value }}</option>
|
|
@endforeach
|
|
</select>
|
|
<svg class="absolute right-4 top-4 w-4 h-4 text-home-foreground/50 pointer-events-none"
|
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
|
</svg>
|
|
</div>
|
|
|
|
<div class="relative">
|
|
<select wire:model.live="sort" aria-label="Urutkan Voucher"
|
|
class="appearance-none px-6 py-3 pr-10 rounded-xl border border-home-foreground/10 bg-white text-home-foreground font-medium focus:outline-none focus:ring-2 focus:ring-home-primary focus:border-transparent transition cursor-pointer min-w-[160px] shadow-sm">
|
|
<option value="">Urutkan</option>
|
|
<option value="latest">Terbaru</option>
|
|
<option value="biggest">Potongan Terbesar</option>
|
|
<option value="ending-soon">Segera Berakhir</option>
|
|
</select>
|
|
<svg class="absolute right-4 top-4 w-4 h-4 text-home-foreground/50 pointer-events-none"
|
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@if ($vouchers->isNotEmpty())
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-12">
|
|
@foreach ($vouchers as $voucher)
|
|
<article
|
|
class="bg-white rounded-2xl border border-home-foreground/10 overflow-hidden hover:shadow-xl hover:shadow-home-primary/5 hover:border-home-primary/30 hover:-translate-y-1 transition-all duration-300 group flex flex-col h-full">
|
|
|
|
<div class="bg-home-primary/5 p-6 relative overflow-hidden flex-1">
|
|
<div
|
|
class="absolute top-0 right-0 w-24 h-24 bg-home-primary/10 rounded-full blur-2xl -mr-10 -mt-10">
|
|
</div>
|
|
|
|
<div class="relative z-10">
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-white px-3 py-1 rounded-full border border-home-primary/10 shadow-sm mb-4">
|
|
<span class="w-2 h-2 rounded-full bg-home-primary"></span>
|
|
<span
|
|
class="text-xs font-bold text-home-primary uppercase tracking-wider">{{ $voucher->tags }}</span>
|
|
</div>
|
|
|
|
<h3
|
|
class="text-xl font-bold text-home-foreground mb-2 group-hover:text-home-primary transition-colors line-clamp-2">
|
|
{{ $voucher->name }}
|
|
</h3>
|
|
<p class="text-sm text-home-foreground/60 mb-6 line-clamp-2 leading-relaxed">
|
|
{{ $voucher->summary }}
|
|
</p>
|
|
|
|
<div class="bg-white rounded-xl p-4 border border-dashed border-home-primary/30 flex items-center justify-between cursor-pointer hover:border-home-primary transition-colors"
|
|
x-data="{ textToCopy: '{{ $voucher->code }}', copied: false }"
|
|
@click="
|
|
navigator.clipboard.writeText(textToCopy);
|
|
copied = true;
|
|
setTimeout(() => copied = false, 1500);
|
|
">
|
|
<div>
|
|
<p
|
|
class="text-[10px] text-home-foreground/50 uppercase tracking-widest font-bold mb-1">
|
|
Kode Voucher
|
|
</p>
|
|
<p
|
|
class="text-lg font-bold text-home-primary font-mono tracking-widest select-all">
|
|
{{ $voucher->code }}
|
|
</p>
|
|
</div>
|
|
|
|
<div
|
|
class="w-8 h-8 rounded-full bg-home-primary/10 flex items-center justify-center text-home-primary">
|
|
<template x-if="!copied">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
|
</svg>
|
|
</template>
|
|
|
|
<template x-if="copied">
|
|
<svg class="w-4 h-4 text-green-600" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M5 13l4 4L19 7" />
|
|
</svg>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="px-6 pt-4 pb-0 space-y-3">
|
|
<div
|
|
class="flex justify-between items-center text-sm border-b border-home-foreground/5 pb-3">
|
|
<span class="text-home-foreground/50 flex items-center gap-2">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2-1.343-2-3-2zm0 4c-2.485 0-4.5 1.567-4.5 3.5V18h9v-2.5c0-1.933-2.015-3.5-4.5-3.5z">
|
|
</path>
|
|
</svg>
|
|
Min. Pembelian
|
|
</span>
|
|
<span
|
|
class="font-bold text-home-foreground">{{ formatCurrencyNumber($voucher->min_purchase, 'Rp') }}</span>
|
|
</div>
|
|
<div
|
|
class="flex justify-between items-center text-sm border-b border-home-foreground/5 pb-3">
|
|
<span class="text-home-foreground/50 flex items-center gap-2">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z">
|
|
</path>
|
|
</svg>
|
|
Berlaku Hingga
|
|
</span>
|
|
<time datetime="{{ formatDateLocalized($voucher->end_date) }}"
|
|
class="font-bold text-home-foreground">{{ formatDateLocalized($voucher->end_date) }}</time>
|
|
</div>
|
|
<div class="flex justify-between items-center text-sm">
|
|
<span class="text-home-foreground/50 flex items-center gap-2">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M20 12H4"></path>
|
|
</svg>
|
|
Sisa Kuota
|
|
</span>
|
|
<span
|
|
class="font-bold text-home-primary bg-home-primary/10 px-2 py-0.5 rounded text-xs">
|
|
{{ $voucher->available_count }} / {{ $voucher->quota ?? '∞' }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="p-6 flex gap-3 mt-auto">
|
|
<button wire:click="claim('{{ $voucher->hash }}')"
|
|
class="flex-1 bg-home-primary text-white font-bold py-3 rounded-xl hover:bg-home-secondary hover:text-home-primary hover:shadow-lg hover:shadow-home-primary/20 transition-all duration-300 text-sm shadow-md shadow-home-primary/10">
|
|
Klaim Voucher
|
|
</button>
|
|
<button wire:click="showDetail('{{ $voucher->hash }}')"
|
|
class="flex-1 border border-home-foreground/20 text-home-foreground font-bold py-3 rounded-xl hover:border-home-primary hover:text-home-primary hover:bg-home-primary/5 transition-all duration-300 text-sm">
|
|
Lihat Detail
|
|
</button>
|
|
</div>
|
|
</article>
|
|
@endforeach
|
|
</div>
|
|
|
|
<div class="flex justify-center w-full">
|
|
{{ $vouchers->links('vendor.livewire.custom-pagination') }}
|
|
</div>
|
|
@else
|
|
@include('components.animations.lottie.boxing-cat')
|
|
@endif
|
|
</main>
|
|
|
|
@if ($showDetailModal && $selectedVoucher)
|
|
<div class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
|
<div class="absolute inset-0 bg-black/60 backdrop-blur-sm" wire:click="closeDetail"></div>
|
|
<div
|
|
class="relative bg-white w-full max-w-2xl rounded-3xl overflow-hidden shadow-2xl animate-in fade-in zoom-in duration-300">
|
|
<div class="relative h-48 bg-home-primary flex items-center justify-center overflow-hidden">
|
|
<div class="absolute inset-0 opacity-20">
|
|
<div class="absolute top-0 right-0 w-64 h-64 bg-white rounded-full -mr-32 -mt-32"></div>
|
|
<div class="absolute bottom-0 left-0 w-48 h-48 bg-white rounded-full -ml-24 -mb-24"></div>
|
|
</div>
|
|
<div class="relative z-10 text-center">
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-white/20 backdrop-blur-md px-4 py-1.5 rounded-full border border-white/30 text-white text-xs font-bold uppercase tracking-widest mb-4">
|
|
<span class="w-2 h-2 rounded-full bg-white animate-pulse"></span>
|
|
{{ $selectedVoucher->tags }}
|
|
</div>
|
|
<h2 class="text-3xl font-bold text-white px-6">{{ $selectedVoucher->name }}</h2>
|
|
</div>
|
|
<button wire:click="closeDetail"
|
|
class="absolute top-6 right-6 w-10 h-10 rounded-full bg-white/10 hover:bg-white/20 text-white flex items-center justify-center transition-all">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M6 18L18 6M6 6l12 12"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="p-8 max-h-[60vh] overflow-y-auto custom-scrollbar">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
|
|
<div>
|
|
<h4 class="text-sm font-bold text-home-foreground/40 uppercase tracking-wider mb-4">Syarat
|
|
&
|
|
Ketentuan</h4>
|
|
<div class="space-y-4">
|
|
<div class="flex items-start gap-3">
|
|
<div
|
|
class="w-8 h-8 rounded-lg bg-home-primary/5 flex items-center justify-center text-home-primary mt-0.5">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3-.895 3-2-1.343-2-3-2zm0 4c-2.485 0-4.5 1.567-4.5 3.5V18h9v-2.5c0-1.933-2.015-3.5-4.5-3.5z">
|
|
</path>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm font-medium text-home-foreground/50">Minimum Pembelian</p>
|
|
<p class="font-bold text-home-foreground">
|
|
{{ formatCurrencyNumber($selectedVoucher->min_purchase, 'Rp') }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-start gap-3">
|
|
<div
|
|
class="w-8 h-8 rounded-lg bg-home-primary/5 flex items-center justify-center text-home-primary mt-0.5">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z">
|
|
</path>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm font-medium text-home-foreground/50">Masa Berlaku</p>
|
|
<p class="font-bold text-home-foreground">Hingga
|
|
{{ formatDateLocalized($selectedVoucher->end_date) }}</p>
|
|
</div>
|
|
</div>
|
|
@if ($selectedVoucher->limit_per_user)
|
|
<div class="flex items-start gap-3">
|
|
<div
|
|
class="w-8 h-8 rounded-lg bg-home-primary/5 flex items-center justify-center text-home-primary mt-0.5">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z">
|
|
</path>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm font-medium text-home-foreground/50">Batas per Pengguna
|
|
</p>
|
|
<p class="font-bold text-home-foreground">
|
|
{{ $selectedVoucher->limit_per_user }}x Klaim</p>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<h4 class="text-sm font-bold text-home-foreground/40 uppercase tracking-wider mb-4">
|
|
Outlet
|
|
Tersedia
|
|
</h4>
|
|
<div class="flex flex-wrap gap-2">
|
|
@forelse ($selectedVoucher->outlets as $outlet)
|
|
<span
|
|
class="px-4 py-2 bg-home-primary/5 border border-home-primary/10 rounded-xl text-sm font-semibold text-home-primary flex items-center gap-2">
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z">
|
|
</path>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"></path>
|
|
</svg>
|
|
{{ $outlet->name }}
|
|
</span>
|
|
@empty
|
|
<span
|
|
class="px-4 py-2 bg-home-foreground/5 border border-home-foreground/10 rounded-xl text-sm font-semibold text-home-foreground/50">
|
|
Dapat digunakan di semua outlet
|
|
</span>
|
|
@endforelse
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<h4 class="text-sm font-bold text-home-foreground/40 uppercase tracking-wider mb-4">
|
|
Tier
|
|
</h4>
|
|
<div class="flex flex-wrap gap-2">
|
|
@forelse ($selectedVoucher->tiers as $tier)
|
|
<span
|
|
class="px-4 py-2 bg-home-primary/5 border border-home-primary/10 rounded-xl text-sm font-semibold text-home-primary flex items-center gap-2">
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z">
|
|
</path>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"></path>
|
|
</svg>
|
|
{{ $tier->name }}
|
|
</span>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-home-foreground/5 rounded-2xl p-6">
|
|
<h4 class="text-sm font-bold text-home-foreground/40 uppercase tracking-wider mb-4">Ringkasan
|
|
</h4>
|
|
<p class="text-home-foreground/70 leading-relaxed italic">
|
|
"{{ $selectedVoucher->summary }}"
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="p-8 bg-white border-t border-home-foreground/5 flex gap-4">
|
|
<button wire:click="closeDetail"
|
|
class="flex-1 py-4 px-6 border border-home-foreground/20 text-home-foreground font-bold rounded-2xl hover:bg-home-foreground/5 transition-all">
|
|
Tutup
|
|
</button>
|
|
<button wire:click="claim('{{ $selectedVoucher->hash }}')"
|
|
class="flex-[2] py-4 px-6 bg-home-primary text-white font-bold rounded-2xl hover:bg-home-secondary hover:text-home-primary hover:shadow-xl hover:shadow-home-primary/20 transition-all shadow-lg shadow-home-primary/10">
|
|
Klaim Sekarang
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
@assets
|
|
<script src="https://unpkg.com/@lottiefiles/dotlottie-wc@0.8.5/dist/dotlottie-wc.js" type="module"></script>
|
|
@endassets
|