451 lines
16 KiB
PHP
451 lines
16 KiB
PHP
<div class="accordion bg-body-tertiary rounded-5 p-4">
|
|
<div class="accordion-item border-0">
|
|
<h3 class="accordion-header" id="promoCodeHeading">
|
|
<button type="button"
|
|
class="accordion-button animate-underline collapsed py-0 ps-sm-2 ps-lg-0 ps-xl-2"
|
|
data-bs-toggle="collapse"
|
|
data-bs-target="#promoCode"
|
|
aria-expanded="false"
|
|
aria-controls="promoCode">
|
|
<i class="ci-percent fs-xl me-2"></i>
|
|
<span class="animate-target me-2">
|
|
{{ __('checkout.use_point') }}
|
|
</span>
|
|
</button>
|
|
</h3>
|
|
|
|
<div class="accordion-collapse collapse"
|
|
id="promoCode"
|
|
aria-labelledby="promoCodeHeading">
|
|
|
|
<div class="accordion-body pt-3 pb-2 ps-sm-2 px-lg-0 px-xl-2">
|
|
|
|
{{-- Your Points --}}
|
|
<div class="alert bg-white dark:bg-gray-800 text-white mb-3">
|
|
|
|
<div class="d-flex align-items-center gap-3">
|
|
<div>
|
|
<h4 class="mb-0 fw-bold text-dark dark:text-white" id="userPoints">{{ number_format(auth()->user()->customer->point, 0, ",",".") }}</h4>
|
|
<small class="text-black dark:text-white">{{ __('checkout.available_points') }}</small>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Points Form --}}
|
|
@if(session('use_point'))
|
|
{{-- Points Applied Display --}}
|
|
<div class="alert alert-success d-flex align-items-center gap-3">
|
|
<div class="flex-grow-1">
|
|
<h6 class="mb-1">{{ __('checkout.points_applied') }}</h6>
|
|
<p class="mb-0">
|
|
<strong>{{ number_format(session('use_point'), 0, ",", ".") }}</strong> {{ __('checkout.points_used') }}
|
|
</p>
|
|
</div>
|
|
<button type="button" class="btn btn-outline-danger btn-sm" id="remove-points-btn">
|
|
{{ __('checkout.remove_point') }}
|
|
</button>
|
|
</div>
|
|
@else
|
|
{{-- Apply Points Form --}}
|
|
<form class="needs-validation d-flex gap-2" novalidate>
|
|
<div class="position-relative w-100">
|
|
<input type="number"
|
|
class="form-control"
|
|
id="input-point"
|
|
min="1"
|
|
max="{{ auth()->user()->customer->point }}"
|
|
placeholder="{{ __('checkout.input_point') }}"
|
|
required>
|
|
</div>
|
|
<button type="submit" class="btn btn-dark">
|
|
{{ __('checkout.apply_point') }}
|
|
</button>
|
|
</form>
|
|
@endif
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
{{-- SINGLE REUSABLE MODAL --}}
|
|
<div class="modal fade" id="voucherEventModal" tabindex="-1">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content rounded-4">
|
|
<div class="modal-header border-0">
|
|
<h5 class="modal-title fw-semibold">
|
|
Voucher Event
|
|
</h5>
|
|
<button type="button"
|
|
class="btn-close"
|
|
data-bs-dismiss="modal">
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body pt-0">
|
|
<div id="voucherEventContent"></div>
|
|
</div>
|
|
|
|
<div class="modal-footer border-0">
|
|
<button type="button"
|
|
class="btn btn-secondary"
|
|
data-bs-dismiss="modal">
|
|
{{ __('checkout.close') }}
|
|
</button>
|
|
|
|
<button type="button"
|
|
class="btn btn-primary"
|
|
id="redeemVoucherBtn"
|
|
data-voucher-event-id="">
|
|
{{ __('checkout.redeem') }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
|
|
const modal = document.getElementById('voucherEventModal');
|
|
|
|
modal.addEventListener('show.bs.modal', function (event) {
|
|
|
|
const button = event.relatedTarget;
|
|
|
|
const name = button.getAttribute('data-name');
|
|
const description = button.getAttribute('data-description');
|
|
const point = button.getAttribute('data-point');
|
|
const start = button.getAttribute('data-start');
|
|
const end = button.getAttribute('data-end');
|
|
const terms = button.getAttribute('data-terms');
|
|
|
|
let content = '';
|
|
|
|
if (description) {
|
|
content += `<p>${description}</p>`;
|
|
}
|
|
|
|
if (point) {
|
|
content += `
|
|
<div class="mb-2">
|
|
<strong>{{ __('checkout.points_required') }}:</strong>
|
|
${point}
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
if (start && end) {
|
|
content += `
|
|
<div class="mb-2">
|
|
<strong>{{ __('checkout.valid_period') }}:</strong><br>
|
|
${start} - ${end}
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
if (terms) {
|
|
content += `
|
|
<div class="mt-3 small text-muted">
|
|
<strong>{{ __('checkout.terms_and_conditions') }}:</strong>
|
|
<p>${terms}</p>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
modal.querySelector('.modal-title').textContent = name;
|
|
document.getElementById('voucherEventContent').innerHTML = content;
|
|
|
|
// Set voucher event ID for redeem button
|
|
const redeemBtn = document.getElementById('redeemVoucherBtn');
|
|
redeemBtn.setAttribute('data-voucher-event-id', button.getAttribute('data-id'));
|
|
|
|
});
|
|
|
|
// Handle points form submission
|
|
document.addEventListener('submit', function(e) {
|
|
const form = e.target;
|
|
|
|
// Check if this is the points form
|
|
if (!form || !form.classList.contains('needs-validation')) {
|
|
return;
|
|
}
|
|
|
|
e.preventDefault();
|
|
|
|
const pointInput = form.querySelector('input[placeholder="{{ __('checkout.input_point') }}"]');
|
|
const submitBtn = form.querySelector('button[type="submit"]');
|
|
const originalText = submitBtn.textContent;
|
|
const availablePoints = parseInt(document.getElementById('userPoints').textContent.replace(/\./g, ''));
|
|
|
|
if (!pointInput || !pointInput.value.trim()) {
|
|
alert('Please enter points to use');
|
|
return;
|
|
}
|
|
|
|
const pointsToUse = parseInt(pointInput.value.trim());
|
|
|
|
if (isNaN(pointsToUse) || pointsToUse <= 0) {
|
|
alert('Please enter a valid number of points');
|
|
return;
|
|
}
|
|
|
|
if (pointsToUse > availablePoints) {
|
|
alert('You cannot use more points than available');
|
|
return;
|
|
}
|
|
|
|
// Show loading state
|
|
submitBtn.disabled = true;
|
|
submitBtn.textContent = 'Applying...';
|
|
|
|
// Get CSRF token
|
|
const token = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
|
|
|
// Submit points to server to set session
|
|
fetch('/apply-points', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'X-CSRF-TOKEN': token,
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: new URLSearchParams({
|
|
'use_point': pointsToUse
|
|
}).toString()
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Show success message
|
|
alert('Points applied successfully!');
|
|
|
|
// Clear input
|
|
pointInput.value = '';
|
|
|
|
// Add visual feedback
|
|
pointInput.style.backgroundColor = '#d4edda';
|
|
pointInput.style.borderColor = '#28a745';
|
|
|
|
// Remove visual feedback after 2 seconds
|
|
setTimeout(() => {
|
|
pointInput.style.backgroundColor = '';
|
|
pointInput.style.borderColor = '';
|
|
}, 2000);
|
|
|
|
// Reload page to show updated cart
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1000);
|
|
} else {
|
|
// Show error message
|
|
alert(data.message || 'Failed to apply points');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error applying points:', error);
|
|
alert('An error occurred while applying the points');
|
|
})
|
|
.finally(() => {
|
|
// Restore button state
|
|
submitBtn.disabled = false;
|
|
submitBtn.textContent = originalText;
|
|
});
|
|
});
|
|
|
|
// Handle remove points button click
|
|
document.getElementById('remove-points-btn')?.addEventListener('click', function() {
|
|
const removeBtn = this;
|
|
const originalText = removeBtn.textContent;
|
|
|
|
// Show loading state
|
|
removeBtn.disabled = true;
|
|
removeBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Removing...';
|
|
|
|
// Get CSRF token
|
|
const token = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
|
|
|
// Remove points via AJAX
|
|
fetch('/remove-points', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'X-CSRF-TOKEN': token,
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Show success message
|
|
alert('Points removed successfully!');
|
|
|
|
// Clear input field
|
|
const pointInput = document.querySelector('input#input-point');
|
|
if (pointInput) {
|
|
pointInput.value = '';
|
|
pointInput.style.backgroundColor = '#f8d7da';
|
|
pointInput.style.borderColor = '#dc3545';
|
|
|
|
// Remove visual feedback after 2 seconds
|
|
setTimeout(() => {
|
|
pointInput.style.backgroundColor = '';
|
|
pointInput.style.borderColor = '';
|
|
}, 2000);
|
|
}
|
|
|
|
// Reload page to show updated cart
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1000);
|
|
} else {
|
|
// Show error message
|
|
alert(data.message || 'Failed to remove points');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error removing points:', error);
|
|
alert('An error occurred while removing the points');
|
|
})
|
|
.finally(() => {
|
|
// Restore button state
|
|
removeBtn.disabled = false;
|
|
removeBtn.textContent = originalText;
|
|
});
|
|
});
|
|
|
|
// Handle redeem button click
|
|
document.getElementById('redeemVoucherBtn').addEventListener('click', function() {
|
|
const voucherEventId = this.getAttribute('data-voucher-event-id');
|
|
|
|
if (!voucherEventId) {
|
|
console.error('No voucher event ID found');
|
|
return;
|
|
}
|
|
|
|
// Disable button during processing
|
|
this.disabled = true;
|
|
this.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Processing...';
|
|
|
|
// Make AJAX call to redeem voucher
|
|
fetch(`/voucher-events/${voucherEventId}/redeem`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''
|
|
},
|
|
body: JSON.stringify({})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Show success message
|
|
alert('Voucher redeemed successfully!');
|
|
|
|
window.location.reload();
|
|
} else {
|
|
// Show error message
|
|
alert(data.message || 'Failed to redeem voucher');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An error occurred while redeeming the voucher');
|
|
})
|
|
.finally(() => {
|
|
// Re-enable button
|
|
this.disabled = false;
|
|
this.innerHTML = '{{ __('checkout.redeem') }}';
|
|
});
|
|
});
|
|
|
|
// Custom modal handler to prevent backdrop issues
|
|
const voucherBadges = document.querySelectorAll('[data-bs-toggle="modal"][data-bs-target="#voucherEventModal"]');
|
|
voucherBadges.forEach(function(badge) {
|
|
badge.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
// Remove any existing backdrop
|
|
const existingBackdrop = document.querySelector('.modal-backdrop');
|
|
if (existingBackdrop) {
|
|
existingBackdrop.remove();
|
|
}
|
|
|
|
// Show modal without backdrop
|
|
const modalInstance = new bootstrap.Modal(modal, {
|
|
backdrop: false
|
|
});
|
|
modalInstance.show();
|
|
});
|
|
});
|
|
|
|
// Function to apply voucher code when badge is clicked
|
|
function applyVoucher(voucherCode) {
|
|
// Find the point input
|
|
const pointInput = document.querySelector('input#input-point');
|
|
|
|
if (pointInput) {
|
|
|
|
// set point session via AJAX
|
|
const token = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
|
|
|
fetch('/apply-points', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'X-CSRF-TOKEN': token,
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: new URLSearchParams({
|
|
'use_point': voucherCode
|
|
}).toString()
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Set the voucher code in input
|
|
pointInput.value = voucherCode;
|
|
|
|
// Add visual feedback
|
|
pointInput.style.backgroundColor = '#d4edda';
|
|
pointInput.style.borderColor = '#28a745';
|
|
|
|
// Remove visual feedback after 2 seconds
|
|
setTimeout(() => {
|
|
pointInput.style.backgroundColor = '';
|
|
pointInput.style.borderColor = '';
|
|
}, 2000);
|
|
|
|
// Show success message
|
|
alert('Points applied successfully!');
|
|
|
|
// Reload page to show updated cart
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1000);
|
|
} else {
|
|
// Show error message
|
|
alert(data.message || 'Failed to apply points');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error applying points:', error);
|
|
alert('An error occurred while applying the points');
|
|
});
|
|
|
|
// Focus on the input
|
|
pointInput.focus();
|
|
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
</script> |