<x-app-layout>
<div class="py-12"
{{-- membuat state komponent alpine --}}
x-data="stateListProduct({{ Js::from($products) }})">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900 dark:text-gray-100">
{{-- {{ __("CASHIER DASHBOARD") }} --}}
{{-- <div class="max-w-7xl mx-auto p-2 lg:p-4">
<div class="mt-2"> --}}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 lg:gap-8 item-start">
{{-- start card list product --}}
<div class="scale-100 p-6 bg-white dark:bg-gray-800/50 dark:bg-gradient-to-bl from-gray-700/50 via-transparent dark:ring-1 dark:ring-inset dark:ring-white/5 rounded-lg shadow-2xl shadow-gray-500/20 dark:shadow-none flex duration-250 focus:outline focus:outline-2 focus:outline-red-500 w-full">
<div class="grid grid-cols-2 gap-2 w-full">
<div
x-show="listProduct.filter(p => p.quantity > 0).length === 0"
class="col-span-2 bg-blue-500 text-white text-center py-6 rounded-lg font-semibold">
Tidak ada produk tersedia
</div>
{{-- @for ($i = 0; $i < 6; $i++) --}}
<template x-for="product in listProduct.filter(p => p.quantity > 0)" :key="product.id">
<div class="motion-safe:hover:scale-[1.01] transition-transform w-full max-w-sm bg-white border border-gray-200 rounded-lg shadow-sm dark:bg-gray-800 dark:border-gray-700">
<a href="#">
<img class="p-2 rounded-xl" src="https://flowbite.s3.amazonaws.com/docs/gallery/square/image.jpg" alt="product image" />
</a>
<div class="px-5 pb-5">
<a href="#">
<h5 class="text-xl font-semibold tracking-tight text-gray-900 dark:text-white" x-text="product.name"></h5>
</a>
<div class="flex items-center justify-between mt-2.5 mb-5 w-full">
<div class="flex items-center space-x-1">
<svg class="w-4 h-4 text-yellow-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"/>
</svg>
<svg class="w-4 h-4 text-yellow-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"/>
</svg>
<svg class="w-4 h-4 text-yellow-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"/>
</svg>
<svg class="w-4 h-4 text-yellow-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"/>
</svg>
<svg class="w-4 h-4 text-gray-200 dark:text-gray-600" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 22 20">
<path d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"/>
</svg>
</div>
<span class="text-sm text-blue-500 font-semibold whitespace-nowrap">
<span x-text="product.quantity"></span>
</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm font-bold text-gray-900 dark:text-white">
Rp <span x-text="parseInt(product.price)"></span>
</span>
<button
@click="addProductToCart(product)"
:disabled="product.quantity == 0 || isInCart(product.id)"
:class="product.quantity == 0
? 'bg-gray-400 cursor-not-allowed text-white'
: isInCart(product.id)
? 'bg-blue-500 text-white'
: 'bg-blue-500 hover:bg-blue-600 text-white'"
class="px-4 py-2 rounded-lg w-full"
>
<span x-text="
product.quantity == 0
? 'Stok Habis'
: isInCart(product.id)
? 'Added'
: 'Add to cart'
"></span>
</button>
</div>
</div>
</div>
</template>
{{-- @endfor --}}
</div>
</div>
{{-- end card list product --}}
{{-- start card order product --}}
<div class="scale-100 p-6 dark:bg-gray-800 rounded-lg shadow-md flex flex-col">
<h2 class="mb-4 text-xl font-semibold text-gray-900 dark:text-white">
Daftar Pesanan
</h2>
<table class="w-full text-sm text-gray-500 dark:text-gray-400">
<thead class="text-xs uppercase bg-gray-100 dark:bg-gray-700">
<tr>
<th class="px-4 py-2">Produk</th>
<th class="px-4 py-2">Qty</th>
<th class="px-4 py-2">Harga</th>
<th></th>
</tr>
</thead>
<tbody>
<template x-for="product in listProductOnCart" :key="product.id">
<tr>
<td class="px-4 py-2" x-text="product.name"></td>
<!-- QTY -->
<td class="px-4 py-2">
<div class="flex items-center gap-2">
<button @click="decreaseQty(product.id)"
class="bg-gray-300 px-2 rounded">-</button>
<span x-text="product.qty"></span>
<button @click="increaseQty(product)"
class="bg-gray-300 px-2 rounded">+</button>
</div>
</td>
<!-- HARGA -->
<td class="px-4 py-2"
x-text="(product.qty * product.price).toLocaleString('id-ID')"></td>
<!-- HAPUS -->
<td>
<button @click="removeProductFromCart(product.id)"
class="text-red-500">X</button>
</td>
</tr>
</template>
</tbody>
<!-- TOTAL + PEMBAYARAN -->
<tfoot x-show="listProductOnCart.length > 0">
<tr class="font-bold">
<td colspan="2">Total</td>
<td x-text="totalPrice().toLocaleString('id-ID')"></td>
</tr>
<tr>
<td colspan="2">Membayar</td>
<td>
<input type="number"
x-model="money"
class="w-full border rounded p-1">
</td>
</tr>
<tr>
<td colspan="3">
<p class="text-sm text-gray-700" x-text="message"></p>
</td>
</tr>
<tr>
<td colspan="3">
<button @click="pay()"
class="w-full bg-blue-500 text-black py-2 rounded">
Bayar
</button>
</td>
</tr>
</tfoot>
</table>
</div>
{{-- end card order product --}}
</div>
{{-- </div>
</div> --}}
</div>
</div>
</div>
</div>
<script>
function stateListProduct(productsFromLaravel) {
return {
listProduct: productsFromLaravel,
listProductOnCart: [],
money: 0,
paymentStatus: '',
message: '',
addProductToCart(product) {
let existing = this.listProductOnCart.find(p => p.id === product.id);
if (existing) {
if (existing.qty < product.quantity) {
existing.qty++;
} else {
alert("Stok habis!");
}
} else {
this.listProductOnCart.push({
...product,
qty: 1
});
}
},
removeProductFromCart(id) {
this.listProductOnCart =
this.listProductOnCart.filter(p => p.id !== id);
},
isInCart(id) {
return this.listProductOnCart.some(p => p.id === id);
},
increaseQty(product) {
let existing = this.listProductOnCart.find(p => p.id === product.id);
if (existing.qty < product.quantity) {
existing.qty++;
} else {
alert("Stok tidak cukup!");
}
},
decreaseQty(id) {
let existing = this.listProductOnCart.find(p => p.id === id);
if (existing.qty > 1) {
existing.qty--;
} else {
this.removeProductFromCart(id);
}
},
totalPrice() {
return this.listProductOnCart.reduce((sum, p) => {
return sum + (p.qty * p.price);
}, 0);
},
pay() {
let total = this.totalPrice();
if (this.money < total) {
alert("Saldo tidak cukup");
return;
}
// KIRIM KE LARAVEL
fetch('/checkout', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({
products: this.listProductOnCart
})
})
.then(res => res.json())
.then(data => {
alert("Produk berhasil di order");
// reset cart
this.listProductOnCart = [];
this.money = 0;
// reload biar stok update
location.reload();
});
}
}
}
</script>
</x-app-layout>0 views