|
|
<!doctype html><html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/user-head :: head}"></head><!-- <meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" /><title>Victoria Public Hall — Booking</title><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;800&family=Playfair+Display:ital,wght@0,400;0,700;1,700&display=swap" rel="stylesheet"> --><style> :root { --accent: #12363b; --muted: #6b6b6b; --card-bg: #ffffff; --slot-radius: 10px; --green-start: #16a34a; --green-end: #09905a; }
* { 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; }
/* 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; }
/* ---------- Navbar styles (desktop + mobile behaviour) ---------- */ /* keep your existing desktop styles; add / replace these responsive bits */
/* 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) — 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); }
/* 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; }
/****************************** 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; }
/* 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 */ }
/* ========== Confirmation / cards styles ========== */
/* Booking Confirmed Title — applies ONLY to this h1 */ h1.booking-confirmed { width: 313px; height: 39px;
font-family: "Inter", sans-serif; font-weight: 700; font-size: 32px; line-height: 100%; letter-spacing: 0; text-align: center;
color: #0CBC47 !important; /* force green color */ margin: 0 auto; display: block; }
/* Booking details subtitle — ONLY for this h2 */ h3.booking-subtitle {
font-family: "Inter", sans-serif;
font-size: 12px; /* Size */ line-height: 11px; /* Figma line height */ letter-spacing: 0;
text-align: center; /* Center aligned */ color: #000000; /* Black text */
}
.grid { display: grid; grid-template-columns: 1fr; gap: 16px; justify-items: center; margin: 10px 0 24px; }
.summary-card { Width: 536px; Height: 114px; background: var(--card-bg); border-radius: 10px; box-shadow: 0 10px 24px rgba(7, 25, 30, 0.06); padding: 18px; border: 1px solid rgba(0, 0, 0, 0.03); text-align: left; }
.av-card { Width: 536px; background: var(--card-bg); border-radius: 10px; box-shadow: 0 10px 24px rgba(7, 25, 30, 0.06); padding: 18px; border: 1px solid rgba(0, 0, 0, 0.03); text-align: left; }
.summary-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.summary-left { width: 60%; color: var(--muted); font-size: 14px; display: flex; flex-direction: column; gap: 12px; }
.summary-left .label { font-weight: 700; color: black !important; font-size: 13px; }
.summary-right { width: 40%; text-align: right; font-weight: 400; color: #0b0b0b; font-size: 14px; display: flex; flex-direction: column; gap: 12px; align-items: flex-end; }
.av-box { margin-top: 12px; padding: 12px; max-height: 160px; overflow-y: auto; padding-right: 6px; }
.av-title { font-weight: 700; margin-bottom: 8px; color: #222; font-size: 14px; }
.av-list { display: flex; flex-direction: column; gap: 8px; }
.av-row { display: flex; justify-content: space-between; align-items: center; padding: 6px 8px; border-radius: 6px; background: transparent; }
.av-time { font-weight: 400; color: #0b0b0b; }
.av-seats { color: #0b0b0b; font-size: 13px; }
.gbm-wrap { margin-top: 22px; text-align: center; }
.gbm { Width: 536px; display: inline-block; padding: 16px 40px; background: #043B55; color: #fff; border-radius: 10px; border: none; font-weight: 700; text-decoration: none; cursor: pointer; box-shadow: 0 8px 26px rgba(4, 59, 69, 0.12); margin-bottom: 10px; }
.secondary-link { display: inline-block; margin-top: 12px; font-size: 14px; color: var(--muted); text-decoration: underline; cursor: pointer; background: transparent; border: none; }
/* ===== Final mobile override — place LAST in your CSS (<=520px) ===== */ @media (max-width: 520px) {
/* page / body */ body { padding: 12px 10px; background-position: center top; background-size: cover; -webkit-font-smoothing: antialiased; }
/* container & panels */ .container, .panel-wrap, .page { width: 100%; max-width: 420px; margin: 0 auto; padding: 0 8px; box-sizing: border-box; }
/* header / nav */ .logo { width: 61px; height: 61px; }
nav.primary { display: none !important; }
#desktopBookBtn { display: none !important; }
.hamburger { display: flex !important; }
/* hero */ .page h1 { font-size: 32px !important; width: 100%; max-width: 360px; margin: 6px auto 8px; }
.hero .lead { font-size: 14px !important; max-width: 320px; margin-bottom: 12px; }
.panel-wrap { padding: 6px 0 18px; }
/* Book-grid / confirmation block — force centered and full width */ .grid, .book-grid { width: 100% !important; max-width: 420px !important; margin: 8px auto 18px !important; gap: 10px !important; padding: 0 8px !important; box-sizing: border-box !important; justify-items: center !important; }
/* Booking Confirmed title */ h1.booking-confirmed { width: 100% !important; max-width: 420px !important; font-family: "Inter", sans-serif !important; font-weight: 700 !important; font-size: 28px !important; line-height: 34px !important; height: auto !important; color: #0CBC47 !important; margin: 6px auto 0 !important; text-align: center !important; }
/* subtitle beneath booking title */ .book-grid p { width: 100% !important; max-width: 420px !important; font-family: "Inter", sans-serif !important; font-weight: 400 !important; font-size: 15px !important; line-height: 20px !important; margin: 4px auto 0 !important; color: #000 !important; text-align: center !important; }
/* Summary / cards: full width stacking */ .summary-card, .av-card, .card, .summary-box, .vph-summary-box { width: 100% !important; max-width: 100% !important; padding: 14px !important; border-radius: 10px !important; box-sizing: border-box !important; }
/* AV list */ .av-box { margin-top: 10px !important; padding: 10px !important; max-height: 160px !important; overflow-y: auto !important; }
.av-list { max-height: unset !important; overflow-y: visible !important; gap: 8px !important; }
.av-row { padding: 8px 6px !important; }
/* Buttons and CTAs: full width, touch-friendly */ .gbm, .btn, .vph-modal-submit, .modal-submit { width: 100% !important; max-width: 100% !important; padding: 12px 16px !important; box-sizing: border-box !important; font-size: 16px !important; border-radius: 12px !important;
}
/* Modals: stretch to comfortable mobile size */ .vph-modal, .modal { width: 94% !important; padding: 14px !important; max-height: 92vh !important; border-radius: 12px !important; }
.vph-summary-box, .vph-av-box, .summary-box { height: auto !important; padding: 12px !important; }
.vph-modal-submit, .modal-submit { width: 100% !important; padding: 12px 14px !important; }
/* small tweaks */ .preview-note-box, .summary-item, .muted, .people-support { font-size: 13px !important; line-height: 1.35 !important; }
.time-ranges { overflow-x: auto !important; -webkit-overflow-scrolling: touch !important; gap: 8px !important; padding-bottom: 8px !important; }
.time-ranges::-webkit-scrollbar { display: none; }
.logo { width: 61px !important; height: 61px !important; }
/* extra small screens */ @media (max-width: 360px) { h1.booking-confirmed { font-size: 24px !important; line-height: 30px !important; }
h2.booking-subtitle, h3.booking-subtitle { font-size: 14px !important; line-height: 18px !important; }
.gbm { padding: 12px !important; font-size: 15px !important; } } }
.panel { background: transparent; }</style><!-- </head> -->
<body> <div class="container"> <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>
<main class="page" role="main" aria-labelledby="hero-heading"> <div class="hero" aria-hidden="false"> <h1 id="hero-heading">Victoria Public Hall</h1> <div class="lead">Experience Chennai's First Town Hall</div> </div>
<div class="panel-wrap"> <div class="panel" role="region" aria-label="Booking panel">
<div class="grid"> <div class="book-grid" aria-hidden="false"> <h1 class="booking-confirmed">Booking Confirmed!</h1> <br> <p>Your booking details has been sent to your phone/email</p> </div>
<div class="summary-card" aria-live="polite"> <div class="summary-row"> <div class="summary-left"> <div class="label">Visiting on</div> <div class="label">Time</div> <div class="label">Total Guest(s)</div> </div> <div class="summary-right"> <div id="confirmDate"></div> <div id="confirmRange"></div> <div id="confirmPeople"></div> </div> </div> </div>
<div class="av-card"> <div class="av-title">AV Experience</div> <div class="av-box"> <div id="confirmAvList" class="av-list">
</div> </div> </div>
</div>
<div class="gbm-wrap"> <a href="/victoriapublichall/register" class="gbm" id="goBackBtn">Go back to main page</a> <!-- <div>
<button id="downloadBtn" class="secondary-link">Download booking (PDF)</button> </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> /* ======================== 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).'); }); } })(); </script>
<script type="text/javascript"> $(document).ready(function () { $('#pageLoader').hide();
let confirmrefid = sessionStorage.getItem("confirmrefid");
if (!confirmrefid) { window.location.href = "/victoriapublichall/register"; } sessionStorage.removeItem("confirmrefid");
// Fetch booking details $.ajax({ type: "GET", url: "/victoriapublichall/bookingapi/getdetailsbyrefid", data: { confirmrefid: confirmrefid },
success: function (response) {
// ===== Populate summary card ===== $("#confirmDate").text(formatDateToLong(response.visitingDate)); $("#confirmRange").text(response.timeRange || "--"); $("#confirmPeople").text( response.no_of_people ? response.no_of_people.toString().padStart(2, "0") : "00" );
// ===== Populate AV Experience ===== const list = $("#confirmAvList"); list.empty(); // clear old rows
if (!response.allocatedSlots || response.allocatedSlots.length === 0) { list.append(` <div class="av-row"> <div class="av-time">No slots allocated</div> </div> `); } else { response.allocatedSlots.forEach(s => { list.append(` <div class="av-row"> <div class="av-time">${s.time} (${s.language})</div> <div class="av-seats">${s.people} Seat${s.people > 1 ? "s" : ""}</div> </div> `); }); } },
error: function (xhr) { Swal.fire({ icon: "error", title: "Unable to load booking details", text: xhr.responseText || "Please try again.", confirmButtonText: "OK" }).then(() => { window.location.href = "/victoriapublichall/register"; }); } });
});
function formatDateToLong(dateStr) { if (!dateStr) return "--";
const [dd, mm, yyyy] = dateStr.split("-");
const months = [ "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" ];
return `${dd}, ${months[parseInt(mm) - 1]} ${yyyy}`; } </script>
<script> // Replace '/your/specified/path' with the page you want to redirect to const redirectPath = '/victoriapublichall/register'; // This runs when the user presses the browser's back button window.addEventListener('popstate', function (event) {
window.location.href = redirectPath;
}); // Push a dummy state so that the popstate event triggers properly history.pushState(null, null, location.href); </script>
</body>
</html>
|