222 lines
8.7 KiB
PHP
222 lines
8.7 KiB
PHP
@props([
|
|
'quantity' => 1,
|
|
'item_reference_id' => null,
|
|
'locationId' => session('location_id', 22),
|
|
'buttonText' => 'Add to cart',
|
|
'buttonClass' => 'btn-dark',
|
|
])
|
|
|
|
<div class="d-flex gap-3 pb-3 pb-lg-4 mb-3">
|
|
<div class="count-input flex-shrink-0">
|
|
<button type="button" class="btn btn-icon btn-lg" data-decrement aria-label="Decrement quantity"
|
|
onclick="decrementQuantity(this)">
|
|
<i class="ci-minus"></i>
|
|
</button>
|
|
<input type="number" class="form-control form-control-lg" min="1" value="{{ $quantity }}" readonly>
|
|
<button type="button" class="btn btn-icon btn-lg" data-increment aria-label="Increment quantity"
|
|
onclick="incrementQuantity(this)">
|
|
<i class="ci-plus"></i>
|
|
</button>
|
|
</div>
|
|
<button type="button" class="btn btn-lg {{ $buttonClass }} w-100" onclick="addToCartItem(this)"
|
|
data-item-reference-id="{{ $item_reference_id }}" data-location-id="{{ $locationId }}"
|
|
data-quantity="{{ $quantity }}">
|
|
<span class="button-text">{{ $buttonText }}</span>
|
|
<span class="loading-text" style="display: none;">
|
|
<i class="ci-loading animate-spin"></i> Adding...
|
|
</span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Login Dialog Modal -->
|
|
<div class="modal fade" id="loginDialogModal" tabindex="-1" aria-labelledby="loginDialogLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header border-0">
|
|
<h5 class="modal-title" id="loginDialogLabel">Login Required</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body text-center py-4">
|
|
<div class="mb-4">
|
|
<i class="ci-user-circle text-primary" style="font-size: 3rem;"></i>
|
|
</div>
|
|
<h6 class="mb-3">Please login to add items to cart</h6>
|
|
<p class="text-muted mb-4">You need to be logged in to add items to your shopping cart and proceed with checkout.</p>
|
|
<div class="d-grid gap-2">
|
|
<a href="{{ route('login') }}" class="btn btn-primary">
|
|
<i class="ci-login me-2"></i>Login to Continue
|
|
</a>
|
|
<a href="{{ route('register') }}" class="btn btn-outline-primary">
|
|
<i class="ci-user-plus me-2"></i>Create Account
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function incrementQuantity(button) {
|
|
const input = button.parentElement.querySelector('input[type="number"]');
|
|
input.value = parseInt(input.value);
|
|
updateAddToCartButton(button);
|
|
}
|
|
|
|
function decrementQuantity(button) {
|
|
const input = button.parentElement.querySelector('input[type="number"]');
|
|
const currentValue = parseInt(input.value);
|
|
if (currentValue > 1) {
|
|
input.value = currentValue;
|
|
}
|
|
updateAddToCartButton(button);
|
|
}
|
|
|
|
function updateAddToCartButton(button) {
|
|
const container = button.closest('.d-flex');
|
|
const addToCartBtn = container.querySelector('button[onclick="addToCartItem(this)"]');
|
|
const input = container.querySelector('input[type="number"]');
|
|
|
|
if (addToCartBtn && input) {
|
|
addToCartBtn.dataset.quantity = input.value;
|
|
}
|
|
}
|
|
|
|
async function addToCartItem(button) {
|
|
const itemReferenceId = button.dataset.itemReferenceId;
|
|
const locationId = button.dataset.locationId;
|
|
const quantity = button.dataset.quantity || button.parentElement.querySelector('input[type="number"]')
|
|
.value;
|
|
|
|
if (!itemReferenceId) {
|
|
console.error('Item Reference ID is required');
|
|
return;
|
|
}
|
|
|
|
const buttonText = button.querySelector('.button-text');
|
|
const loadingText = button.querySelector('.loading-text');
|
|
|
|
// Show loading state
|
|
button.disabled = true;
|
|
if (buttonText) buttonText.style.display = 'none';
|
|
if (loadingText) loadingText.style.display = 'inline';
|
|
|
|
try {
|
|
const token = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
|
const response = await fetch('{{ route('cart.add') }}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': token,
|
|
'Accept': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
item_reference_id: itemReferenceId,
|
|
location_id: locationId,
|
|
qty: quantity
|
|
})
|
|
});
|
|
|
|
if (response.ok) {
|
|
const result = await response.json();
|
|
if (result.success) {
|
|
// Update cart count in header
|
|
updateCartCount();
|
|
|
|
// Redirect to cart page on success
|
|
window.location.href = '{{ route('cart.index') }}';
|
|
}
|
|
} else {
|
|
const error = await response.json();
|
|
console.error('Error adding to cart:', error);
|
|
// Check if error is due to unauthenticated user
|
|
if (error.message && error.message.toLowerCase().includes('unauthenticated') || response.status === 401) {
|
|
showLoginDialog();
|
|
} else {
|
|
// You could show an error message here
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Network error:', error);
|
|
// You could show an error message here
|
|
} finally {
|
|
// Restore button state
|
|
button.disabled = false;
|
|
if (buttonText) buttonText.style.display = 'inline';
|
|
if (loadingText) loadingText.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
// Function to update cart count in header
|
|
async function updateCartCount() {
|
|
try {
|
|
const response = await fetch('{{ route('cart.count') }}', {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
|
|
if (response.ok) {
|
|
const result = await response.json();
|
|
const cartCountElements = document.querySelectorAll('.cart-count');
|
|
cartCountElements.forEach(element => {
|
|
element.textContent = result.count;
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Error updating cart count:', error);
|
|
}
|
|
}
|
|
|
|
// Function to show login dialog
|
|
function showLoginDialog() {
|
|
// Try to use Bootstrap Modal if available
|
|
if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
|
|
const modal = new bootstrap.Modal(document.getElementById('loginDialogModal'));
|
|
modal.show();
|
|
} else {
|
|
// Fallback: manually show the modal
|
|
const modalElement = document.getElementById('loginDialogModal');
|
|
if (modalElement) {
|
|
modalElement.style.display = 'block';
|
|
modalElement.classList.add('show');
|
|
modalElement.setAttribute('aria-modal', 'true');
|
|
modalElement.setAttribute('role', 'dialog');
|
|
|
|
// Add backdrop
|
|
const backdrop = document.createElement('div');
|
|
backdrop.className = 'modal-backdrop fade show';
|
|
backdrop.id = 'loginDialogBackdrop';
|
|
document.body.appendChild(backdrop);
|
|
|
|
// Handle close buttons
|
|
const closeButtons = modalElement.querySelectorAll('[data-bs-dismiss="modal"]');
|
|
closeButtons.forEach(button => {
|
|
button.onclick = hideLoginDialog;
|
|
});
|
|
|
|
// Handle backdrop click
|
|
backdrop.onclick = hideLoginDialog;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Function to hide login dialog
|
|
function hideLoginDialog() {
|
|
const modalElement = document.getElementById('loginDialogModal');
|
|
const backdrop = document.getElementById('loginDialogBackdrop');
|
|
|
|
if (modalElement) {
|
|
modalElement.style.display = 'none';
|
|
modalElement.classList.remove('show');
|
|
modalElement.removeAttribute('aria-modal');
|
|
modalElement.removeAttribute('role');
|
|
}
|
|
|
|
if (backdrop) {
|
|
backdrop.remove();
|
|
}
|
|
}
|
|
</script>
|