594 lines
23 KiB
PHP
594 lines
23 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire;
|
|
|
|
use Livewire\Component;
|
|
use App\Models\Items;
|
|
use App\Models\TypeItems;
|
|
use Illuminate\Support\Str;
|
|
use Midtrans\Config;
|
|
use Midtrans\Snap;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use App\Mail\OrderReceipt;
|
|
use Kreait\Firebase\Factory;
|
|
use Kreait\Firebase\ServiceAccount;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class FoodOrder extends Component
|
|
{
|
|
public array $cart = [];
|
|
public bool $showCart = false;
|
|
public ?int $typeItemId = null;
|
|
public bool $showEmailInput = false;
|
|
public string $customerEmail = '';
|
|
|
|
public bool $isExistingCustomer = false; // Meja sudah dipesan
|
|
public ?string $selectedTableId = null; // Untuk meja yang tersedia (table_activation_sensor_active = 0)
|
|
public ?string $selectedOccupiedTableId = null; // Untuk meja yang sudah diduduki (table_activation_sensor_active = 1, dengan reserved_by)
|
|
public string $inputCustomerName = ''; // Input nama pemesan
|
|
public bool $showCustomerNameInput = false;
|
|
public bool $isCustomerNameInputDisabled = false;
|
|
|
|
public array $availableTables = []; // Meja yang table_activation_sensor_active = 0
|
|
public array $occupiedTables = []; // Meja yang table_activation_sensor_active = 1 dan punya reserved_by
|
|
public Collection $allTablesData; // Menggunakan Collection untuk pencarian lebih cepat
|
|
public bool $showMapModal = false;
|
|
|
|
public ?string $tableIdFromUrl = null; // ID meja dari URL QR code
|
|
|
|
protected array $rules = [
|
|
'customerEmail' => 'required|email|max:255',
|
|
'selectedTableId' => 'nullable|string',
|
|
'selectedOccupiedTableId' => 'nullable|string',
|
|
'inputCustomerName' => 'nullable|string|max:255', // Validasi bersyarat
|
|
];
|
|
|
|
protected $listeners = [
|
|
'paymentSuccess' => 'handlePaymentSuccess',
|
|
'tableStatusUpdated' => 'syncTablesFromFirebase', // Refresh table data after status update
|
|
];
|
|
|
|
public function mount($typeSlug = null)
|
|
{
|
|
$this->cart = session()->get('cart', []);
|
|
$this->allTablesData = collect(); // Inisialisasi collection kosong
|
|
$this->syncTablesFromFirebase();
|
|
|
|
if (request()->has('table_id')) {
|
|
$this->tableIdFromUrl = request()->query('table_id');
|
|
}
|
|
|
|
// Handle default typeSlug redirection only if not already on the correct path
|
|
if (empty($typeSlug) && (request()->route()->getName() !== 'menu.byType' || request()->segment(2) !== 'makanan')) {
|
|
return redirect()->route('menu.byType', ['typeSlug' => 'makanan']);
|
|
}
|
|
|
|
if (!empty($typeSlug)) {
|
|
$foundType = TypeItems::whereRaw('LOWER(REPLACE(name, " ", "-")) = ?', [Str::lower($typeSlug)])->first();
|
|
$this->typeItemId = $foundType->id ?? null;
|
|
|
|
if (!$this->typeItemId) {
|
|
// If typeSlug is provided but not found, redirect to default 'makanan'
|
|
return redirect()->route('menu.byType', ['typeSlug' => 'makanan']);
|
|
}
|
|
} else {
|
|
// Default to 'makanan' if no typeSlug is provided
|
|
$defaultType = TypeItems::whereRaw('LOWER(REPLACE(name, " ", "-")) = ?', ['makanan'])->first();
|
|
$this->typeItemId = $defaultType->id ?? null;
|
|
}
|
|
}
|
|
|
|
private function attemptAutoSelectTable()
|
|
{
|
|
if ($this->tableIdFromUrl && $this->allTablesData->isNotEmpty()) {
|
|
$foundTable = $this->allTablesData->firstWhere('device_id', $this->tableIdFromUrl);
|
|
|
|
if ($foundTable) {
|
|
$isActive = $foundTable['firebase_data']['sensors']['table_activation_sensor_active'] ?? 0;
|
|
$hasReservedBy = isset($foundTable['reserved_by']) && !empty($foundTable['reserved_by']);
|
|
|
|
if ($isActive === 0) { // Meja tersedia
|
|
$this->selectedTableId = $foundTable['id'];
|
|
$this->selectedOccupiedTableId = null; // Pastikan kosong
|
|
$this->inputCustomerName = auth()->user()->name ?? 'Guest';
|
|
$this->isExistingCustomer = false;
|
|
$this->dispatch('notify', message: 'Meja ' . $foundTable['device_id'] . ' berhasil dipilih secara otomatis.');
|
|
} elseif ($hasReservedBy) { // Meja tidak tersedia dan punya nama pemesan
|
|
$this->selectedOccupiedTableId = $foundTable['id'];
|
|
$this->selectedTableId = null; // Pastikan kosong
|
|
$this->isExistingCustomer = true;
|
|
$this->dispatch('notify', message: 'Meja ' . $foundTable['device_id'] . ' sudah terisi oleh ' . $foundTable['reserved_by'] . '. Harap konfirmasi nama Anda.');
|
|
} else {
|
|
$this->dispatch('notify', message: 'Meja ' . $foundTable['device_id'] . ' saat ini tidak tersedia.');
|
|
$this->selectedTableId = null;
|
|
$this->selectedOccupiedTableId = null;
|
|
}
|
|
} else {
|
|
$this->dispatch('notify', message: 'Meja ' . $this->tableIdFromUrl . ' tidak ditemukan.');
|
|
$this->selectedTableId = null;
|
|
$this->selectedOccupiedTableId = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getFirebaseDatabase()
|
|
{
|
|
try {
|
|
$firebaseCredentialsPath = config('services.firebase.credentials');
|
|
|
|
// Periksa di lokasi default Laravel dan storage
|
|
if (!file_exists($firebaseCredentialsPath)) {
|
|
$firebaseCredentialsPath = storage_path('app/' . $firebaseCredentialsPath);
|
|
}
|
|
if (!file_exists($firebaseCredentialsPath)) {
|
|
throw new \Exception("Firebase credentials file not found at: " . $firebaseCredentialsPath);
|
|
}
|
|
|
|
$factory = (new Factory)
|
|
->withServiceAccount($firebaseCredentialsPath)
|
|
->withDatabaseUri(config('services.firebase.database_url'));
|
|
|
|
return $factory->createDatabase();
|
|
} catch (\Exception $e) {
|
|
logger()->error("Firebase initialization failed: " . $e->getMessage());
|
|
$this->dispatch('notify', message: 'Gagal terhubung ke sistem meja: ' . $e->getMessage());
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public function syncTablesFromFirebase()
|
|
{
|
|
$database = $this->getFirebaseDatabase();
|
|
if (!$database) {
|
|
$this->availableTables = [];
|
|
$this->occupiedTables = [];
|
|
$this->allTablesData = collect();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$firebaseTablesData = $database->getReference('/')->getValue();
|
|
$processedAvailableTables = [];
|
|
$processedOccupiedTables = [];
|
|
$allProcessedTables = [];
|
|
|
|
if ($firebaseTablesData) {
|
|
foreach ($firebaseTablesData as $firebaseKey => $data) {
|
|
$isActive = $data['sensors']['table_activation_sensor_active'] ?? 0;
|
|
$isAvailable = ($isActive === 0);
|
|
$reservedBy = $data['reserved_by'] ?? null;
|
|
$hasReservedBy = !empty($reservedBy);
|
|
|
|
$tableDetail = [
|
|
'id' => $firebaseKey,
|
|
'device_id' => $data['device_id'] ?? $firebaseKey,
|
|
'table_activation_sensor_active' => $isActive,
|
|
'reserved_by' => $reservedBy,
|
|
'is_available' => $isAvailable,
|
|
'has_reserved_by' => $hasReservedBy,
|
|
'firebase_data' => $data // Simpan data mentah untuk referensi
|
|
];
|
|
|
|
$allProcessedTables[$firebaseKey] = $tableDetail; // Gunakan ID sebagai kunci untuk pencarian cepat
|
|
|
|
if ($isAvailable) {
|
|
$processedAvailableTables[] = $tableDetail;
|
|
} elseif ($hasReservedBy) {
|
|
$processedOccupiedTables[] = $tableDetail;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->availableTables = array_values($processedAvailableTables);
|
|
$this->occupiedTables = array_values($processedOccupiedTables);
|
|
$this->allTablesData = collect($allProcessedTables); // Convert to Collection
|
|
|
|
// Panggil attemptAutoSelectTable setelah data meja siap
|
|
$this->attemptAutoSelectTable();
|
|
|
|
logger("Tables synced from Firebase. Total available tables: " . count($this->availableTables));
|
|
logger("Total occupied tables (with name): " . count($this->occupiedTables));
|
|
logger("Total tables for dropdown and map: " . $this->allTablesData->count());
|
|
|
|
} catch (\Exception $e) {
|
|
logger()->error("Failed to sync tables from Firebase: " . $e->getMessage());
|
|
$this->dispatch('notify', message: 'Gagal memperbarui status meja dari Firebase: ' . $e->getMessage());
|
|
$this->availableTables = [];
|
|
$this->occupiedTables = [];
|
|
$this->allTablesData = collect();
|
|
}
|
|
}
|
|
|
|
public function showMap()
|
|
{
|
|
$this->showMapModal = true;
|
|
}
|
|
|
|
public function closeMap()
|
|
{
|
|
$this->showMapModal = false;
|
|
}
|
|
|
|
public function updatedSelectedTableId($value)
|
|
{
|
|
// Reset state jika pilihan meja tersedia berubah
|
|
$this->selectedOccupiedTableId = null;
|
|
$this->inputCustomerName = '';
|
|
$this->showCustomerNameInput = false;
|
|
$this->isCustomerNameInputDisabled = false;
|
|
$this->resetErrorBag(['inputCustomerName']);
|
|
|
|
if ($value) {
|
|
$this->inputCustomerName = auth()->user()->name ?? 'Guest';
|
|
$this->showCustomerNameInput = true;
|
|
// $this->isCustomerNameInputDisabled tetap false
|
|
}
|
|
logger("Meja kosong dipilih: " . $value);
|
|
}
|
|
|
|
public function updatedSelectedOccupiedTableId($value)
|
|
{
|
|
// Reset state jika pilihan meja terreservasi berubah
|
|
$this->selectedTableId = null;
|
|
$this->inputCustomerName = '';
|
|
$this->showCustomerNameInput = false;
|
|
$this->isCustomerNameInputDisabled = false;
|
|
$this->resetErrorBag(['inputCustomerName']);
|
|
|
|
if ($value) {
|
|
$selectedTable = $this->allTablesData->get($value); // Menggunakan get() dari Collection
|
|
if ($selectedTable && $selectedTable['has_reserved_by']) {
|
|
$this->inputCustomerName = $selectedTable['reserved_by'];
|
|
$this->showCustomerNameInput = true;
|
|
$this->isCustomerNameInputDisabled = true;
|
|
$this->dispatch('notify', message: 'Nama pemesan otomatis terisi: ' . $selectedTable['reserved_by'] . '.');
|
|
} else {
|
|
$this->inputCustomerName = '';
|
|
$this->showCustomerNameInput = true;
|
|
$this->isCustomerNameInputDisabled = false;
|
|
$this->dispatch('notify', message: 'Meja ini terisi, namun nama pemesan belum terdaftar. Mohon masukkan nama Anda.');
|
|
}
|
|
}
|
|
logger("Meja terisi dipilih: " . $value);
|
|
}
|
|
|
|
public function updatedIsExistingCustomer($value)
|
|
{
|
|
$this->selectedTableId = null;
|
|
$this->selectedOccupiedTableId = null;
|
|
$this->inputCustomerName = '';
|
|
$this->showCustomerNameInput = false;
|
|
$this->isCustomerNameInputDisabled = false;
|
|
$this->resetErrorBag(['selectedTableId', 'selectedOccupiedTableId', 'inputCustomerName']);
|
|
|
|
if (!$value) { // Jika user TIDAK mencentang "Saya sudah memesan meja" (pemesanan baru)
|
|
$this->inputCustomerName = auth()->user()->name ?? 'Guest';
|
|
$this->showCustomerNameInput = true;
|
|
// $this->isCustomerNameInputDisabled tetap false
|
|
}
|
|
}
|
|
|
|
private function validateTableSelection()
|
|
{
|
|
$this->resetErrorBag(['selectedTableId', 'selectedOccupiedTableId', 'inputCustomerName']);
|
|
|
|
$selectedTableId = $this->isExistingCustomer ? $this->selectedOccupiedTableId : $this->selectedTableId;
|
|
$errorProperty = $this->isExistingCustomer ? 'selectedOccupiedTableId' : 'selectedTableId';
|
|
|
|
if (empty($selectedTableId)) {
|
|
$this->addError($errorProperty, 'Pilih meja Anda.');
|
|
return false;
|
|
}
|
|
|
|
$selectedTable = $this->allTablesData->get($selectedTableId);
|
|
|
|
if (!$selectedTable) {
|
|
$this->addError($errorProperty, 'Meja yang dipilih tidak valid.');
|
|
return false;
|
|
}
|
|
|
|
$isSensorActive = ($selectedTable['firebase_data']['sensors']['table_activation_sensor_active'] ?? 0) === 1;
|
|
|
|
if ($this->isExistingCustomer) { // Mengisi meja yang sudah terisi
|
|
if (!$isSensorActive) { // Jika meja dipilih sebagai "terisi" tapi sensornya 0 (tersedia)
|
|
$this->addError($errorProperty, 'Meja yang dipilih sebagai "sudah terisi" ternyata masih tersedia.');
|
|
return false;
|
|
}
|
|
if (!$selectedTable['has_reserved_by']) { // Jika meja terisi tapi tidak ada nama pemesan
|
|
$this->addError($errorProperty, 'Meja ini tidak tersedia untuk penambahan pesanan tanpa nama pemesan yang terdaftar. Pilih meja kosong atau meja terisi lain.');
|
|
return false;
|
|
}
|
|
// Validasi nama pemesan untuk meja terisi
|
|
$this->validateOnly('inputCustomerName', ['inputCustomerName' => 'required|string|max:255'], [
|
|
'inputCustomerName.required' => 'Masukkan nama pemesan yang sesuai dengan meja ini.',
|
|
]);
|
|
if ($this->getErrorBag()->has('inputCustomerName')) {
|
|
return false;
|
|
}
|
|
if (Str::lower($this->inputCustomerName) !== Str::lower($selectedTable['reserved_by'])) {
|
|
$this->addError('inputCustomerName', 'Nama pemesan tidak cocok dengan data meja ini: "' . $selectedTable['reserved_by'] . '".');
|
|
return false;
|
|
}
|
|
} else { // Mengisi meja yang tersedia
|
|
if ($isSensorActive) { // Jika meja dipilih sebagai "tersedia" tapi sensornya 1 (tidak tersedia)
|
|
$this->addError($errorProperty, 'Meja yang dipilih tidak tersedia.');
|
|
return false;
|
|
}
|
|
// Pastikan nama pemesan tidak kosong saat memilih meja kosong
|
|
$this->validateOnly('inputCustomerName', ['inputCustomerName' => 'required|string|max:255'], [
|
|
'inputCustomerName.required' => 'Nama pemesan wajib diisi untuk meja baru.',
|
|
]);
|
|
if ($this->getErrorBag()->has('inputCustomerName')) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
public function checkout()
|
|
{
|
|
if (!$this->validateTableSelection()) {
|
|
return;
|
|
}
|
|
$this->validate(['customerEmail' => 'required|email']);
|
|
|
|
logger("Checkout method called.");
|
|
$cartItems = $this->getCartItemsProperty();
|
|
|
|
if (empty($cartItems)) {
|
|
logger("Cart is empty");
|
|
$this->dispatch('notify', message: 'Keranjang kosong');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
Config::$serverKey = config('services.midtrans.server_key');
|
|
Config::$isProduction = config('services.midtrans.is_production', false);
|
|
Config::$isSanitized = true;
|
|
Config::$is3ds = true;
|
|
|
|
$selectedTableData = $this->getSelectedTableForTransaction();
|
|
|
|
$params = [
|
|
'transaction_details' => [
|
|
'order_id' => 'ORDER-' . time() . '-' . uniqid(),
|
|
'gross_amount' => $this->getCartTotalProperty(),
|
|
],
|
|
'customer_details' => [
|
|
'first_name' => $this->inputCustomerName ?: (auth()->user()->name ?? 'Guest'),
|
|
'email' => auth()->user()->email ?? $this->customerEmail ?? 'guest@example.com',
|
|
],
|
|
'item_details' => array_map(function($item) {
|
|
return [
|
|
'id' => $item['id'],
|
|
'price' => $item['price'],
|
|
'quantity' => $item['qty'],
|
|
'name' => $item['name'],
|
|
];
|
|
}, $cartItems),
|
|
'custom_field1' => 'Firebase Table ID: ' . ($selectedTableData['id'] ?? 'N/A'),
|
|
'custom_field2' => 'Nama Meja: ' . ($selectedTableData['device_id'] ?? 'N/A'),
|
|
'custom_field3' => 'Nama Pemesan: ' . $this->inputCustomerName,
|
|
];
|
|
|
|
$snapToken = Snap::getSnapToken($params);
|
|
$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());
|
|
}
|
|
}
|
|
|
|
public function sendReceiptEmail()
|
|
{
|
|
if (!$this->validateTableSelection()) {
|
|
return;
|
|
}
|
|
$this->validate(['customerEmail' => 'required|email|max:255']);
|
|
|
|
$cartItems = $this->getCartItemsProperty();
|
|
$cartTotal = $this->getCartTotalProperty();
|
|
$mejaDetail = $this->getSelectedTableForTransaction();
|
|
|
|
try {
|
|
Mail::to($this->customerEmail)->send(new OrderReceipt($cartItems, $cartTotal, $mejaDetail));
|
|
|
|
$this->dispatch('notify', message: 'Detail pesanan telah dikirim ke email Anda.');
|
|
$this->updateTableAndResetState(); // Menggunakan fungsi baru
|
|
} catch (\Exception $e) {
|
|
logger("Failed to send receipt email: " . $e->getMessage());
|
|
$this->dispatch('notify', message: 'Gagal mengirim email. Silakan coba lagi.');
|
|
}
|
|
}
|
|
|
|
public function skipPayment()
|
|
{
|
|
if (!$this->validateTableSelection()) {
|
|
return;
|
|
}
|
|
|
|
$this->dispatch('notify', message: 'Pesanan Anda telah diproses tanpa pembayaran.');
|
|
$this->updateTableAndResetState(); // Menggunakan fungsi baru
|
|
}
|
|
|
|
public function handlePaymentSuccess()
|
|
{
|
|
$this->dispatch('notify', message: 'Pembayaran berhasil!');
|
|
$this->updateTableAndResetState(); // Menggunakan fungsi baru
|
|
}
|
|
|
|
// Fungsi Pembantu Baru
|
|
private function getSelectedTableForTransaction(): ?array
|
|
{
|
|
$tableId = $this->selectedTableId ?? $this->selectedOccupiedTableId;
|
|
return $this->allTablesData->get($tableId);
|
|
}
|
|
|
|
// Fungsi Pembantu Baru untuk mengupdate meja dan mereset state
|
|
private function updateTableAndResetState()
|
|
{
|
|
$tableData = $this->getSelectedTableForTransaction();
|
|
if ($tableData) {
|
|
$updates = [
|
|
'sensors/table_activation_sensor_active' => 1,
|
|
'reserved_by' => $this->inputCustomerName
|
|
];
|
|
$this->updateFirebaseTableStatus($tableData['id'], $updates);
|
|
}
|
|
$this->clearCartAndResetState();
|
|
}
|
|
|
|
private function updateFirebaseTableStatus(string $firebaseTableId, array $updates)
|
|
{
|
|
$database = $this->getFirebaseDatabase();
|
|
if (!$database) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$database->getReference($firebaseTableId)->update($updates);
|
|
logger("Firebase: Updated {$firebaseTableId} with " . json_encode($updates));
|
|
$this->dispatch('notify', message: "Status meja '{$firebaseTableId}' berhasil diperbarui di Firebase.");
|
|
$this->syncTablesFromFirebase(); // Pertahankan ini untuk memastikan UI Livewire refresh
|
|
} catch (\Exception $e) {
|
|
logger()->error("Failed to update Firebase for table ID {$firebaseTableId}: " . $e->getMessage());
|
|
$this->dispatch('notify', message: 'Gagal memperbarui status meja di Firebase: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
private function clearCartAndResetState()
|
|
{
|
|
$this->cart = [];
|
|
session()->forget('cart');
|
|
$this->showCart = false;
|
|
$this->showEmailInput = false;
|
|
$this->customerEmail = '';
|
|
$this->selectedTableId = null;
|
|
$this->selectedOccupiedTableId = null;
|
|
$this->inputCustomerName = '';
|
|
$this->resetValidation();
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.food-order', [
|
|
'foodItems' => $this->getFilteredFoodItemsProperty(),
|
|
'cartItems' => $this->getCartItemsProperty(),
|
|
'cartTotal' => $this->getCartTotalProperty(),
|
|
'pageTitle' => $this->getPageTitleProperty(),
|
|
'typeItemId' => $this->typeItemId,
|
|
'allTypeItems' => $this->getAllTypeItemsProperty(),
|
|
'availableTables' => $this->availableTables,
|
|
'occupiedTables' => $this->occupiedTables,
|
|
'allTablesData' => $this->allTablesData->toArray(), // Kirim sebagai array ke view
|
|
'tableIdFromUrl' => $this->tableIdFromUrl,
|
|
])->layout('components.layouts.front');
|
|
}
|
|
|
|
// --- Helper Properties ---
|
|
|
|
public function getFoodItemsProperty()
|
|
{
|
|
return Items::all();
|
|
}
|
|
|
|
public function getAllTypeItemsProperty() // Menggabungkan getTypeItemsProperty
|
|
{
|
|
return TypeItems::all();
|
|
}
|
|
|
|
public function getFilteredFoodItemsProperty()
|
|
{
|
|
if ($this->typeItemId) {
|
|
return Items::where('type_item_id', $this->typeItemId)->get();
|
|
}
|
|
return Items::all();
|
|
}
|
|
|
|
public function getCartItemsProperty()
|
|
{
|
|
$items = [];
|
|
foreach ($this->cart as $itemId => $qty) {
|
|
$item = Items::find($itemId);
|
|
if ($item) {
|
|
$items[] = [
|
|
'id' => $item->id,
|
|
'name' => $item->name,
|
|
'price' => $item->price,
|
|
'qty' => $qty,
|
|
'total_price' => $item->price * $qty,
|
|
];
|
|
}
|
|
}
|
|
return $items;
|
|
}
|
|
|
|
public function getCartTotalProperty()
|
|
{
|
|
return collect($this->getCartItemsProperty())->sum('total_price');
|
|
}
|
|
|
|
public function getPageTitleProperty()
|
|
{
|
|
if ($this->typeItemId) {
|
|
$type = TypeItems::find($this->typeItemId);
|
|
return $type ? $type->name : 'Semua Menu';
|
|
}
|
|
return 'Semua Menu';
|
|
}
|
|
|
|
public function addToCart($itemId)
|
|
{
|
|
$item = Items::find($itemId);
|
|
if (!$item) {
|
|
$this->dispatch('notify', message: 'Item tidak ditemukan.');
|
|
return;
|
|
}
|
|
|
|
$this->cart[$itemId] = ($this->cart[$itemId] ?? 0) + 1;
|
|
session()->put('cart', $this->cart);
|
|
$this->dispatch('notify', message: $item->name . ' ditambahkan ke keranjang.');
|
|
}
|
|
|
|
public function removeFromCart($itemId)
|
|
{
|
|
if (isset($this->cart[$itemId])) {
|
|
$item = Items::find($itemId); // Get item before potential unset
|
|
if ($this->cart[$itemId] > 1) {
|
|
$this->cart[$itemId]--;
|
|
} else {
|
|
unset($this->cart[$itemId]);
|
|
}
|
|
session()->put('cart', $this->cart);
|
|
$this->dispatch('notify', message: $item->name . ' dihapus dari keranjang.');
|
|
if (empty($this->cart)) {
|
|
$this->showCart = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function openCart()
|
|
{
|
|
$this->showCart = true;
|
|
}
|
|
|
|
public function closeCart()
|
|
{
|
|
$this->showCart = false;
|
|
}
|
|
|
|
public function filterByType($typeId)
|
|
{
|
|
$this->typeItemId = $typeId;
|
|
$type = TypeItems::find($typeId);
|
|
if ($type) {
|
|
$typeSlug = Str::slug($type->name);
|
|
$newUrl = route('menu.byType', ['typeSlug' => $typeSlug], false);
|
|
$this->dispatch('updateUrl', url: $newUrl);
|
|
}
|
|
}
|
|
}
|