관리-도구
편집 파일: cart.blade.php
@extends('layouts.appss') @section('content') <main> <div class="ul-container"> <div class="ul-breadcrumb"> <h2 class="ul-breadcrumb-title">Cart List</h2> <div class="ul-breadcrumb-nav"> <a href="{{ url('/') }}"><i class="flaticon-home"></i> Home</a> <i class="flaticon-arrow-point-to-right"></i> <span class="current-page">Cart List</span> </div> </div> </div> <div class="ul-cart-container"> <div class="cart-top"> <div class="table-responsive"> <table class="ul-cart-table"> <thead> <tr> <th>Product</th> <th>Price</th> <th>Color</th> <th>Size</th> <th>Quantity</th> <th>Subtotal</th> <th>Remove</th> </tr> </thead> <tbody> @php $total = 0; @endphp @foreach($cartItems as $item) @php $product = $item->product; $price = $product->price; $subtotal = $price * $item->quantity; $total += $subtotal; $colorName = $item->color ? \App\Models\ProductColor::where('id', $item->color)->value('color_name') : '-'; // ✅ Get selected color image or fallback $colorModel = $item->color ? \App\Models\ProductColor::with('images')->find($item->color) : null; if ($colorModel && $colorModel->images->isNotEmpty()) { $imagePath = $colorModel->images->first()->image; } elseif ($product->images->isNotEmpty()) { $imagePath = $product->images->first()->image; } else { $imagePath = 'images/no-image.jpg'; } @endphp <tr data-id="{{ $item->id }}"> <td> <div class="ul-cart-product"> <a href="{{ route('shop-details', $item->product_id) }}" class="ul-cart-product-img"> <img src="{{ asset('storage/' . $imagePath) }}" alt="{{ $product->title }}"> </a> <a href="{{ route('shop-details', $item->product_id) }}" class="ul-cart-product-title"> {{ $product->title }} </a> </div> </td> <td><span class="ul-cart-item-price" data-price="{{ $price }}">₹{{ number_format($price, 2) }}</span></td> <td>{{ $colorName }}</td> {{-- ✅ Size or Meter column --}} <td> @if($product->product_mode === 'material') Meter @else {{ $item->size ?? '-' }} @endif </td> {{-- ✅ Quantity column --}} <td> @if($product->product_mode === 'material') {{-- 🧵 For material, show meter quantity in same styled box (no + / - buttons) --}} <div class="ul-product-details-quantity mt-0"> <div class="quantity-box" style="justify-content: center;"> <input type="text" class="ul-product-quantity" value="{{ $item->quantity }} Meter" readonly style="pointer-events: none; width: 70px; border: none; background: transparent; text-align: center; font-weight: 600;"> </div> </div> @else {{-- 🛍️ For ready-made, show + / - buttons --}} <div class="ul-product-details-quantity mt-0"> <div class="quantity-box"> <button type="button" class="quantityDecreaseButton">-</button> <input type="number" name="product-quantity" class="ul-product-quantity" value="{{ $item->quantity }}" min="1" data-id="{{ $item->id }}" style="pointer-events:none;"> <button type="button" class="quantityIncreaseButton">+</button> </div> </div> @endif </td> <td><span class="ul-cart-item-subtotal">₹{{ number_format($subtotal, 2) }}</span></td> <td> <div class="ul-cart-item-remove"> <form method="POST" action="{{ route('cart.remove', $item->id) }}"> @csrf @method('DELETE') <button type="submit"><i class="flaticon-close"></i></button> </form> </div> </td> </tr> @endforeach </tbody> </table> </div> </div> <style> .quantity-box { display: flex; align-items: center; border: 1px solid #ddd; border-radius: 6px; overflow: hidden; width: 110px; justify-content: space-between; } .quantity-box button { background-color: #f8f8f8; border: none; font-size: 20px; width: 35px; height: 35px; cursor: pointer; transition: all 0.2s ease; } .quantity-box button:hover { background-color: #222; color: #fff; } .quantity-box input { border: none; width: 40px; text-align: center; font-size: 16px; background: transparent; pointer-events: none; } </style> <!-- ✅ Total section without shipping --> <div class="cart-bottom"> <div class="ul-cart-expense-overview"> <h3 class="ul-cart-expense-overview-title">Total</h3> <div class="middle"> <div class="single-row"> <span class="inner-title">Subtotal</span> <span class="number" id="subtotal">₹{{ number_format($total, 2) }}</span> </div> </div> <div class="bottom"> <div class="single-row"> <span class="inner-title">Total</span> <span class="number" id="total">₹{{ number_format($total, 2) }}</span> </div> <a href="{{ route('cartcheckout') }}" class="ul-cart-checkout-direct-btn"> CHECKOUT </a> </div> </div> </div> </div> </main> <style> .quantity-box button { position: relative; z-index: 1000; /* Ensures buttons are clickable */ pointer-events: auto; } </style> <!-- ✅ JavaScript for live quantity update --> <script> window.addEventListener("load", () => { let isUpdating = false; console.log("JS Loaded"); document.querySelectorAll(".quantityIncreaseButton, .quantityDecreaseButton") .forEach(button => { button.addEventListener("click", async (event) => { event.preventDefault(); if (isUpdating) return; isUpdating = true; const row = button.closest("tr"); const input = row.querySelector(".ul-product-quantity"); const itemId = row.dataset.id; const price = parseFloat(row.querySelector(".ul-cart-item-price").dataset.price); const subtotalEl = row.querySelector(".ul-cart-item-subtotal"); let quantity = parseInt(input.value.trim()) || 1; // ✅ Handle + button if (button.classList.contains("quantityIncreaseButton")) { try { const res = await fetch(`/cart/check-stock/${itemId}`); const data = await res.json(); console.log("Stock API Response:", data); if (!data.available_quantity) { alert("Stock check failed."); isUpdating = false; return; } if (quantity + 1 > data.available_quantity) { alert(`Only ${data.available_quantity} quantity available.`); isUpdating = false; return; } quantity++; } catch (error) { console.error("Stock API Error:", error); alert("Unable to check stock. Please try again."); isUpdating = false; return; } } // ✅ Handle - button if (button.classList.contains("quantityDecreaseButton") && quantity > 1) { quantity--; } // ✅ Update UI input.value = quantity; subtotalEl.textContent = "₹" + (price * quantity).toFixed(2); updateTotals(); // ✅ Update backend await fetch(`/cart/update/${itemId}`, { method: "POST", headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": "{{ csrf_token() }}" }, body: JSON.stringify({ quantity }) }); isUpdating = false; }); }); function updateTotals() { let subtotal = 0; document.querySelectorAll(".ul-cart-item-subtotal").forEach(el => { subtotal += parseFloat(el.textContent.replace(/[₹,]/g, "")) || 0; }); document.getElementById("subtotal").textContent = "₹" + subtotal.toFixed(2); document.getElementById("total").textContent = "₹" + subtotal.toFixed(2); } }); </script> @endsection