167 lines
8.8 KiB
PHP
167 lines
8.8 KiB
PHP
<div class="container mx-auto px-4 py-8 main-content-scroll">
|
|
<div class="flex flex-col sm:flex-row justify-between items-center mb-8 gap-4">
|
|
<h1 class="text-3xl font-bold text-gray-800">{{ $pageTitle }}</h1>
|
|
|
|
<div class="w-full sm:w-auto">
|
|
<label for="typeFilter" class="sr-only">Filter by Category</label>
|
|
<select id="typeFilter" wire:model.live="typeItemId" wire:change="filterByType($event.target.value)"
|
|
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-green-500 focus:ring focus:ring-green-500 focus:ring-opacity-50">
|
|
<option value="">Semua Menu</option>
|
|
@foreach ($allTypeItems as $type)
|
|
<option value="{{ $type->id }}">{{ $type->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 mb-8">
|
|
@forelse ($foodItems as $item) {{-- UBAH: Gunakan $item sebagai objek model --}}
|
|
<div wire:click="addToCart({{ $item->id }})" {{-- UBAH: Akses ID sebagai properti objek --}}
|
|
class="bg-white cursor-pointer shadow rounded-lg transition transform hover:scale-105 active:scale-95 active:ring-2 active:ring-green-400">
|
|
@if (isset($item->image_url) && $item->image_url) {{-- UBAH: Akses image_url sebagai properti objek --}}
|
|
<img src="{{ $item->image_url }}" alt="{{ $item->name }}" class="w-full h-40 object-cover" {{-- UBAH: Akses name sebagai properti objek --}}
|
|
loading="lazy" decoding="async" />
|
|
@else
|
|
{{-- UBAH: Logika gambar default disesuaikan --}}
|
|
<img src="{{ asset('img/placeholder-food.jpg') }}" alt="{{ $item->name }}"
|
|
class="w-full h-40 object-cover" loading="lazy" decoding="async" />
|
|
@endif
|
|
|
|
<div class="p-4 flex flex-col flex-grow">
|
|
<h2 class="text-lg font-semibold leading-tight">{{ $item->name }}</h2> {{-- UBAH: Akses name sebagai properti objek --}}
|
|
<p class="text-gray-500 mb-3">Rp {{ number_format($item->price, 0, ',', '.') }}</p> {{-- UBAH: Akses price sebagai properti objek --}}
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div class="col-span-full text-center py-10">
|
|
<p class="text-gray-500 text-xl">Tidak ada menu tersedia untuk kategori ini.</p>
|
|
</div>
|
|
@endforelse
|
|
</div>
|
|
|
|
<div class="fixed bottom-4 right-4 z-30">
|
|
<button wire:click="openCart"
|
|
class="bg-green-600 text-white rounded-full p-4 shadow-lg hover:bg-green-700 transition flex items-center gap-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24"
|
|
stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" />
|
|
</svg>
|
|
<span class="font-medium">{{ array_sum($cart) }}</span>
|
|
|
|
</button>
|
|
</div>
|
|
|
|
@if ($showCart)
|
|
<div class="fixed inset-0 bg-black bg-opacity-50 z-40 flex items-center justify-center" role="dialog"
|
|
aria-modal="true" aria-labelledby="cart-title">
|
|
<div class="bg-white w-full max-w-md rounded shadow-lg p-6 z-50 relative">
|
|
<h2 id="cart-title" class="text-xl font-bold mb-4">Keranjang</h2>
|
|
|
|
@if (empty($cartItems))
|
|
<p class="text-gray-500">Keranjang kosong.</p>
|
|
@else
|
|
<ul class="divide-y divide-gray-200 mb-4 max-h-72 overflow-y-auto" tabindex="0">
|
|
@foreach ($cartItems as $item)
|
|
<li class="py-2 flex justify-between items-center">
|
|
<div>
|
|
<p class="font-medium">{{ $item['name'] }}</p>
|
|
<p class="text-sm text-gray-500">Rp
|
|
{{ number_format($item['price'], 0, ',', '.') }}</p>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<button wire:click="removeFromCart({{ $item['id'] }})" type="button"
|
|
class="px-2 py-1 bg-red-100 text-red-700 rounded">
|
|
-
|
|
</button>
|
|
<span class="mx-2">{{ $item['qty'] }}</span>
|
|
<button wire:click="addToCart({{ $item['id'] }})" type="button"
|
|
class="px-2 py-1 bg-green-100 text-green-700 rounded">
|
|
+
|
|
</button>
|
|
</div>
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
<div class="font-bold mb-4 text-right text-lg">Total: Rp
|
|
{{ number_format($cartTotal, 0, ',', '.') }}</div>
|
|
<button wire:click="checkout"
|
|
class="w-full bg-green-600 hover:bg-green-700 text-white py-2 rounded mb-2 focus:outline-none focus:ring-2 focus:ring-green-500"
|
|
type="button" wire:loading.attr="disabled" wire:loading.class="opacity-50">
|
|
<span wire:loading.remove>Checkout</span>
|
|
<span wire:loading>Processing...</span>
|
|
</button>
|
|
@endif
|
|
|
|
<button wire:click="closeCart"
|
|
class="absolute top-2 right-2 text-gray-500 hover:text-gray-700 focus:outline-none"
|
|
aria-label="Close cart" type="button">
|
|
✕
|
|
</button>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<div x-data="{ notification: false, message: '' }"
|
|
x-on:notify.window="notification = true; message = $event.detail.message; setTimeout(() => notification = false, 3000)"
|
|
x-cloak>
|
|
<div x-show="notification" x-transition:enter="transition ease-out duration-300"
|
|
x-transition:enter-start="opacity-0 transform translate-y-2"
|
|
x-transition:enter-end="opacity-100 transform translate-y-0"
|
|
x-transition:leave="transition ease-in duration-200"
|
|
x-transition:leave-start="opacity-100 transform translate-y-0"
|
|
x-transition:leave-end="opacity-0 transform translate-y-2"
|
|
class="fixed top-8 right-8 bg-green-500 text-white px-4 py-2 rounded shadow-lg z-50"> {{-- Tambahkan z-50 --}}
|
|
<p x-text="message"></p>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
Livewire.on('midtransSnapToken', (data) => {
|
|
console.log('Snap token received:', data.token);
|
|
|
|
if (typeof snap !== 'undefined') {
|
|
snap.pay(data.token, {
|
|
onSuccess: function(result) {
|
|
console.log('Payment success:', result);
|
|
Livewire.dispatch('paymentSuccess');
|
|
},
|
|
onPending: function(result) {
|
|
console.log('Payment pending:', result);
|
|
Livewire.dispatch('notify', {
|
|
message: 'Pembayaran belum selesai'
|
|
});
|
|
},
|
|
onError: function(result) {
|
|
console.log('Payment error:', result);
|
|
Livewire.dispatch('notify', {
|
|
message: 'Terjadi kesalahan pembayaran'
|
|
});
|
|
},
|
|
onClose: function() {
|
|
console.log('Payment closed');
|
|
Livewire.dispatch('notify', {
|
|
message: 'Pembayaran dibatalkan'
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
console.error("Midtrans Snap is not loaded. Please check your Midtrans script tag.");
|
|
Livewire.dispatch('notify', {
|
|
message: 'Payment gateway tidak tersedia'
|
|
});
|
|
}
|
|
});
|
|
|
|
// Handle URL updates from Livewire component
|
|
Livewire.on('updateUrl', (data) => {
|
|
const newUrl = data.url;
|
|
if (window.history.pushState) {
|
|
window.history.pushState({ path: newUrl }, '', newUrl);
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
</div>
|