astrapay / templates /home.html
GamerC0der's picture
Update templates/home.html
53ee66f verified
raw
history blame
32.5 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AstraPay</title>
<style>
body {
margin: 0;
padding: 0;
min-height: 100vh;
background-color: #000000;
font-family: Arial, sans-serif;
}
.main-content {
margin-top: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
text-align: center;
}
.title {
color: #ffffff;
font-size: 4rem;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.3);
margin-bottom: 2rem;
}
.button {
background-color: #ffffff;
color: #000000;
border: none;
padding: 1rem 2rem;
font-size: 1.2rem;
font-weight: bold;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-block;
}
.button:hover {
background-color: #f0f0f0;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(255, 255, 255, 0.2);
}
.modal {
display: none;
position: fixed;
z-index: 50;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
animation: fadeIn 0.15s ease-out;
}
.modal.show {
display: flex;
align-items: center;
justify-content: center;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideIn {
from {
opacity: 0;
transform: scale(0.96);
}
to {
opacity: 1;
transform: scale(1);
}
}
.modal-content {
background-color: #1a1a1a;
position: relative;
padding: 0;
border-radius: 12px;
width: 90%;
max-width: 500px;
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
animation: slideIn 0.2s ease-out;
display: flex;
flex-direction: column;
max-height: 90vh;
overflow: hidden;
}
.modal-header {
color: #ffffff;
padding: 1.5rem 1.5rem 0 1.5rem;
margin-bottom: 1.5rem;
font-size: 1.25rem;
font-weight: 600;
letter-spacing: -0.01em;
line-height: 1.4;
}
.modal-close {
position: absolute;
right: 1rem;
top: 1rem;
background: transparent;
border: none;
color: rgba(255, 255, 255, 0.7);
cursor: pointer;
padding: 0.5rem;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
width: 32px;
height: 32px;
}
.modal-close:hover {
background-color: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 1);
}
.modal-close:focus {
outline: 2px solid rgba(255, 255, 255, 0.5);
outline-offset: 2px;
}
.modal-close-icon {
width: 16px;
height: 16px;
stroke: currentColor;
stroke-width: 2;
fill: none;
}
.modal-body {
padding: 0 1.5rem 1.5rem 1.5rem;
overflow-y: auto;
}
.form-group {
margin-bottom: 1.25rem;
}
.form-label {
display: block;
color: rgba(255, 255, 255, 0.9);
margin-bottom: 0.5rem;
font-weight: 500;
font-size: 0.875rem;
}
.form-input {
width: 100%;
padding: 0.625rem 0.875rem;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 6px;
background-color: rgba(255, 255, 255, 0.05);
color: #ffffff;
font-size: 0.9375rem;
transition: all 0.2s ease;
box-sizing: border-box;
}
.form-input:focus {
outline: none;
border-color: rgba(255, 255, 255, 0.3);
background-color: rgba(255, 255, 255, 0.08);
}
.form-input::placeholder {
color: rgba(255, 255, 255, 0.4);
}
.form-input-email {
width: 100%;
padding: 0.625rem 0.875rem;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 8px;
background-color: rgba(255, 255, 255, 0.06);
color: #ffffff;
font-size: 0.9375rem;
transition: all 0.3s ease;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
}
.form-input-email:focus {
outline: none;
border-color: rgba(255, 255, 255, 0.4);
background-color: rgba(255, 255, 255, 0.1);
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1);
}
.form-input-email::placeholder {
color: rgba(255, 255, 255, 0.5);
font-style: italic;
}
.form-input-email:hover:not(:focus) {
border-color: rgba(255, 255, 255, 0.25);
background-color: rgba(255, 255, 255, 0.08);
}
.form-textarea {
width: 100%;
padding: 0.625rem 0.875rem;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 6px;
background-color: rgba(255, 255, 255, 0.05);
color: #ffffff;
font-size: 0.9375rem;
min-height: 100px;
resize: vertical;
transition: all 0.2s ease;
box-sizing: border-box;
font-family: inherit;
}
.form-textarea:focus {
outline: none;
border-color: rgba(255, 255, 255, 0.3);
background-color: rgba(255, 255, 255, 0.08);
}
.form-textarea::placeholder {
color: rgba(255, 255, 255, 0.4);
}
.modal-buttons {
display: flex;
gap: 0.75rem;
justify-content: flex-end;
margin-top: 1.5rem;
padding-top: 1.5rem;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.btn-secondary {
background-color: transparent;
color: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(255, 255, 255, 0.2);
padding: 0.625rem 1.25rem;
border-radius: 6px;
cursor: pointer;
font-size: 0.9375rem;
font-weight: 500;
transition: all 0.2s ease;
}
.btn-secondary:hover {
background-color: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.3);
}
.button {
background-color: #ffffff;
color: #000000;
border: none;
padding: 0.625rem 1.25rem;
font-size: 0.9375rem;
font-weight: 500;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
text-decoration: none;
display: inline-block;
}
.button:hover {
background-color: #f0f0f0;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(255, 255, 255, 0.15);
}
.top-banner {
background: rgba(100, 100, 255, 0.15);
border: 1px solid rgba(100, 100, 255, 0.3);
border-radius: 8px;
padding: 0.75rem 1.5rem;
margin-bottom: 2rem;
color: #6464ff;
font-size: 0.9rem;
font-weight: 500;
text-align: center;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
.banner {
background: rgba(255, 193, 7, 0.15);
border: 1px solid rgba(255, 193, 7, 0.3);
border-radius: 8px;
padding: 0.75rem 1.5rem;
margin-bottom: 2rem;
color: #ffc107;
font-size: 0.9rem;
font-weight: 500;
text-align: center;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
.toast-container {
position: fixed;
bottom: 1.5rem;
right: 1.5rem;
z-index: 100;
display: flex;
flex-direction: column;
gap: 0.75rem;
pointer-events: none;
}
.toast {
background-color: #1a1a1a;
color: #ffffff;
padding: 0.875rem 1rem;
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
min-width: 300px;
max-width: 400px;
display: flex;
align-items: center;
gap: 0.75rem;
pointer-events: auto;
animation: toastSlideIn 0.3s ease-out;
font-size: 0.9375rem;
}
.toast.error {
border-color: rgba(239, 68, 68, 0.3);
background-color: rgba(239, 68, 68, 0.1);
}
.toast.success {
border-color: rgba(34, 197, 94, 0.3);
background-color: rgba(34, 197, 94, 0.1);
}
@keyframes toastSlideIn {
from {
opacity: 0;
transform: translateX(100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes toastSlideOut {
from {
opacity: 1;
transform: translateX(0);
}
to {
opacity: 0;
transform: translateX(100%);
}
}
.toast.hiding {
animation: toastSlideOut 0.2s ease-in forwards;
}
.toast-icon {
flex-shrink: 0;
width: 20px;
height: 20px;
}
.toast-message {
flex: 1;
line-height: 1.5;
}
.toast-close {
background: transparent;
border: none;
color: rgba(255, 255, 255, 0.6);
cursor: pointer;
padding: 0.25rem;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
flex-shrink: 0;
}
.toast-close:hover {
background-color: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 1);
}
.toast-close-icon {
width: 16px;
height: 16px;
stroke: currentColor;
stroke-width: 2;
fill: none;
}
</style>
</head>
<body>
<div class="main-content">
<div class="container">
<h1 class="title">AstraPay</h1>
<div class="top-banner">
Contact Matthew on Slack if any issues occur.
</div>
<div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
<button class="button" onclick="openModal()" style="display: flex; align-items: center; gap: 0.5rem;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect>
<line x1="1" y1="10" x2="23" y2="10"></line>
</svg>
Create Payment Link
</button>
<button class="button" onclick="openClaimModal()" style="background-color: rgba(255, 255, 255, 0.9); display: flex; align-items: center; gap: 0.5rem;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 12 20 22 4 22 4 12"></polyline>
<rect x="2" y="7" width="20" height="5"></rect>
<line x1="12" y1="22" x2="12" y2="7"></line>
<path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"></path>
<path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"></path>
</svg>
Create Claim Link
</button>
<button class="button" onclick="openEnterIdModal()" style="background-color: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.3); color: #ffffff; display: flex; align-items: center; gap: 0.5rem;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 21l-6-6m2-5a7 7 0 1 1-14 0 7 7 0 0 1 14 0z"></path>
</svg>
Enter ID
</button>
</div>
</div>
<div id="paymentModal" class="modal">
<div class="modal-content">
<button class="modal-close" onclick="closeModal()" aria-label="Close">
<svg class="modal-close-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M18 6L6 18M6 6l12 12" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div class="modal-header">Create Payment Link</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label" for="astras">Number of Astras</label>
<input type="number" id="astras" class="form-input" min="1" max="10000" placeholder="Enter number of astras" required oninput="validateAstrasAmount(this)">
</div>
<div class="form-group">
<label class="form-label" for="description">Description</label>
<textarea id="description" class="form-textarea" placeholder="Enter payment description" required></textarea>
</div>
<div class="form-group">
<label class="form-label" for="recipient-email">Your AstraNova Email</label>
<input type="email" id="recipient-email" class="form-input-email" placeholder="Enter your AstraNova email" required>
</div>
<div class="modal-buttons">
<button class="btn-secondary" onclick="closeModal()" style="display: flex; align-items: center; gap: 0.5rem;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
Cancel
</button>
<button class="button" onclick="createPaymentLink()" style="display: flex; align-items: center; gap: 0.5rem;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="12" y1="5" x2="12" y2="19"></line>
<line x1="5" y1="12" x2="19" y2="12"></line>
</svg>
Create Link
</button>
</div>
</div>
</div>
</div>
<div id="claimModal" class="modal">
<div class="modal-content">
<button class="modal-close" onclick="closeClaimModal()" aria-label="Close">
<svg class="modal-close-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M18 6L6 18M6 6l12 12" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div class="modal-header">Create Claim Link</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label" for="claim-astras">Number of Astras</label>
<input type="number" id="claim-astras" class="form-input" min="1" max="10000" placeholder="Enter number of astras" required oninput="validateClaimAstrasAmount(this)">
<div style="font-size: 0.8rem; color: rgba(255, 255, 255, 0.6); margin-top: 0.5rem;">
You'll send: <span id="claim-send-amount">-</span> Astras (+1%)<br>
Claimable: <span id="claim-claim-amount">-</span> Astras (-1%)
</div>
</div>
<div class="modal-buttons">
<button class="btn-secondary" onclick="closeClaimModal()" style="display: flex; align-items: center; gap: 0.5rem;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
Cancel
</button>
<button class="button" onclick="createClaimLink()" style="display: flex; align-items: center; gap: 0.5rem;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 12 20 22 4 22 4 12"></polyline>
<rect x="2" y="7" width="20" height="5"></rect>
<line x1="12" y1="22" x2="12" y2="7"></line>
<path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"></path>
<path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"></path>
</svg>
Create Claim Link
</button>
</div>
</div>
</div>
</div>
<div id="enterIdModal" class="modal">
<div class="modal-content">
<button class="modal-close" onclick="closeEnterIdModal()" aria-label="Close">
<svg class="modal-close-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M18 6L6 18M6 6l12 12" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div class="modal-header">Enter Link ID</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label" for="link-id">Enter 4-character code</label>
<input type="text" id="link-id" class="form-input" placeholder="e.g., A3B7" maxlength="4" style="text-transform: uppercase; font-size: 1.2rem; letter-spacing: 0.5rem; text-align: center;" required oninput="this.value = this.value.toUpperCase().replace(/[^A-Z0-9]/g, '')" onkeypress="if(event.key === 'Enter') goToLink()">
</div>
<div class="modal-buttons">
<button class="btn-secondary" onclick="closeEnterIdModal()" style="display: flex; align-items: center; gap: 0.5rem;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
Cancel
</button>
<button class="button" onclick="goToLink()" style="display: flex; align-items: center; gap: 0.5rem;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h14M12 5l7 7-7 7"></path>
</svg>
Go to Link
</button>
</div>
</div>
</div>
</div>
<div id="toastContainer" class="toast-container"></div>
<script>
function showToast(message, type = 'error') {
const container = document.getElementById('toastContainer');
const toast = document.createElement('div');
toast.className = `toast ${type}`;
const iconSvg = type === 'error'
? '<svg class="toast-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>'
: '<svg class="toast-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
toast.innerHTML = `
${iconSvg}
<span class="toast-message">${message}</span>
<button class="toast-close" onclick="this.parentElement.remove()" aria-label="Close">
<svg class="toast-close-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M18 6L6 18M6 6l12 12" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
`;
container.appendChild(toast);
setTimeout(() => {
toast.classList.add('hiding');
setTimeout(() => {
if (toast.parentElement) {
toast.remove();
}
}, 200);
}, 4000);
}
function validateAstrasAmount(input) {
const value = parseInt(input.value);
if (!isNaN(value) && value > 10000) {
input.value = 10000;
showToast('Maximum 10,000 Astras per payment link');
}
}
function openModal() {
const modal = document.getElementById('paymentModal');
modal.style.display = 'flex';
setTimeout(() => {
modal.classList.add('show');
}, 10);
document.body.style.overflow = 'hidden';
}
function closeModal() {
const modal = document.getElementById('paymentModal');
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = 'none';
}, 200);
document.body.style.overflow = '';
document.getElementById('astras').value = '';
document.getElementById('description').value = '';
document.getElementById('recipient-email').value = '';
}
async function createPaymentLink() {
const astras = document.getElementById('astras').value;
const description = document.getElementById('description').value.trim();
const recipientEmail = document.getElementById('recipient-email').value.trim();
if (!astras) {
showToast('Please enter the number of Astras');
document.getElementById('astras').focus();
return;
}
const astrasAmount = parseInt(astras);
if (astrasAmount > 10000) {
showToast('Maximum 10,000 Astras per payment link');
document.getElementById('astras').focus();
return;
}
if (!description) {
showToast('Please enter a description');
document.getElementById('description').focus();
return;
}
if (!recipientEmail) {
showToast('Please enter your AstraNova email');
document.getElementById('recipient-email').focus();
return;
}
try {
const response = await fetch('/create-payment-link', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: astrasAmount,
description: description.trim(),
recipient_email: recipientEmail
})
});
const data = await response.json();
if (response.ok) {
showToast('Payment link created successfully!', 'success');
setTimeout(() => {
window.location.href = data.payment_url;
}, 500);
} else {
showToast('Error creating payment link: ' + data.error);
}
} catch (error) {
showToast('Error creating payment link: ' + error.message);
}
}
function openClaimModal() {
const modal = document.getElementById('claimModal');
modal.style.display = 'flex';
setTimeout(() => {
modal.classList.add('show');
}, 10);
document.body.style.overflow = 'hidden';
}
function closeClaimModal() {
const modal = document.getElementById('claimModal');
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = 'none';
}, 200);
document.body.style.overflow = '';
document.getElementById('claim-astras').value = '';
document.getElementById('claim-send-amount').textContent = '-';
document.getElementById('claim-claim-amount').textContent = '-';
}
function validateClaimAstrasAmount(input) {
const value = parseInt(input.value);
if (!isNaN(value) && value > 0) {
const sendAmount = Math.max(1, Math.floor(value * 1.01));
const claimAmount = Math.max(1, Math.floor(value * 0.99));
document.getElementById('claim-send-amount').textContent = sendAmount;
document.getElementById('claim-claim-amount').textContent = claimAmount;
} else {
document.getElementById('claim-send-amount').textContent = '-';
document.getElementById('claim-claim-amount').textContent = '-';
}
if (!isNaN(value) && value > 10000) {
input.value = 10000;
showToast('Maximum 10,000 Astras per claim link');
}
}
async function createClaimLink() {
const astras = document.getElementById('claim-astras').value;
if (!astras) {
showToast('Please enter the number of Astras');
document.getElementById('claim-astras').focus();
return;
}
const astrasAmount = parseInt(astras);
if (astrasAmount > 10000) {
showToast('Maximum 10,000 Astras per claim link');
document.getElementById('claim-astras').focus();
return;
}
try {
const response = await fetch('/create-claim-link', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: astrasAmount
})
});
const data = await response.json();
if (response.ok) {
showToast('Claim link created successfully!', 'success');
setTimeout(() => {
window.location.href = data.claim_url;
}, 500);
} else {
showToast('Error creating claim link: ' + data.error);
}
} catch (error) {
showToast('Error creating claim link: ' + error.message);
}
}
function openEnterIdModal() {
const modal = document.getElementById('enterIdModal');
modal.style.display = 'flex';
setTimeout(() => {
modal.classList.add('show');
}, 10);
document.body.style.overflow = 'hidden';
document.getElementById('link-id').focus();
}
function closeEnterIdModal() {
const modal = document.getElementById('enterIdModal');
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = 'none';
}, 200);
document.body.style.overflow = '';
document.getElementById('link-id').value = '';
}
async function goToLink() {
const linkId = document.getElementById('link-id').value.trim().toUpperCase();
if (!linkId || linkId.length !== 4) {
showToast('Please enter a valid 4-character code');
document.getElementById('link-id').focus();
return;
}
try {
const response = await fetch(`/check-link/${linkId}`);
const data = await response.json();
if (response.ok && data.exists) {
if (data.type === 'payment') {
window.location.href = `/pay/${linkId}`;
} else if (data.type === 'claim') {
window.location.href = `/claim/${linkId}`;
}
} else {
showToast('Link not found. Please check the code and try again.');
document.getElementById('link-id').focus();
}
} catch (error) {
showToast('Error checking link: ' + error.message);
}
}
window.onclick = function(event) {
const paymentModal = document.getElementById('paymentModal');
const claimModal = document.getElementById('claimModal');
const enterIdModal = document.getElementById('enterIdModal');
if (event.target === paymentModal) {
closeModal();
}
if (event.target === claimModal) {
closeClaimModal();
}
if (event.target === enterIdModal) {
closeEnterIdModal();
}
}
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
const paymentModal = document.getElementById('paymentModal');
const claimModal = document.getElementById('claimModal');
const enterIdModal = document.getElementById('enterIdModal');
if (paymentModal.classList.contains('show')) {
closeModal();
}
if (claimModal.classList.contains('show')) {
closeClaimModal();
}
if (enterIdModal.classList.contains('show')) {
closeEnterIdModal();
}
}
});
</script>
</div>
</body>
</html>