You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

990 lines
24 KiB

6 days ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!doctype html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head th:replace="~{fragments/user-head :: head}"></head>
  4. <!-- <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width,initial-scale=1" />
  6. <title>Victoria Public Hall — Booking</title>
  7. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  8. <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"> -->
  9. <style>
  10. :root {
  11. --accent: #12363b;
  12. --muted: #6b6b6b;
  13. --card-bg: #ffffff;
  14. --slot-radius: 10px;
  15. --green-start: #16a34a;
  16. --green-end: #09905a;
  17. }
  18. * {
  19. box-sizing: border-box;
  20. margin: 0;
  21. padding: 0
  22. }
  23. html,
  24. body {
  25. height: 100%
  26. }
  27. body {
  28. font-family: "Inter", "Helvetica Neue", Arial, sans-serif;
  29. background:
  30. linear-gradient(rgba(255, 255, 255, 0.70), rgba(255, 255, 255, 0.82)),
  31. url('/victoriapublichall/images/vph-background_v1.jpg') top center / cover no-repeat,
  32. url('/victoriapublichall/images/vph-background_v1.jpg') bottom center / cover no-repeat;
  33. min-height: 100vh;
  34. background-attachment: fixed;
  35. /* keeps both images static */
  36. background-repeat: no-repeat;
  37. background-size: cover;
  38. -webkit-font-smoothing: antialiased;
  39. min-height: 100vh;
  40. display: flex;
  41. flex-direction: column;
  42. gap: 12px;
  43. padding: 18px 24px;
  44. }
  45. /* container */
  46. .container {
  47. width: 100%;
  48. max-width: 1200px;
  49. margin: 0 auto;
  50. }
  51. /******************************
  52. NAVBAR (desktop + mobile)
  53. ******************************/
  54. .topbar {
  55. display: flex;
  56. align-items: center;
  57. justify-content: space-between;
  58. gap: 16px;
  59. padding: 10px 0;
  60. position: relative;
  61. z-index: 1300;
  62. }
  63. .leftbar {
  64. display: flex;
  65. align-items: center;
  66. gap: 20px;
  67. }
  68. /* ---------- Navbar styles (desktop + mobile behaviour) ---------- */
  69. /* keep your existing desktop styles; add / replace these responsive bits */
  70. /* small logo + layout helpers */
  71. .nav-left {
  72. display: flex;
  73. align-items: center;
  74. gap: 12px;
  75. }
  76. .logo {
  77. width: 72px;
  78. height: 72px;
  79. object-fit: contain;
  80. border-radius: 50%;
  81. }
  82. /* default desktop nav */
  83. nav.primary {
  84. display: flex;
  85. gap: 18px;
  86. align-items: center;
  87. }
  88. /* Desktop Navigation Links (Figma Accurate) */
  89. nav.primary a {
  90. font-family: "Playfair Display", serif !important;
  91. font-weight: 400 !important;
  92. /* Regular */
  93. font-style: normal !important;
  94. font-size: 15px !important;
  95. /* Figma size */
  96. line-height: 100% !important;
  97. letter-spacing: 0 !important;
  98. color: #3C1E12;
  99. /* matches Book a Visit color */
  100. text-decoration: none;
  101. padding: 6px 8px;
  102. /* keep your layout spacing */
  103. border-radius: 6px;
  104. transition: background 0.2s ease;
  105. }
  106. /* Hover state (optional subtle effect like Figma preview) */
  107. nav.primary a:hover {
  108. background: rgba(0, 0, 0, 0.06);
  109. color: #3C1E12;
  110. /* no change in color */
  111. }
  112. /* Mobile menu links */
  113. .mobile-nav a {
  114. font-family: "Playfair Display", serif !important;
  115. font-weight: 400 !important;
  116. font-size: 15px !important;
  117. letter-spacing: 0 !important;
  118. color: #3C1E12;
  119. }
  120. .rightbar {
  121. display: flex;
  122. align-items: center;
  123. gap: 12px;
  124. }
  125. /* Desktop CTA (Book a Visit) — With Figma Border */
  126. #desktopBookBtn {
  127. width: 174px;
  128. /* Figma button width */
  129. height: 57px;
  130. /* Figma button height */
  131. display: inline-flex;
  132. align-items: center;
  133. justify-content: center;
  134. background: transparent;
  135. border-radius: 8px;
  136. /* Figma corner radius */
  137. /* Border from Figma (thin outline) */
  138. border: 1px solid rgba(60, 30, 18, 0.40);
  139. /* darker visible border */
  140. cursor: pointer;
  141. /* Figma Typography */
  142. font-family: "Playfair Display", serif !important;
  143. font-weight: 700 !important;
  144. /* Bold */
  145. font-style: italic !important;
  146. font-size: 24px !important;
  147. line-height: 100% !important;
  148. /* Letter spacing -6% = -0.06em */
  149. letter-spacing: -0.06em !important;
  150. color: #3C1E12 !important;
  151. }
  152. /* Hover effect (Figma-like subtle shadow) */
  153. #desktopBookBtn:hover {
  154. box-shadow: 0 2px 6px rgba(0, 0, 0, 0.10);
  155. }
  156. /* hamburger (hidden on desktop) */
  157. .hamburger {
  158. display: none;
  159. align-items: center;
  160. justify-content: center;
  161. width: 44px;
  162. height: 44px;
  163. border-radius: 8px;
  164. border: 1px solid rgba(0, 0, 0, 0.06);
  165. background: transparent;
  166. cursor: pointer;
  167. padding: 8px;
  168. }
  169. .hamburger .bar {
  170. display: block;
  171. width: 18px;
  172. height: 2px;
  173. background: var(--dark);
  174. margin: 3px 0;
  175. transition: transform .2s, opacity .2s;
  176. }
  177. /* mobile floating menu + overlay (initial hidden) */
  178. .mobile-overlay {
  179. position: fixed;
  180. inset: 0;
  181. background: rgba(0, 0, 0, 0.22);
  182. z-index: 1350;
  183. opacity: 0;
  184. pointer-events: none;
  185. transition: opacity .22s ease;
  186. }
  187. .mobile-overlay.show {
  188. opacity: 1;
  189. pointer-events: auto;
  190. }
  191. .mobile-nav {
  192. position: fixed;
  193. left: 12px;
  194. right: 12px;
  195. top: 68px;
  196. max-width: 420px;
  197. margin: 0 auto;
  198. background: #fff;
  199. border-radius: 12px;
  200. padding: 14px;
  201. box-shadow: 0 22px 60px rgba(0, 0, 0, 0.16);
  202. border: 1px solid rgba(0, 0, 0, 0.06);
  203. z-index: 1400;
  204. transform: translateY(-8px) scale(.995);
  205. opacity: 0;
  206. pointer-events: none;
  207. transition: opacity .22s ease, transform .22s ease;
  208. }
  209. .mobile-nav.open {
  210. opacity: 1;
  211. transform: translateY(0) scale(1);
  212. pointer-events: auto;
  213. }
  214. .mobile-nav a {
  215. display: block;
  216. padding: 10px 12px;
  217. color: var(--dark);
  218. text-decoration: none;
  219. border-radius: 8px;
  220. font-weight: 600;
  221. }
  222. .mobile-nav a+a {
  223. margin-top: 8px;
  224. }
  225. /******************************
  226. PAGE / HERO / PANEL
  227. ******************************/
  228. .page {
  229. width: 100%;
  230. display: flex;
  231. flex-direction: column;
  232. align-items: center;
  233. justify-content: flex-start;
  234. margin-top: 20px;
  235. }
  236. .panel-wrap {
  237. width: 100%;
  238. display: flex;
  239. justify-content: center;
  240. align-items: center;
  241. margin-top: 18px;
  242. }
  243. .hero {
  244. width: 100%;
  245. max-width: 920px;
  246. text-align: center;
  247. margin-bottom: 12px;
  248. }
  249. /* Desktop style */
  250. .page h1 {
  251. font-family: "Inter", sans-serif;
  252. font-weight: 700;
  253. font-style: normal;
  254. font-size: 48px;
  255. line-height: 100%;
  256. letter-spacing: 0;
  257. text-align: center;
  258. width: 100%;
  259. max-width: 444px;
  260. /* Figma width */
  261. margin: 0 auto 10px;
  262. /* Center + bottom spacing */
  263. color: #3B1E14 !important;
  264. }
  265. /* Desktop version */
  266. .hero .lead {
  267. font-family: "Inter", sans-serif;
  268. font-weight: 400;
  269. font-style: normal;
  270. font-size: 20px;
  271. line-height: 100%;
  272. letter-spacing: 0;
  273. text-align: center;
  274. width: 100%;
  275. max-width: 417px;
  276. /* From Figma */
  277. margin: 0 auto 20px;
  278. /* Center + spacing */
  279. color: #000000;
  280. /* BLACK COLOR as requested */
  281. }
  282. /* ========== Confirmation / cards styles ========== */
  283. /* Booking Confirmed Title — applies ONLY to this h1 */
  284. h1.booking-confirmed {
  285. width: 313px;
  286. height: 39px;
  287. font-family: "Inter", sans-serif;
  288. font-weight: 700;
  289. font-size: 32px;
  290. line-height: 100%;
  291. letter-spacing: 0;
  292. text-align: center;
  293. color: #0CBC47 !important;
  294. /* force green color */
  295. margin: 0 auto;
  296. display: block;
  297. }
  298. /* Booking details subtitle — ONLY for this h2 */
  299. h3.booking-subtitle {
  300. font-family: "Inter", sans-serif;
  301. font-size: 12px;
  302. /* Size */
  303. line-height: 11px;
  304. /* Figma line height */
  305. letter-spacing: 0;
  306. text-align: center;
  307. /* Center aligned */
  308. color: #000000;
  309. /* Black text */
  310. }
  311. .grid {
  312. display: grid;
  313. grid-template-columns: 1fr;
  314. gap: 16px;
  315. justify-items: center;
  316. margin: 10px 0 24px;
  317. }
  318. .summary-card {
  319. Width: 536px;
  320. Height: 114px;
  321. background: var(--card-bg);
  322. border-radius: 10px;
  323. box-shadow: 0 10px 24px rgba(7, 25, 30, 0.06);
  324. padding: 18px;
  325. border: 1px solid rgba(0, 0, 0, 0.03);
  326. text-align: left;
  327. }
  328. .av-card {
  329. Width: 536px;
  330. background: var(--card-bg);
  331. border-radius: 10px;
  332. box-shadow: 0 10px 24px rgba(7, 25, 30, 0.06);
  333. padding: 18px;
  334. border: 1px solid rgba(0, 0, 0, 0.03);
  335. text-align: left;
  336. }
  337. .summary-row {
  338. display: flex;
  339. align-items: flex-start;
  340. justify-content: space-between;
  341. gap: 12px;
  342. }
  343. .summary-left {
  344. width: 60%;
  345. color: var(--muted);
  346. font-size: 14px;
  347. display: flex;
  348. flex-direction: column;
  349. gap: 12px;
  350. }
  351. .summary-left .label {
  352. font-weight: 700;
  353. color: black !important;
  354. font-size: 13px;
  355. }
  356. .summary-right {
  357. width: 40%;
  358. text-align: right;
  359. font-weight: 400;
  360. color: #0b0b0b;
  361. font-size: 14px;
  362. display: flex;
  363. flex-direction: column;
  364. gap: 12px;
  365. align-items: flex-end;
  366. }
  367. .av-box {
  368. margin-top: 12px;
  369. padding: 12px;
  370. max-height: 160px;
  371. overflow-y: auto;
  372. padding-right: 6px;
  373. }
  374. .av-title {
  375. font-weight: 700;
  376. margin-bottom: 8px;
  377. color: #222;
  378. font-size: 14px;
  379. }
  380. .av-list {
  381. display: flex;
  382. flex-direction: column;
  383. gap: 8px;
  384. }
  385. .av-row {
  386. display: flex;
  387. justify-content: space-between;
  388. align-items: center;
  389. padding: 6px 8px;
  390. border-radius: 6px;
  391. background: transparent;
  392. }
  393. .av-time {
  394. font-weight: 400;
  395. color: #0b0b0b;
  396. }
  397. .av-seats {
  398. color: #0b0b0b;
  399. font-size: 13px;
  400. }
  401. .gbm-wrap {
  402. margin-top: 22px;
  403. text-align: center;
  404. }
  405. .gbm {
  406. Width: 536px;
  407. display: inline-block;
  408. padding: 16px 40px;
  409. background: #043B55;
  410. color: #fff;
  411. border-radius: 10px;
  412. border: none;
  413. font-weight: 700;
  414. text-decoration: none;
  415. cursor: pointer;
  416. box-shadow: 0 8px 26px rgba(4, 59, 69, 0.12);
  417. margin-bottom: 10px;
  418. }
  419. .secondary-link {
  420. display: inline-block;
  421. margin-top: 12px;
  422. font-size: 14px;
  423. color: var(--muted);
  424. text-decoration: underline;
  425. cursor: pointer;
  426. background: transparent;
  427. border: none;
  428. }
  429. /* ===== Final mobile override — place LAST in your CSS (<=520px) ===== */
  430. @media (max-width: 520px) {
  431. /* page / body */
  432. body {
  433. padding: 12px 10px;
  434. background-position: center top;
  435. background-size: cover;
  436. -webkit-font-smoothing: antialiased;
  437. }
  438. /* container & panels */
  439. .container,
  440. .panel-wrap,
  441. .page {
  442. width: 100%;
  443. max-width: 420px;
  444. margin: 0 auto;
  445. padding: 0 8px;
  446. box-sizing: border-box;
  447. }
  448. /* header / nav */
  449. .logo {
  450. width: 61px;
  451. height: 61px;
  452. }
  453. nav.primary {
  454. display: none !important;
  455. }
  456. #desktopBookBtn {
  457. display: none !important;
  458. }
  459. .hamburger {
  460. display: flex !important;
  461. }
  462. /* hero */
  463. .page h1 {
  464. font-size: 32px !important;
  465. width: 100%;
  466. max-width: 360px;
  467. margin: 6px auto 8px;
  468. }
  469. .hero .lead {
  470. font-size: 14px !important;
  471. max-width: 320px;
  472. margin-bottom: 12px;
  473. }
  474. .panel-wrap {
  475. padding: 6px 0 18px;
  476. }
  477. /* Book-grid / confirmation block — force centered and full width */
  478. .grid,
  479. .book-grid {
  480. width: 100% !important;
  481. max-width: 420px !important;
  482. margin: 8px auto 18px !important;
  483. gap: 10px !important;
  484. padding: 0 8px !important;
  485. box-sizing: border-box !important;
  486. justify-items: center !important;
  487. }
  488. /* Booking Confirmed title */
  489. h1.booking-confirmed {
  490. width: 100% !important;
  491. max-width: 420px !important;
  492. font-family: "Inter", sans-serif !important;
  493. font-weight: 700 !important;
  494. font-size: 28px !important;
  495. line-height: 34px !important;
  496. height: auto !important;
  497. color: #0CBC47 !important;
  498. margin: 6px auto 0 !important;
  499. text-align: center !important;
  500. }
  501. /* subtitle beneath booking title */
  502. .book-grid p {
  503. width: 100% !important;
  504. max-width: 420px !important;
  505. font-family: "Inter", sans-serif !important;
  506. font-weight: 400 !important;
  507. font-size: 15px !important;
  508. line-height: 20px !important;
  509. margin: 4px auto 0 !important;
  510. color: #000 !important;
  511. text-align: center !important;
  512. }
  513. /* Summary / cards: full width stacking */
  514. .summary-card,
  515. .av-card,
  516. .card,
  517. .summary-box,
  518. .vph-summary-box {
  519. width: 100% !important;
  520. max-width: 100% !important;
  521. padding: 14px !important;
  522. border-radius: 10px !important;
  523. box-sizing: border-box !important;
  524. }
  525. /* AV list */
  526. .av-box {
  527. margin-top: 10px !important;
  528. padding: 10px !important;
  529. max-height: 160px !important;
  530. overflow-y: auto !important;
  531. }
  532. .av-list {
  533. max-height: unset !important;
  534. overflow-y: visible !important;
  535. gap: 8px !important;
  536. }
  537. .av-row {
  538. padding: 8px 6px !important;
  539. }
  540. /* Buttons and CTAs: full width, touch-friendly */
  541. .gbm,
  542. .btn,
  543. .vph-modal-submit,
  544. .modal-submit {
  545. width: 100% !important;
  546. max-width: 100% !important;
  547. padding: 12px 16px !important;
  548. box-sizing: border-box !important;
  549. font-size: 16px !important;
  550. border-radius: 12px !important;
  551. }
  552. /* Modals: stretch to comfortable mobile size */
  553. .vph-modal,
  554. .modal {
  555. width: 94% !important;
  556. padding: 14px !important;
  557. max-height: 92vh !important;
  558. border-radius: 12px !important;
  559. }
  560. .vph-summary-box,
  561. .vph-av-box,
  562. .summary-box {
  563. height: auto !important;
  564. padding: 12px !important;
  565. }
  566. .vph-modal-submit,
  567. .modal-submit {
  568. width: 100% !important;
  569. padding: 12px 14px !important;
  570. }
  571. /* small tweaks */
  572. .preview-note-box,
  573. .summary-item,
  574. .muted,
  575. .people-support {
  576. font-size: 13px !important;
  577. line-height: 1.35 !important;
  578. }
  579. .time-ranges {
  580. overflow-x: auto !important;
  581. -webkit-overflow-scrolling: touch !important;
  582. gap: 8px !important;
  583. padding-bottom: 8px !important;
  584. }
  585. .time-ranges::-webkit-scrollbar {
  586. display: none;
  587. }
  588. .logo {
  589. width: 61px !important;
  590. height: 61px !important;
  591. }
  592. /* extra small screens */
  593. @media (max-width: 360px) {
  594. h1.booking-confirmed {
  595. font-size: 24px !important;
  596. line-height: 30px !important;
  597. }
  598. h2.booking-subtitle,
  599. h3.booking-subtitle {
  600. font-size: 14px !important;
  601. line-height: 18px !important;
  602. }
  603. .gbm {
  604. padding: 12px !important;
  605. font-size: 15px !important;
  606. }
  607. }
  608. }
  609. .panel {
  610. background: transparent;
  611. }
  612. </style>
  613. <!-- </head> -->
  614. <body>
  615. <div class="container">
  616. <header class="topbar" role="banner">
  617. <div class="leftbar">
  618. <div class="nav-left">
  619. <!-- logo image — use same img src you already have -->
  620. <img th:src="@{images/VPH-logo_main-EN 1.png}" alt="VPH logo" class="logo">
  621. </div>
  622. <!-- desktop nav (hidden on mobile) -->
  623. <nav class="primary" aria-label="Primary navigation">
  624. <a href="/victoriapublichall/home">Home</a>
  625. <a href="#">About VPH</a>
  626. <a href="/victoriapublichall/visit">Visit</a>
  627. <!--<a href="#">Contact Us</a>-->
  628. </nav>
  629. </div>
  630. <!-- right side: hamburger (mobile) + desktop CTA -->
  631. <div class="rightbar">
  632. <button id="hambtn" class="hamburger" aria-label="Open menu" aria-expanded="false" aria-controls="mobileNav">
  633. <span class="bar bar1" aria-hidden="true"></span>
  634. <span class="bar bar2" aria-hidden="true"></span>
  635. <span class="bar bar3" aria-hidden="true"></span>
  636. </button>
  637. </div>
  638. </header>
  639. <!-- overlay (click to close) -->
  640. <div id="mobileOverlay" class="mobile-overlay" aria-hidden="true"></div>
  641. <!-- mobile nav -->
  642. <nav id="mobileNav" class="mobile-nav" aria-hidden="true" role="dialog" aria-modal="true" aria-label="Mobile menu">
  643. <a href="/victoriapublichall/home">Home</a>
  644. <a href="#">About VPH</a>
  645. <a href="/victoriapublichall/visit">Visit</a>
  646. <a href="#">Contact Us</a>
  647. </nav>
  648. <main class="page" role="main" aria-labelledby="hero-heading">
  649. <div class="hero" aria-hidden="false">
  650. <h1 id="hero-heading">Victoria Public Hall</h1>
  651. <div class="lead">Experience Chennai's First Town Hall</div>
  652. </div>
  653. <div class="panel-wrap">
  654. <div class="panel" role="region" aria-label="Booking panel">
  655. <div class="grid">
  656. <div class="book-grid" aria-hidden="false">
  657. <h1 class="booking-confirmed">Booking Confirmed!</h1>
  658. <br>
  659. <p>Your booking details has been sent to your phone/email</p>
  660. </div>
  661. <div class="summary-card" aria-live="polite">
  662. <div class="summary-row">
  663. <div class="summary-left">
  664. <div class="label">Visiting on</div>
  665. <div class="label">Time</div>
  666. <div class="label">Total Guest(s)</div>
  667. </div>
  668. <div class="summary-right">
  669. <div id="confirmDate"></div>
  670. <div id="confirmRange"></div>
  671. <div id="confirmPeople"></div>
  672. </div>
  673. </div>
  674. </div>
  675. <div class="av-card">
  676. <div class="av-title">AV Experience</div>
  677. <div class="av-box">
  678. <div id="confirmAvList" class="av-list">
  679. </div>
  680. </div>
  681. </div>
  682. </div>
  683. <div class="gbm-wrap">
  684. <a href="/victoriapublichall/register" class="gbm" id="goBackBtn">Go back to main page</a>
  685. <!-- <div>
  686. <button id="downloadBtn" class="secondary-link">Download booking (PDF)</button>
  687. </div> -->
  688. </div>
  689. </div>
  690. </div>
  691. </main>
  692. </div>
  693. <div id="pageLoader"
  694. 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;">
  695. <div style="position: relative; top: 50%; transform: translateY(-50%);">
  696. <div class="spinner-border text-primary" style="width: 3rem; height: 3rem;"></div>
  697. <p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
  698. </div>
  699. </div>
  700. <script th:replace="~{fragments/user-script :: script}"></script>
  701. <script>
  702. /* ========================
  703. MOBILE NAV (improved)
  704. ======================== */
  705. (function () {
  706. const hambtn = document.getElementById('hambtn');
  707. const mobileNav = document.getElementById('mobileNav');
  708. const mobileOverlay = document.getElementById('mobileOverlay');
  709. const desktopBook = document.getElementById('desktopBookBtn');
  710. const mobileBook = document.getElementById('mobileBook');
  711. if (!hambtn || !mobileNav || !mobileOverlay) {
  712. // nothing to do if elements missing
  713. } else {
  714. function openMenu() {
  715. hambtn.setAttribute('aria-expanded', 'true');
  716. mobileNav.classList.add('open'); mobileNav.setAttribute('aria-hidden', 'false');
  717. mobileOverlay.classList.add('show'); mobileOverlay.setAttribute('aria-hidden', 'false');
  718. document.body.style.overflow = 'hidden';
  719. const first = mobileNav.querySelector('a'); if (first) first.focus();
  720. }
  721. function closeMenu() {
  722. hambtn.setAttribute('aria-expanded', 'false');
  723. mobileNav.classList.remove('open'); mobileNav.setAttribute('aria-hidden', 'true');
  724. mobileOverlay.classList.remove('show'); mobileOverlay.setAttribute('aria-hidden', 'true');
  725. document.body.style.overflow = '';
  726. hambtn.focus();
  727. }
  728. hambtn.addEventListener('click', () => {
  729. const isOpen = hambtn.getAttribute('aria-expanded') === 'true';
  730. if (isOpen) closeMenu(); else openMenu();
  731. });
  732. mobileOverlay.addEventListener('click', closeMenu);
  733. document.addEventListener('keydown', (e) => {
  734. if (e.key === 'Escape' && mobileNav.classList.contains('open')) closeMenu();
  735. });
  736. mobileNav.querySelectorAll('a').forEach(a => {
  737. a.addEventListener('click', () => {
  738. // close after clicking any mobile link
  739. closeMenu();
  740. });
  741. });
  742. // ensure menu closes when resizing to desktop
  743. window.addEventListener('resize', () => {
  744. if (window.innerWidth > 900 && mobileNav.classList.contains('open')) closeMenu();
  745. });
  746. }
  747. // Optional: wire desktop Book a Visit to the same booking action as mobile
  748. if (desktopBook && mobileBook) {
  749. desktopBook.addEventListener('click', (e) => {
  750. e.preventDefault();
  751. // mimic mobile behavior for demo: show alert (replace with real action)
  752. alert('Book a Visit clicked — open booking flow here.');
  753. });
  754. mobileBook.addEventListener('click', (e) => {
  755. // mobile link closes menu via handler above and then can navigate or open booking flow
  756. // if you want to override, uncomment below
  757. // e.preventDefault(); alert('Mobile Book clicked (replace with action).');
  758. });
  759. }
  760. })();
  761. </script>
  762. <script type="text/javascript">
  763. $(document).ready(function () {
  764. $('#pageLoader').hide();
  765. let confirmrefid = sessionStorage.getItem("confirmrefid");
  766. if (!confirmrefid) {
  767. window.location.href = "/victoriapublichall/register";
  768. }
  769. sessionStorage.removeItem("confirmrefid");
  770. // Fetch booking details
  771. $.ajax({
  772. type: "GET",
  773. url: "/victoriapublichall/bookingapi/getdetailsbyrefid",
  774. data: { confirmrefid: confirmrefid },
  775. success: function (response) {
  776. // ===== Populate summary card =====
  777. $("#confirmDate").text(formatDateToLong(response.visitingDate));
  778. $("#confirmRange").text(response.timeRange || "--");
  779. $("#confirmPeople").text(
  780. response.no_of_people ? response.no_of_people.toString().padStart(2, "0") : "00"
  781. );
  782. // ===== Populate AV Experience =====
  783. const list = $("#confirmAvList");
  784. list.empty(); // clear old rows
  785. if (!response.allocatedSlots || response.allocatedSlots.length === 0) {
  786. list.append(`
  787. <div class="av-row">
  788. <div class="av-time">No slots allocated</div>
  789. </div>
  790. `);
  791. } else {
  792. response.allocatedSlots.forEach(s => {
  793. list.append(`
  794. <div class="av-row">
  795. <div class="av-time">${s.time} (${s.language})</div>
  796. <div class="av-seats">${s.people} Seat${s.people > 1 ? "s" : ""}</div>
  797. </div>
  798. `);
  799. });
  800. }
  801. },
  802. error: function (xhr) {
  803. Swal.fire({
  804. icon: "error",
  805. title: "Unable to load booking details",
  806. text: xhr.responseText || "Please try again.",
  807. confirmButtonText: "OK"
  808. }).then(() => {
  809. window.location.href = "/victoriapublichall/register";
  810. });
  811. }
  812. });
  813. });
  814. function formatDateToLong(dateStr) {
  815. if (!dateStr) return "--";
  816. const [dd, mm, yyyy] = dateStr.split("-");
  817. const months = [
  818. "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
  819. "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
  820. ];
  821. return `${dd}, ${months[parseInt(mm) - 1]} ${yyyy}`;
  822. }
  823. </script>
  824. <script>
  825. // Replace '/your/specified/path' with the page you want to redirect to
  826. const redirectPath = '/victoriapublichall/register';
  827. // This runs when the user presses the browser's back button
  828. window.addEventListener('popstate', function (event) {
  829. window.location.href = redirectPath;
  830. });
  831. // Push a dummy state so that the popstate event triggers properly
  832. history.pushState(null, null, location.href);
  833. </script>
  834. </body>
  835. </html>