TKK_E32222868/app/Livewire/FoodOrder.php

272 lines
9.0 KiB
PHP

<?php
namespace App\Livewire;
use Livewire\Component;
use App\Models\Items; // --- UBAH: Menggunakan model Items
use App\Models\TypeItems; // --- BARU: Menambahkan model TypeItems
use Illuminate\Support\Str;
use Midtrans\Config;
use Midtrans\Snap;
class FoodOrder extends Component
{
public $foodItems = []; // --- UBAH: Menghapus 'array' type hint agar lebih fleksibel
public array $cart = [];
public bool $showCart = false;
public ?int $typeItemId = null; // --- UBAH: Mengganti $foodType menjadi $typeItemId (sesuai ItemTable)
// --- BARU: Properties untuk dropdown seperti di ItemTable
public $allTypeItems;
protected $listeners = [
'paymentSuccess' => 'handlePaymentSuccess'
];
public function openCart()
{
$this->showCart = true;
}
public function closeCart()
{
$this->showCart = false;
}
// --- DIHAPUS: getGroupedFoodItemsProperty tidak lagi relevan dengan type_item_id
// --- UBAH: Sesuaikan nama properti untuk filter
public function getFilteredFoodItemsProperty()
{
// --- UBAH: Menggunakan model Items
$query = Items::query();
if ($this->typeItemId) { // --- UBAH: Menggunakan $this->typeItemId
$query->where('type_item_id', $this->typeItemId);
}
// --- UBAH: Tambahkan kondisi is_available agar hanya menampilkan yang tersedia
$query->where('is_available', true);
// --- UBAH: eager load relasi typeItem
return $query->with('typeItem')->get(); // Menghapus ->toArray()
}
// --- UBAH: Sesuaikan nama method filter
public function filterByType($typeId = null) // --- UBAH: Parameter menjadi $typeId
{
$this->typeItemId = $typeId; // --- UBAH: Set $this->typeItemId
// Data foodItems akan diperbarui otomatis via render() dan getFilteredFoodItemsProperty()
// Jadi, tidak perlu secara eksplisit memuat ulang di sini.
// Dispatch event untuk update URL (jika diperlukan)
if ($typeId) {
// Asumsi route Anda mendukung parameter type_item_id
$typeItemName = TypeItems::find($typeId)->name ?? 'all'; // Ambil nama untuk URL
$this->dispatch('updateUrl', url: route('menu.byType', ['type' => Str::slug($typeItemName)]));
} else {
$this->dispatch('updateUrl', url: route('menu.all'));
}
}
public function mount($type = null) // --- UBAH: Parameter bisa berupa slug atau ID
{
// --- UBAH: Ambil semua TypeItems saat mount
$this->allTypeItems = TypeItems::all();
if ($type) {
// Coba temukan type_item berdasarkan slug atau ID
$foundType = TypeItems::where('id', $type)
->orWhere('name', Str::title(str_replace('-', ' ', $type))) // Coba cari berdasarkan nama yang dislug
->first();
$this->typeItemId = $foundType->id ?? null;
}
// --- UBAH: Awalnya, foodItems diisi oleh getFilteredFoodItemsProperty() di render
// Jadi tidak perlu query langsung di mount, cukup set $typeItemId
// Namun, jika Anda ingin agar foodItems langsung terisi saat mount, Anda bisa panggil properti
$this->foodItems = $this->getFilteredFoodItemsProperty();
$this->cart = session()->get('cart', []);
}
public function addToCart($id)
{
logger("Adding to cart: $id");
// --- UBAH: Menggunakan model Items
$item = Items::find($id); // Langsung query dari DB untuk memastikan data terkini
if ($item) {
if (!isset($this->cart[$id])) {
$this->cart[$id] = 1;
} else {
$this->cart[$id]++;
}
$this->updateCart();
$this->dispatch('notify', message: $item->name . ' ditambahkan ke keranjang');
} else {
logger("Item with ID $id not found.");
$this->dispatch('notify', message: 'Item tidak ditemukan.');
}
}
public function removeFromCart($id)
{
if (isset($this->cart[$id])) {
$this->cart[$id]--;
if ($this->cart[$id] <= 0) {
unset($this->cart[$id]);
}
$this->updateCart();
}
}
public function updateCart()
{
session()->put('cart', $this->cart);
}
public function updated($name, $value)
{
if (Str::startsWith($name, 'cart.')) {
$foodId = (int)substr($name, 5);
if ($value <= 0 || $value === null) {
unset($this->cart[$foodId]);
} else {
$this->cart[$foodId] = (int)$value;
}
$this->updateCart();
}
}
public function getCartItemsProperty()
{
$items = [];
// --- UBAH: Query items dari database berdasarkan ID di keranjang
// Ini lebih aman daripada mengandalkan $this->foodItems lokal yang mungkin sudah difilter
$foodIdsInCart = array_keys($this->cart);
$foodModels = Items::whereIn('id', $foodIdsInCart)->get()->keyBy('id'); // Ambil model Item
foreach ($this->cart as $foodId => $qty) {
$food = $foodModels->get($foodId); // Ambil model langsung dari koleksi
if ($food && $qty > 0) {
$items[] = [
'id' => $foodId,
'name' => $food->name,
'price' => $food->price,
'image_url' => $food->image_url ?? null,
'qty' => $qty,
'total_price' => $food->price * $qty,
];
}
}
return $items;
}
public function getCartTotalProperty()
{
return array_sum(array_map(function($item) {
return $item['total_price'];
}, $this->getCartItemsProperty()));
}
public function clearCart()
{
$this->cart = [];
$this->updateCart();
$this->closeCart();
}
public function handlePaymentSuccess()
{
$this->clearCart();
$this->dispatch('notify', message: 'Pembayaran berhasil!');
}
public function checkout()
{
logger("Checkout method called");
$cartItems = $this->getCartItemsProperty();
logger("Cart items: " . json_encode($cartItems));
if (empty($cartItems)) {
logger("Cart is empty");
$this->dispatch('notify', message: 'Keranjang kosong');
return;
}
try {
logger("Setting up Midtrans config");
\Midtrans\Config::$serverKey = config('services.midtrans.server_key');
\Midtrans\Config::$isProduction = false;
\Midtrans\Config::$isSanitized = true;
\Midtrans\Config::$is3ds = true;
$params = [
'transaction_details' => [
'order_id' => 'ORDER-' . time(),
'gross_amount' => $this->getCartTotalProperty(),
],
'customer_details' => [
'first_name' => auth()->user()->name ?? 'Guest',
'email' => auth()->user()->email ?? 'guest@example.com',
],
// --- BARU: Menambahkan item_details untuk Midtrans
'item_details' => array_map(function($item) {
return [
'id' => $item['id'],
'price' => $item['price'],
'quantity' => $item['qty'],
'name' => $item['name'],
];
}, $cartItems),
];
logger("Midtrans params: " . json_encode($params));
$snapToken = \Midtrans\Snap::getSnapToken($params);
logger("Snap token generated: " . $snapToken);
$this->dispatch('midtransSnapToken', token: $snapToken);
} catch (\Exception $e) {
logger("Midtrans error: " . $e->getMessage());
logger("Error trace: " . $e->getTraceAsString());
$this->dispatch('notify', message: 'Gagal memproses pembayaran: ' . $e->getMessage());
}
}
// Method untuk mendapatkan title berdasarkan type_item_id
// --- UBAH: Menggunakan type_item_id dan mengambil nama dari TypeItems
public function getPageTitleProperty()
{
if ($this->typeItemId) {
$typeItem = TypeItems::find($this->typeItemId);
return $typeItem->name ?? 'Semua Menu';
}
return 'Semua Menu';
}
public function render()
{
return view('livewire.food-order', [
'foodItems' => $this->getFilteredFoodItemsProperty(), // --- UBAH: Gunakan properti terkomputasi
'cartItems' => $this->getCartItemsProperty(),
'cartTotal' => $this->getCartTotalProperty(),
'pageTitle' => $this->getPageTitleProperty(),
'typeItemId' => $this->typeItemId, // --- UBAH: Mengganti foodType menjadi typeItemId
'allTypeItems' => $this->allTypeItems, // --- BARU: Lewatkan allTypeItems ke view
])->layout('components.layouts.front');
}
}