update payment selection ui & layout adjustments
This commit is contained in:
@@ -203,6 +203,11 @@
|
|||||||
<div class="card-block">
|
<div class="card-block">
|
||||||
<div class="payment-waiting text-center" style="height: 400px; display: flex; flex-direction: column; justify-content: space-between; align-items: center;">
|
<div class="payment-waiting text-center" style="height: 400px; display: flex; flex-direction: column; justify-content: space-between; align-items: center;">
|
||||||
<img src="/image/mmqr.webp" alt="MMQR Payment" style="max-width: 120px; margin-bottom: 10px;">
|
<img src="/image/mmqr.webp" alt="MMQR Payment" style="max-width: 120px; margin-bottom: 10px;">
|
||||||
|
<div class="processing-indicator" style="margin: 1rem 0;">
|
||||||
|
<div class="processing-dot"></div>
|
||||||
|
<div class="processing-dot"></div>
|
||||||
|
<div class="processing-dot"></div>
|
||||||
|
</div>
|
||||||
<h3 class="m-t-20" style="color: #555;">Waiting for Customer Payment</h3>
|
<h3 class="m-t-20" style="color: #555;">Waiting for Customer Payment</h3>
|
||||||
<p class="text-muted">Please ask customer to scan the QR code</p>
|
<p class="text-muted">Please ask customer to scan the QR code</p>
|
||||||
<% if @qr_svg %>
|
<% if @qr_svg %>
|
||||||
@@ -210,15 +215,11 @@
|
|||||||
<%= raw @qr_svg %>
|
<%= raw @qr_svg %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div class="processing-indicator m-t-10" style="margin-top: 8rem;">
|
<div class="d-flex" style="margin-top: 1rem;">
|
||||||
<div class="processing-dot"></div>
|
<button class="btn btn-danger" id="cancel-btn">Cancel Payment</button>
|
||||||
<div class="processing-dot"></div>
|
|
||||||
<div class="processing-dot"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex" style="margin-top: 10rem;">
|
|
||||||
<button class="btn btn-block btn-default waves-effect" id="cancel-btn">Cancel</button>
|
|
||||||
</div>
|
|
||||||
<input type="hidden" name="server_mode" value="<%=ENV["SERVER_MODE"]%>" id="server_mode">
|
<input type="hidden" name="server_mode" value="<%=ENV["SERVER_MODE"]%>" id="server_mode">
|
||||||
<input type="hidden" name="display_type" id="display_type" value="<%= @display_type%>">
|
<input type="hidden" name="display_type" id="display_type" value="<%= @display_type%>">
|
||||||
</div>
|
</div>
|
||||||
@@ -271,6 +272,7 @@ $(document).ready(function() {
|
|||||||
console.log("Received:", data);
|
console.log("Received:", data);
|
||||||
|
|
||||||
if (data.status === "PAY_SUCCESS") {
|
if (data.status === "PAY_SUCCESS") {
|
||||||
|
$('#cancel-btn').hide();
|
||||||
this.handlePaymentSuccess();
|
this.handlePaymentSuccess();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -303,7 +305,7 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = "/";
|
window.location.href = "/";
|
||||||
}, 3000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: (xhr, status, error) => {
|
error: (xhr, status, error) => {
|
||||||
|
|||||||
@@ -149,7 +149,7 @@
|
|||||||
|
|
||||||
<%# Top Bar - New Design %>
|
<%# Top Bar - New Design %>
|
||||||
<% if !request.path_info.include?('second_display') %>
|
<% if !request.path_info.include?('second_display') %>
|
||||||
<nav class="navbar new-design-navbar" style="position: sticky;">
|
<nav class="navbar new-design-navbar mb-1" style="position: sticky;">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="navbar-left-section">
|
<div class="navbar-left-section">
|
||||||
<% if current_login_employee.role != "waiter" %>
|
<% if current_login_employee.role != "waiter" %>
|
||||||
|
|||||||
@@ -50,8 +50,9 @@
|
|||||||
|
|
||||||
/* Payment Options Grid */
|
/* Payment Options Grid */
|
||||||
.payment-grid {
|
.payment-grid {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
flex-direction: column;
|
||||||
|
/* grid-template-columns: repeat(1, 1fr); */
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
}
|
}
|
||||||
@@ -134,139 +135,66 @@
|
|||||||
border-color: #ff4757;
|
border-color: #ff4757;
|
||||||
color: #ff4757;
|
color: #ff4757;
|
||||||
}
|
}
|
||||||
|
.payment-card#read_nfc {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="modal fade payment-modal" id="read_modal" tabindex="-1" role="dialog">
|
<div class="modal fade payment-modal" id="read_modal" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="payment-header">
|
<div class="payment-header">
|
||||||
<h2 class="modal-title">Payment Selection</h2>
|
<h2 class="modal-title">Payment Options</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="payment-grid">
|
<div class="payment-grid">
|
||||||
<!-- Dynamic QR Card -->
|
|
||||||
<div class="payment-card" id="dynamic_qr">
|
<div class="payment-card" id="dynamic_qr">
|
||||||
<div class="payment-icon">⎙</div>
|
<div class="payment-icon text-center">
|
||||||
<div class="payment-label">Dynamic QR</div>
|
<img src="/image/mmqr.webp" width="100" height="100" />
|
||||||
<div class="payment-description">
|
|
||||||
Generate unique QR code for this specific transaction
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="payment-label text-center">Click here to pay with MMQR</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Static QR Card -->
|
<div class="text-center text-bold text-muted">
|
||||||
<div class="payment-card" id="static_qr">
|
(Or)
|
||||||
<div class="payment-icon">⏚</div>
|
|
||||||
<div class="payment-label">Static QR</div>
|
|
||||||
<div class="payment-description">
|
|
||||||
Use pre-registered merchant QR code for payment
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Read NFC Card -->
|
<!-- Read NFC Card -->
|
||||||
<div class="payment-card disabled" style="grid-column: span 2;">
|
<div class="payment-card disabled" id="read_nfc" style="grid-column: span 2;">
|
||||||
<div class="payment-icon">⎔</div>
|
<div class="payment-icon text-center">
|
||||||
<div class="payment-label">NFC Tap</div>
|
<img src="/image/nfc.png" width="100" height="100" />
|
||||||
<div class="payment-description">
|
|
||||||
Tap your NFC-enabled card or device
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="payment-label text-center">Tap your NFC-enabled card or device</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn-cancel" id="close">
|
<button type="button" class="btn-cancel" id="close">
|
||||||
Cancel Payment
|
Cancel
|
||||||
</button>
|
|
||||||
<button type="button" class="btn-proceed">
|
|
||||||
Process
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script defer type="text/javascript">
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
const paymentCards = document.querySelectorAll('.payment-card:not(.disabled)');
|
const paymentCards = document.querySelectorAll('.payment-card:not(.disabled)');
|
||||||
const proceedButton = document.querySelector('.btn-proceed');
|
|
||||||
const cancelButton = document.querySelector('.btn-cancel');
|
const cancelButton = document.querySelector('.btn-cancel');
|
||||||
|
|
||||||
let selectedPaymentMethodId = null;
|
|
||||||
let selectedPaymentMethodLabel = '';
|
|
||||||
const originalProceedButtonText = proceedButton.textContent.trim();
|
|
||||||
function styleProceedButton(enabled) {
|
|
||||||
proceedButton.disabled = !enabled;
|
|
||||||
|
|
||||||
if (enabled) {
|
|
||||||
proceedButton.style.borderColor = '#54A5AF'; // Active/theme color
|
|
||||||
proceedButton.style.color = '#54A5AF';
|
|
||||||
proceedButton.textContent = `Process with ${selectedPaymentMethodLabel}`;
|
|
||||||
} else {
|
|
||||||
// Reset to default styles (defined in CSS) when disabled
|
|
||||||
proceedButton.style.borderColor = ''; // Reverts to stylesheet's .btn-proceed border-color
|
|
||||||
proceedButton.style.color = ''; // Reverts to stylesheet's .btn-proceed color
|
|
||||||
proceedButton.textContent = originalProceedButtonText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initial state: Disable the "Process" button
|
|
||||||
styleProceedButton(false);
|
|
||||||
|
|
||||||
paymentCards.forEach(card => {
|
|
||||||
card.addEventListener('click', function (e) {
|
|
||||||
// If the clicked card is already active, we can either do nothing
|
|
||||||
// or re-affirm the selection. Current logic re-affirms.
|
|
||||||
// This ensures that selectedPaymentMethodLabel is correctly set for the button text.
|
|
||||||
|
|
||||||
// Remove 'active' class from all other payment cards
|
|
||||||
paymentCards.forEach(c => {
|
|
||||||
if (c !== e.currentTarget) {
|
|
||||||
c.classList.remove('active');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add 'active' class to the clicked card
|
|
||||||
e.currentTarget.classList.add('active');
|
|
||||||
|
|
||||||
// Store selected method's ID and Label
|
|
||||||
selectedPaymentMethodId = e.currentTarget.id;
|
|
||||||
selectedPaymentMethodLabel = e.currentTarget.querySelector('.payment-label').textContent.trim();
|
|
||||||
|
|
||||||
// Enable and update the "Process" button
|
|
||||||
styleProceedButton(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
proceedButton.addEventListener('click', function () {
|
|
||||||
if (!this.disabled && selectedPaymentMethodId) {
|
|
||||||
console.log(`Action: Process payment using ${selectedPaymentMethodId}`);
|
|
||||||
|
|
||||||
if (selectedPaymentMethodId === 'dynamic_qr') {
|
|
||||||
initDynamicQrPay()
|
|
||||||
} else if (selectedPaymentMethodId === 'static_qr') {
|
|
||||||
// showStaticQRInstructions();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert("Please select a payment method first.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cancelButton.addEventListener('click', function () {
|
cancelButton.addEventListener('click', function () {
|
||||||
console.log("Action: Cancel payment.");
|
console.log("Action: Cancel payment.");
|
||||||
|
|
||||||
paymentCards.forEach(c => c.classList.remove('active'));
|
paymentCards.forEach(c => c.classList.remove('active'));
|
||||||
selectedPaymentMethodId = null;
|
|
||||||
selectedPaymentMethodLabel = '';
|
|
||||||
|
|
||||||
styleProceedButton(false);
|
styleProceedButton(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
const disabledNfcCard = document.querySelector('.payment-card.disabled');
|
const disabledNfcCard = document.querySelector('.payment-card.disabled');
|
||||||
if (disabledNfcCard) {
|
|
||||||
disabledNfcCard.style.cursor = 'not-allowed';
|
document.querySelector('.payment-card#dynamic_qr').addEventListener('click', function() {
|
||||||
// Add opacity if not already styled to look sufficiently disabled by its class
|
initDynamicQrPay();
|
||||||
if (window.getComputedStyle(disabledNfcCard).opacity === '1') {
|
});
|
||||||
disabledNfcCard.style.opacity = '0.6';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initDynamicQrPay() {
|
function initDynamicQrPay() {
|
||||||
const paymentMethod = 'MMQR';
|
const paymentMethod = 'MMQR';
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<section class="content">
|
<section class="content" style="padding: 0;">
|
||||||
<% flash.each do |type, message| %>
|
<% flash.each do |type, message| %>
|
||||||
<% if type == "notice"
|
<% if type == "notice"
|
||||||
color = "alert-success"
|
color = "alert-success"
|
||||||
|
|||||||
Reference in New Issue
Block a user