|
|
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/user-head :: head}"></head><style> :root { --bg: #f6f3ef; --accent: #12363b; --dark: #2f1f1b; --muted: #7b7773; --panel-w: 660px; --radius: 14px; }
/* Reset */ * { box-sizing: border-box; margin: 0; padding: 0 }
html, body { height: 100% }
body { font-family: "Inter", "Helvetica Neue", Arial, sans-serif;
background: linear-gradient(rgba(255, 255, 255, 0.70), rgba(255, 255, 255, 0.82)), url('/victoriapublichall/images/vph-background_v1.jpg') top center / cover no-repeat, url('/victoriapublichall/images/vph-background_v1.jpg') bottom center / cover no-repeat;
min-height: 100vh; background-attachment: fixed; /* keeps both images static */ background-repeat: no-repeat; background-size: cover;
-webkit-font-smoothing: antialiased; min-height: 100vh;
display: flex; flex-direction: column; gap: 12px; padding: 18px 24px; }
/* Mobile view image should be FULL COVER, NO REPEAT */ @media (max-width: 520px) { body { background: linear-gradient(rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0.90)), url('/victoriapublichall/images/vph-background_v1.jpg');
background-size: 100em; /* full cover */ background-repeat: no-repeat; background-position: center center; background-attachment: scroll; /* prevents weird zooming on mobile */
/* remove second image on mobile */ } }
/* container */ .container { width: 100%; max-width: 1200px; margin: 0 auto; }
/****************************** NAVBAR (desktop + mobile) ******************************/ .topbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 10px 0; position: relative; z-index: 1300; }
.leftbar { display: flex; align-items: center; gap: 20px; }
/* small logo + layout helpers */ .nav-left { display: flex; align-items: center; gap: 12px; }
.logo { width: 72px; height: 72px; object-fit: contain; border-radius: 50%; }
/* default desktop nav */ nav.primary { display: flex; gap: 18px; align-items: center; }
/* Desktop Navigation Links (Figma Accurate) */ nav.primary a { font-family: "Playfair Display", serif !important; font-weight: 400 !important; /* Regular */ font-style: normal !important; font-size: 15px !important; /* Figma size */ line-height: 100% !important; letter-spacing: 0 !important;
color: #3C1E12; /* matches Book a Visit color */ text-decoration: none;
padding: 6px 8px; /* keep your layout spacing */ border-radius: 6px;
transition: background 0.2s ease; }
/* Hover state (optional subtle effect like Figma preview) */ nav.primary a:hover { background: rgba(0, 0, 0, 0.06); color: #3C1E12; /* no change in color */ }
/* Mobile menu links */ .mobile-nav a { font-family: "Playfair Display", serif !important; font-weight: 400 !important; font-size: 15px !important; letter-spacing: 0 !important; color: #3C1E12; }
.rightbar { display: flex; align-items: center; gap: 12px; }
/* desktop CTA (Book a Visit) */
/* Desktop CTA (Book a Visit) — Updated with Figma specs */
/* Desktop CTA (Book a Visit) — With Figma Border */ #desktopBookBtn { width: 174px; /* Figma button width */ height: 57px; /* Figma button height */ display: inline-flex; align-items: center; justify-content: center;
background: transparent; border-radius: 8px; /* Figma corner radius */
/* Border from Figma (thin outline) */ border: 1px solid rgba(60, 30, 18, 0.40); /* darker visible border */
cursor: pointer;
/* Figma Typography */ font-family: "Playfair Display", serif !important; font-weight: 700 !important; /* Bold */ font-style: italic !important; font-size: 24px !important; line-height: 100% !important;
/* Letter spacing -6% = -0.06em */ letter-spacing: -0.06em !important;
color: #3C1E12 !important; }
/* Hover effect (Figma-like subtle shadow) */ #desktopBookBtn:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.10); }
/* Keep existing responsive behavior */ @media (max-width: 900px) { nav.primary { display: none !important; }
#desktopBookBtn { display: none !important; }
.hamburger { display: flex !important; }
/* Mobile logo size */ .logo { width: 44px; height: 44px; } }
/* hamburger (hidden on desktop) */ .hamburger { display: none; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 8px; border: 1px solid rgba(0, 0, 0, 0.06); background: transparent; cursor: pointer; padding: 8px; }
.hamburger .bar { display: block; width: 18px; height: 2px; background: var(--dark); margin: 3px 0; transition: transform .2s, opacity .2s; }
/* mobile floating menu + overlay (initial hidden) */ .mobile-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.22); z-index: 1350; opacity: 0; pointer-events: none; transition: opacity .22s ease; }
.mobile-overlay.show { opacity: 1; pointer-events: auto; }
.mobile-nav { position: fixed; left: 12px; right: 12px; top: 68px; max-width: 420px; margin: 0 auto; background: #fff; border-radius: 12px; padding: 14px; box-shadow: 0 22px 60px rgba(0, 0, 0, 0.16); border: 1px solid rgba(0, 0, 0, 0.06); z-index: 1400; transform: translateY(-8px) scale(.995); opacity: 0; pointer-events: none; transition: opacity .22s ease, transform .22s ease; }
.mobile-nav.open { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.mobile-nav a { display: block; padding: 10px 12px; color: var(--dark); text-decoration: none; border-radius: 8px; font-weight: 600; }
.mobile-nav a+a { margin-top: 8px; }
.mobile-nav .book-cta { background: #f7f9f9; text-align: center; padding: 12px; color: var(--accent); font-weight: 700; }
/* small screens tweak */ @media (max-width:520px) { .logo { width: 61px !important; /* Figma width */ height: 61px !important; /* Figma height */ object-fit: contain; }
.mobile-nav { left: 12px; right: 12px; top: 68px; max-width: 420px; margin: 0 auto; background: #fff; border-radius: 12px; padding: 14px; box-shadow: 0 22px 60px rgba(0, 0, 0, 0.16); border: 1px solid rgba(0, 0, 0, 0.06); z-index: 1400; transform: translateY(-8px) scale(.995); opacity: 0; pointer-events: none; transition: opacity .22s ease, transform .22s ease; } }
/****************************** PAGE / HERO / PANEL ******************************/ .page { width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; margin-top: 20px; }
.panel-wrap { width: 100%; display: flex; justify-content: center; align-items: center; margin-top: 18px; }
.hero { width: 100%; max-width: 920px; text-align: center; margin-bottom: 12px; }
/* Desktop style */ .page h1 { font-family: "Inter", sans-serif; font-weight: 700; font-style: normal; font-size: 48px; line-height: 100%; letter-spacing: 0; text-align: center;
width: 100%; max-width: 444px; /* Figma width */ margin: 0 auto 10px; /* Center + bottom spacing */ color: #3B1E14 !important; }
/* Mobile view */ @media (max-width:520px) { .page h1 { font-family: "Inter", sans-serif; font-weight: 700; font-style: normal;
font-size: 32px !important; /* Figma size */ line-height: 100% !important; /* Figma line height */ letter-spacing: 0;
width: 296px; /* Figma width */ max-width: 90%; /* Responsive safety */ margin: 0 auto; /* Center horizontally */
text-align: center; /* Figma alignment */ color: #3B1E14 !important; /* Requested color */ } }
/* Desktop version */ .hero .lead { font-family: "Inter", sans-serif; font-weight: 400; font-style: normal; font-size: 20px; line-height: 100%; letter-spacing: 0; text-align: center;
width: 100%; max-width: 417px; /* From Figma */ margin: 0 auto 20px; /* Center + spacing */ color: #000000; /* BLACK COLOR as requested */ }
/* Mobile version */ @media (max-width:520px) { .hero .lead { font-family: "Inter", sans-serif; font-weight: 400; font-style: normal;
font-size: 14px !important; /* Figma size */ line-height: 100% !important; /* Figma line height */ letter-spacing: 0;
width: 275px; /* Figma width */ max-width: 90%; /* keep responsive */ margin: 0 auto 20px; /* center align */
text-align: center; /* Figma alignment */ color: #000000 !important; /* Text color */ } }
/* Desktop version */ .panel h3 { font-family: "Inter", sans-serif; font-weight: 700; /* bold */ font-style: normal; font-size: 20px; line-height: 100%; letter-spacing: 0; text-align: center; color: #000000; /* BLACK TEXT */
width: 100%; max-width: 336px; /* Figma width */ margin: 0 auto 14px; /* center + bottom spacing */ }
/* Mobile version */ @media (max-width:520px) { .panel h3 { font-size: 24px; /* slightly smaller */ max-width: 120%; line-height: 140%; } }
/* Desktop version */ .muted-label { font-family: "Inter", sans-serif; font-weight: 700; font-style: normal; font-size: 16px; line-height: 100%; letter-spacing: 0; color: #3B1E14;
width: 100%; max-width: 100%; margin-bottom: 8px;
text-align: left; display: block;
margin-left: 40px !important; /* ⬅ FIXES CENTER ISSUE */ }
/* Mobile version */ @media (max-width:520px) { .muted-label { font-size: 16px; max-width: 1400%; line-height: 140%; text-align: left; margin-left: 0 !important; /* keep left */ } }
/* Desktop version */ .input { width: 100%; max-width: 536px; /* Figma width */ padding: 16px 18px; /* creates approx 65px height */ border-radius: 14px; /* Figma radius */ border: 1px solid rgba(0, 0, 0, 0.06); background: #ffffff; font-family: "Inter", sans-serif; font-size: 16px; outline: none; box-sizing: border-box; }
/* Focus glow */ .input:focus { box-shadow: 0 8px 26px rgba(20, 30, 30, 0.04); border-color: rgba(0, 0, 0, 0.14); }
/* Mobile version */ @media (max-width:520px) { .input { max-width: 140%; line-height: 140%; padding: 16px 18px; /* better fit on mobile */ border-radius: 12px; } }
/* Desktop version */ .btn { width: 100%; max-width: 536px; /* Figma width */ padding: 18px 20px; /* visual height approx 66px */ border-radius: 11px; /* Figma radius */
background: var(--accent); /* your theme greenish color */ color: #ffffff; font-family: "Inter", sans-serif; font-weight: 700; font-size: 16px;
border: none; cursor: pointer; box-shadow: 0 8px 26px rgba(18, 54, 59, 0.12);
transition: none !important; /* Animate: Instant */ }
/* Disabled version */ .btn[disabled] { opacity: .6; cursor: not-allowed; box-shadow: none; }
/* Mobile version */ @media (max-width:520px) { .btn { max-width: 140%; line-height: 140%; padding: 16px 18px; /* smaller height on mobile */ border-radius: 12px; font-size: 18px; } }
.links-row { width: 100%; max-width: 536px; display: flex; justify-content: space-between; /* pushes them to opposite sides */ align-items: center; margin: 8px auto 0; /* center align inside panel */ padding: 0 4px; /* small spacing for balance */ }
/* Change phone/email */ .changeLinkrow a { font-family: "Inter", sans-serif; font-size: 16px; font-weight: 400; line-height: 100%; color: #0478D0; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; cursor: pointer; transition: none !important; }
.changeLinkrow a.disabled { color: rgb(0, 128, 192) !important; pointer-events: none; }
/* Resend OTP */ .resendLinkrow { text-align: right; }
.resendLinkrow a { font-family: "Inter", sans-serif; font-size: 16px; font-weight: 400; line-height: 100%; color: #0478D0; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; cursor: pointer; transition: none !important; }
.resendLinkrow a.disabled { color: #0478D0; pointer-events: none; }
.otp-input { width: 536px; /* height: 65px; */ max-width: 100%; /* keeps it responsive on mobile */
padding: 16px 18px; border-radius: 14px; /* Figma: Radius 14px */
background: #ffffff; border: 1px solid rgba(0, 0, 0, 0.06);
font-family: "Inter", sans-serif; font-size: 20px; /* OTP input usually bigger for readability */ font-weight: 400; line-height: 100%;
outline: none; box-sizing: border-box; }
/* Focus effect (same style as your other inputs) */ .otp-input:focus { border-color: rgba(0, 0, 0, 0.12); box-shadow: 0 8px 26px rgba(20, 30, 30, 0.04); }
/* Mobile View – make it fit screen */ @media (max-width: 520px) { .otp-input { max-width: 140%; line-height: 140%; padding: 16px 18px; width: 100%; height: 55px; font-size: 18px; border-radius: 12px; } }
.panel { width: 100%; max-width: var(--panel-w);
/* GLASS EFFECT PANEL */ background: rgba(255, 255, 255, 0);
border-radius: var(--radius); padding: 26px;
border: 1px solid rgba(255, 255, 255, 0);
}
</style>
<body> <div class="container"> <!-- ============================
NAVBAR: REPLACE/EDIT HERE (Brand + desktop nav + CTA; mobile hamburger + menu below) ============================ --> <!-- NAVBAR (replace your existing header / mobile nav markup with this) --> <header class="topbar" role="banner"> <div class="leftbar"> <div class="nav-left"> <!-- logo image — use same img src you already have --> <img th:src="@{images/VPH-logo_main-EN 1.png}" alt="VPH logo" class="logo"> </div>
<!-- desktop nav (hidden on mobile) --> <nav class="primary" aria-label="Primary navigation"> <a href="/victoriapublichall/home">Home</a> <a href="#">About VPH</a> <a href="/victoriapublichall/visit">Visit</a> <a href="#">Contact Us</a> </nav> </div>
<!-- right side: hamburger (mobile) + desktop CTA --> <div class="rightbar"> <button id="hambtn" class="hamburger" aria-label="Open menu" aria-expanded="false" aria-controls="mobileNav"> <span class="bar bar1" aria-hidden="true"></span> <span class="bar bar2" aria-hidden="true"></span> <span class="bar bar3" aria-hidden="true"></span> </button>
</div> </header>
<!-- overlay (click to close) --> <div id="mobileOverlay" class="mobile-overlay" aria-hidden="true"></div>
<!-- mobile nav --> <nav id="mobileNav" class="mobile-nav" aria-hidden="true" role="dialog" aria-modal="true" aria-label="Mobile menu"> <a href="/victoriapublichall/home">Home</a> <a href="#">About VPH</a> <a href="/victoriapublichall/visit">Visit</a> <a href="#">Contact Us</a>
</nav>
<!-- ============================
PAGE CONTENT (HERO + OTP PANEL) ============================ --> <main class="page" role="main" aria-labelledby="hero-heading"> <div class="hero"> <h1 id="hero-heading">Victoria Public Hall</h1> <div class="lead">Experience Chennai's First Town Hall</div>
<div class="panel-wrap"> <div class="panel" role="region" aria-label="OTP booking panel"> <h3>Book your visit / Manage Bookings</h3> <br>
<span class="muted-label" for="contactInput">Enter phone number or email to proceed</span>
<!-- initial input --> <div id="input-block"> <input id="contactInput" class="input" type="text" inputmode="text" placeholder="Phone | Email" autocomplete="off" aria-label="Phone or Email"> <div style="height:12px"></div> <button id="sendBtn" class="btn" type="button">Send OTP</button> </div>
<!-- after-send block --> <div id="sent-block" style="display:none"> <input id="contactInputDisabled" class="input" type="text" disabled> <div style="height:8px"></div> <button id="sendBtnDisabled" class="btn" disabled>Send OTP</button>
<div class="links-row" style="margin-top:8px"> <div class="changeLinkrow"> <a href="#" id="changeLink">Change phone/email</a> </div> <div class="resendLinkrow"> <a href="#" id="resendLink" class="disabled">Resend OTP</a> </div> </div>
<div class="otp-area" id="otpArea" aria-hidden="true"> <span class="muted-label" for="otpInput" style="margin-top:12px">Enter OTP</span> <input id="otpInput" class="otp-input" type="text" maxlength="5" placeholder="Enter OTP" aria-label="OTP"> <div style="height:12px"></div> <button id="submitOtpBtn" class="btn" type="button">Submit</button> </div>
</div> </div> </div>
</div> </main> </div> <div id="pageLoader" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.8); z-index: 9999; text-align: center;"> <div style="position: relative; top: 50%; transform: translateY(-50%);"> <div class="spinner-border text-primary" style="width: 3rem; height: 3rem;"></div> <p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p> </div> </div>
<script th:replace="~{fragments/user-script :: script}"></script>
<script>
$(document).ready(function () { $('#otpInput').on('input', function () { // Allow only digits this.value = this.value.replace(/\D/g, '');
// Max 10 digits if (this.value.length > 5) { this.value = this.value.slice(0, 5); } }); });
/* ======================== MOBILE NAV (improved) ======================== */ (function () { const hambtn = document.getElementById('hambtn'); const mobileNav = document.getElementById('mobileNav'); const mobileOverlay = document.getElementById('mobileOverlay'); const desktopBook = document.getElementById('desktopBookBtn'); const mobileBook = document.getElementById('mobileBook');
if (!hambtn || !mobileNav || !mobileOverlay) { // nothing to do if elements missing } else { function openMenu() { hambtn.setAttribute('aria-expanded', 'true'); mobileNav.classList.add('open'); mobileNav.setAttribute('aria-hidden', 'false'); mobileOverlay.classList.add('show'); mobileOverlay.setAttribute('aria-hidden', 'false'); document.body.style.overflow = 'hidden'; const first = mobileNav.querySelector('a'); if (first) first.focus(); } function closeMenu() { hambtn.setAttribute('aria-expanded', 'false'); mobileNav.classList.remove('open'); mobileNav.setAttribute('aria-hidden', 'true'); mobileOverlay.classList.remove('show'); mobileOverlay.setAttribute('aria-hidden', 'true'); document.body.style.overflow = ''; hambtn.focus(); }
hambtn.addEventListener('click', () => { const isOpen = hambtn.getAttribute('aria-expanded') === 'true'; if (isOpen) closeMenu(); else openMenu(); });
mobileOverlay.addEventListener('click', closeMenu);
document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && mobileNav.classList.contains('open')) closeMenu(); });
mobileNav.querySelectorAll('a').forEach(a => { a.addEventListener('click', () => { // close after clicking any mobile link closeMenu(); }); });
// ensure menu closes when resizing to desktop window.addEventListener('resize', () => { if (window.innerWidth > 900 && mobileNav.classList.contains('open')) closeMenu(); }); }
// Optional: wire desktop Book a Visit to the same booking action as mobile if (desktopBook && mobileBook) { desktopBook.addEventListener('click', (e) => { e.preventDefault(); // mimic mobile behavior for demo: show alert (replace with real action) alert('Book a Visit clicked — open booking flow here.'); }); mobileBook.addEventListener('click', (e) => { // mobile link closes menu via handler above and then can navigate or open booking flow // if you want to override, uncomment below // e.preventDefault(); alert('Mobile Book clicked (replace with action).'); }); } })();
/* ======================== OTP PANEL (demo logic) - start timer only on explicit Resend click ======================== */ (function () { const contactInput = document.getElementById('contactInput'); const sendBtn = document.getElementById('sendBtn'); const sentBlock = document.getElementById('sent-block'); const inputBlock = document.getElementById('input-block'); const contactInputDisabled = document.getElementById('contactInputDisabled'); const sendBtnDisabled = document.getElementById('sendBtnDisabled'); const changeLink = document.getElementById('changeLink'); const resendLink = document.getElementById('resendLink'); const otpArea = document.getElementById('otpArea'); const otpInput = document.getElementById('otpInput'); const submitOtpBtn = document.getElementById('submitOtpBtn');
let resendTimer = null; let secondsLeft = 0; const RESEND_DELAY = 30; // seconds
function isEmail(text) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(text); } function isPhone(text) { const digits = text.replace(/\D/g, ''); return digits.length === 10; // EXACT 10 digits only } function isValidContact(text) { if (!text) return false; const trimmed = text.trim(); return isEmail(trimmed) || isPhone(trimmed); }
function setResendDisabled(state) { if (!resendLink) return; if (state) { resendLink.classList.add('disabled'); resendLink.setAttribute('aria-disabled', 'true'); resendLink.style.pointerEvents = 'none'; } else { resendLink.classList.remove('disabled'); resendLink.removeAttribute('aria-disabled'); resendLink.style.pointerEvents = ''; resendLink.textContent = 'Resend OTP'; } }
function startResendCountdown(sec = RESEND_DELAY) { if (!resendLink) return; if (resendTimer) { clearInterval(resendTimer); resendTimer = null; } secondsLeft = sec; // lock the resend link and show countdown setResendDisabled(true); resendLink.textContent = `Resend OTP (${secondsLeft}s)`; resendTimer = setInterval(() => { secondsLeft--; if (secondsLeft <= 0) { clearInterval(resendTimer); resendTimer = null; setResendDisabled(false); } else { resendLink.textContent = `Resend OTP (${secondsLeft}s)`; } }, 1000); }
function demoSendOtp(contact) {
$.ajax({ type: "GET", url: '/victoriapublichall/otpapi/send-otp', data: { 'userInput': contact }, success: function (response) { if (response.status === "success") {
if (otpArea) { otpArea.style.display = 'block'; otpArea.setAttribute('aria-hidden', 'false'); } if (otpInput) { otpInput.value = ''; setTimeout(() => otpInput.focus(), 120); } startResendCountdown(); } else if (response === "error") {
Swal.fire({ icon: 'warning', title: 'Error', text: 'Invalid Mobile Number or Email ID.', }); return; } else { Swal.fire({ icon: 'warning', title: 'Error', text: 'Error in OTP', }); return; } }, error: function () { alert("Error While Sending OTP."); } });
}
function showSentState(contact) { inputBlock.style.display = 'none'; inputBlock.setAttribute('aria-hidden', 'true'); sentBlock.style.display = 'block'; sentBlock.setAttribute('aria-hidden', 'false'); if (contactInputDisabled) contactInputDisabled.value = contact; if (sendBtnDisabled) sendBtnDisabled.disabled = true; // ensure resend link is enabled for the user to click (timer will only start on explicit click) setResendDisabled(false); }
// Send OTP (initial send) if (sendBtn) { sendBtn.addEventListener('click', () => { const raw = (contactInput && contactInput.value) ? contactInput.value.trim() : ''; // If only digits -> treat as phone if (/^\d+$/.test(raw) && raw.length !== 10) { // alert('Mobile number must be exactly 10 digits.'); Swal.fire({ icon: 'warning', title: 'Validation Error', text: 'Mobile number must be exactly 10 digits.', }); contactInput.focus(); return; } if (!isValidContact(raw)) { // alert('Enter a valid 10-digit phone number or email.'); Swal.fire({ icon: 'warning', title: 'Validation Error', text: 'Enter a valid 10-digit phone number or email.', }); contactInput.focus(); return; }
showSentState(raw); // demo send OTP - do NOT start countdown here per requirement demoSendOtp(raw); document.getElementById('otpArea').scrollIntoView({ behavior: 'smooth', block: 'start' }); }); }
// Resend OTP - only starts countdown when user explicitly clicks Resend if (resendLink) { resendLink.addEventListener('click', (e) => { e.preventDefault(); if (resendLink.classList.contains('disabled')) return; // safety const to = (contactInputDisabled && contactInputDisabled.value) ? contactInputDisabled.value : (contactInput && contactInput.value ? contactInput.value : ''); if (!to) return; if (/^\d+$/.test(to) && to.length !== 10) { // alert('Mobile number must be exactly 10 digits.'); Swal.fire({ icon: 'warning', title: 'Validation Error', text: 'Mobile number must be exactly 10 digits.', });
return; } if (!isValidContact(to)) { // alert('Enter a valid 10-digit phone number or email.'); Swal.fire({ icon: 'warning', title: 'Validation Error', text: 'Enter a valid 10-digit phone number or email.', });
return; } // send new OTP and start the countdown now demoSendOtp(to); startResendCountdown(); }); }
// Change link: go back to input state and reset if (changeLink) { changeLink.addEventListener('click', (e) => { e.preventDefault(); if (resendTimer) { clearInterval(resendTimer); resendTimer = null; } setResendDisabled(false); sentBlock.style.display = 'none'; sentBlock.setAttribute('aria-hidden', 'true'); inputBlock.style.display = 'block'; inputBlock.setAttribute('aria-hidden', 'false'); if (contactInput) contactInput.focus(); if (otpArea) { otpArea.style.display = 'none'; otpArea.setAttribute('aria-hidden', 'true'); } if (otpInput) otpInput.value = ''; if (contactInput) contactInput.value = '';
}); }
// Submit OTP if (submitOtpBtn) { submitOtpBtn.addEventListener('click', () => { const otp = otpInput ? otpInput.value.trim() : ''; const userInput = (contactInputDisabled && contactInputDisabled.value) ? contactInputDisabled.value : (contactInput && contactInput.value ? contactInput.value : ''); if (!otp) { Swal.fire({ icon: 'warning', title: 'Missing OTP', text: 'Please Enter OTP', }); otpInput.focus(); return; }
if (!userInput) { Swal.fire({ icon: 'warning', title: 'Missing Phone Number Or Email', text: 'Please Enter Phone Number Or Email', }); otpInput.focus(); return; }
/* if(otp === currentOtp){ // demo success behavior: you can replace this with a redirect or server call setTimeout(()=> { alert('OTP verified (demo). You can now proceed to bookings.'); // optional: automatically switch back to input or navigate // here we simulate closing the OTP flow (reset) changeLink.click(); }, 700); } else { alert('Invalid OTP. Please try again.'); otpInput.focus(); } */
$.ajax({ type: "GET", url: '/victoriapublichall/otpapi/verifyOTP', data: { 'otp': otp, 'userInput': userInput }, success: function (response) {
console.log("API Response:", response);
// Success case if (response.verifiedotp === "success") {
Swal.fire({ icon: 'success', title: response.message, //text: 'Click OK to continue', showConfirmButton: false, timer: 2000, allowOutsideClick: false, allowEscapeKey: false
}).then(() => {
console.log("Booking Details: ", response.regDetails);
let hasBooking = false; let hasuser = response.userInput;
// regDetails is an array → check if contains items if (response.regDetails && typeof response.regDetails === "object" && !Array.isArray(response.regDetails)) { hasBooking = true; console.log("step1"); }
// regDetails is a string (No booking found) → treat as NO booking else if (typeof response.regDetails === "string") { hasBooking = false; console.log("step2"); }
sessionStorage.setItem("hasBooking", hasBooking); sessionStorage.setItem("hasuser", hasuser); sessionStorage.setItem("bookingdetails", JSON.stringify(response.regDetails)); //sessionStorage.setItem("bookingdetails", response.regDetails);
// Redirect with the correctly determined flag //window.location.href = "/victoriapublichall/registerbook?active=" + hasBooking+"user="+hasuser;
window.location.href = "/victoriapublichall/registerbook"; $('#pageLoader').show();
});
} // Error case returned as 200 OK (badRequest still JSON) else if (response.verifiedotp === "error") {
Swal.fire({ icon: 'error', title: 'Invalid OTP', text: response.message }); } }, error: function (xhr) {
console.log("Error Response:", xhr);
let msg = "Something went wrong";
// Extract JSON error response try { let err = JSON.parse(xhr.responseText); msg = err.message; } catch (e) { msg = "Server error. Try again."; }
Swal.fire({ icon: 'error', title: 'Error', text: msg }); } });
}); }
// keyboard shortcuts if (contactInput) contactInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') sendBtn.click(); }); if (otpInput) otpInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') submitOtpBtn.click(); });
// input smoothing: if user types digits only, limit to 10 digits (for phone) if (contactInput) { contactInput.addEventListener('input', () => { if (/^\d*$/.test(contactInput.value)) { contactInput.value = contactInput.value.replace(/\D/g, '').slice(0, 10); } }); }
})();
</script>
</body>
</html>
|