|
|
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Victoria public hall</title> <!-- Links to Bootstrap CSS and JS, jQuery, and SweetAlert --> <!-- Bootstrap CSS --> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<style> label { color: black; }
/* Header Styling */ .header { background-color: #1d495a; padding: 10px 20px; display: flex; align-items: center; justify-content: space-between; color: white; font-family: Arial, sans-serif;
}
.header .logo { display: flex; align-items: center; }
.header .logo img { height: 60px; }
.header .center-text { position: absolute; /* Centered text */ left: 50%; transform: translateX(-50%); text-align: center; font-size: 24px; }
.header .menu-btn { background-color: transparent; border: none; font-size: 24px; color: white; }
.header .menu-btn:hover { /* text-decoration: underline; */ color: #ccc; }
/* Menu Dropdown */ .menu-dropdown { position: relative; margin-top: 10px; background-color: #1d495a; padding: 10px 20px; display: none; flex-direction: column; width: 100%; }
.menu-dropdown a { color: white; margin-bottom: 5px; text-decoration: none; }
.menu-dropdown a:hover { text-decoration: underline; }
.menu-dropdown { right: 0; left: 0; z-index: 1000; /* Add z-index to bring the menu above other elements */ }
/* Mobile Specific Styling */ @media (max-width : 768px) { .header { display: flex; justify-content: space-between; align-items: center; }
.center-text { font-size: 18px !important; flex-grow: 1; text-align: center; }
.menu-dropdown { right: 0; left: 0; z-index: 1000; /* Add z-index to bring the menu above other elements */ } }
/* Ensure content is not hidden behind the fixed navbar */ body { margin: 0; /* margin-top: 90px; Adjust based on your header height */ }
.disclaimer-list li { font-size: 0.95rem; /* or 1rem */ line-height: 1.6; }
.flatpickr-calendar { z-index: 99999 !important; }
/* Allow calendar to overflow cards */ .card, .card-body, .container { overflow: visible !important; } .pickdate[readonly] { background-color: #fff !important; cursor: pointer; }
.readonly-input { background-color: #e9ecef; /* Bootstrap disabled look */ cursor: not-allowed; }
</style></head>
<body style="background-color: #ebf1fa;">
<!-- Header Start--> <header> <div class="header d-flex justify-content-between align-items-center"> <!-- Left: Logo --> <div class="logo"> <img src="https://gccservices.in/gcc/assets/images/logo.png" alt="Logo"> </div>
<!-- Center: Text --> <div class="center-text">VICTORIA PUBLIC HALL</div>
</div>
</header> <!-- Header End-->
<main class="container mt-4"> <div class="container mt-5"> <div class="card"> <div class="card-header bg-dark text-white"> <h5>Request Information:-</h5> </div> <div class="card-body"> <div class="container mt-4">
<!-- Row 1: Name and Phone --> <div class="row mb-3"> <div class="col-md-5"> <label class="form-label" for="name">Name <span class="text-danger">*</span></label> <input type="text" class="form-control" placeholder="Enter Name here" id="name" oninput="this.value = this.value.replace(/[^a-zA-Z\s]/g, '')"> </div> <div class="col-md-5"> <label class="form-label" for="userinput"> Mobile Number/Email </label> <input type="text" id="userinput" class="form-control readonly-input" placeholder="Enter Phone number"> </div> </div> <div class="row mb-3"> <div class="col-md-5"> <label class="form-label" for="category"> Category <span class="text-danger">*</span> </label>
<select class="form-control" id="category" name="categoryId" required> <option value="">-- Select Category --</option> </select> </div>
<div class="col-md-5"> <label class="form-label" for="preferdate"> Preferred Date <span class="text-danger">*</span> </label>
<div class="input-group"> <input type="text" class="form-control pickdate" id="preferdate" placeholder="dd-mm-yyyy" >
<div class="input-group-append"> <span class="input-group-text" style="cursor:pointer"> 📅 </span> </div> </div> </div>
</div>
</div> </div> </div>
<!-- School / College Card --> <div class="card mt-3 d-none" id="schoolCollegeCard"> <div class="card-header bg-dark text-white"> <h6 class="mb-0">School / College Details</h6> </div> <div class="card-body"> <div class="row mb-3"> <div class="col-md-5"> <label for="privateInstitutionName">Institution Name <span class="text-danger">*</span></label> <input type="text" class="form-control" id="privateInstitutionName" placeholder="Enter School / College Name" oninput="allowOnlyAlphabets(this)"> </div>
<!-- ID Proof Dropdown --> <div class="col-md-5"> <label class="form-label" for="idProof"> ID Proof of accompanying staff <span class="text-danger">*</span> </label>
<select class="form-control idProofSelect mb-2"> <option value="">-- Select ID Proof --</option> </select> </div>
<!-- ID Number Input --> <div class="col-md-5"> <label class="form-label" for="idProofNumber"> ID Proof Number <span class="text-danger">*</span> </label>
<input class="form-control idProofNumber" placeholder="Select ID Proof first" disabled> </div>
</div>
</div> </div>
<!-- Organization / Association Card --> <div class="card mt-3 d-none" id="organizationCard"> <div class="card-header bg-dark text-white"> <h6 class="mb-0">Organization / Association Details</h6> </div> <div class="card-body"> <div class="row mb-3"> <div class="col-md-5"> <label>Organization Name <span class="text-danger">*</span></label> <input type="text" class="form-control" id="orgName" placeholder="Enter Organization Name" oninput="allowOnlyAlphabets(this)"> </div>
<!-- ID Proof Dropdown --> <div class="col-md-5"> <label class="form-label" for="idProof">ID Proof of accompanying staff <span class="text-danger">*</span> </label>
<select class="form-control idProofSelect mb-2"> <option value="">-- Select ID Proof --</option> </select> </div>
<!-- ID Number Input --> <div class="col-md-5"> <label class="form-label" for="idProofNumber"> ID Proof Number <span class="text-danger">*</span> </label>
<input class="form-control idProofNumber" placeholder="Select ID Proof first" disabled> </div>
</div> </div> </div>
<div class="card mt-3 d-none" id="visitorDetailsCard"> <div class="card-header bg-dark text-white"> <h6 class="mb-0">Visitor Details</h6> </div>
<div class="card-body">
<!-- Dynamic User Type Rows --> <div id="userTypeContainer"></div>
<hr>
<!-- Summary --> <div class="d-flex justify-content-between"> <strong>Total People:</strong> <span id="totalPeople">0</span> </div>
<div class="d-flex justify-content-between mt-2"> <strong>Total Amount:</strong> <span id="totalAmount">₹0</span> </div>
</div> </div>
<div class="card mt-3" id="termsCheckCard"> <div class="card-header bg-dark text-white"> <h6 class="mb-0">Disclaimer</h6> </div>
<div class="card-body">
<!-- Disclaimer Content --> <ul class="small text-muted mb-3 disclaimer-list "> <li> Submission of this application shall be treated as a <strong>request only</strong> and shall not be considered as confirmation of booking. </li> <li> The preferred visit date indicated is <strong>subject to availability</strong> and verification by the Competent Authority. </li> <li> In the event of non-availability of the preferred date, the Competent Authority reserves the right to allot an <strong>alternate visit date</strong>. </li> <li> The final visit date shall be communicated to the applicant upon approval. </li> <li> The booking shall be deemed confirmed only upon <strong>administrative approval and successful payment confirmation</strong>, wherever applicable. </li> <li> Payment shall be made within <strong>24 hours</strong> from the date and time of approval, failing which the request shall be liable for <strong>automatic cancellation</strong> without further notice. </li> </ul>
<hr>
<!-- Terms and Conditions Checkbox --> <div class="form-check mt-4 text-center"> <input class="form-check-input" type="checkbox" id="termsCheck"> <label class="form-check-label" for="termsCheck"> I have read the above Disclaimer. <!-- <a href="#" data-bs-toggle="modal" data-bs-target="#termsModal">
terms and conditions </a>. --> </label> </div>
</div> </div>
<div class="text-center mt-4"> <button type="button" class="btn btn-success" id="submitBtn" onclick="saveBulkBooking()">Submit</button>
<button type="button" class="btn btn-secondary" onclick="goBack()">Back</button> </div> <br>
</div>
</main> <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" role="status" style="width: 3rem; height: 3rem;"> <span class="sr-only">Loading...</span> </div> <!-- Add the 'Please wait' text below the spinner --> <p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p> </div> </div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<!-- Flatpickr CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<!-- Flatpickr JS --> <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<script>
$(document).ready(function () {
$.ajax({ url: "/victoriapublichall/bookingapi/category", type: "GET", success: function (data) { const categorySelect = $("#category"); categorySelect.empty(); categorySelect.append('<option value="">-- Select Category --</option>');
data.forEach(row => { categorySelect.append( `<option value="${row.id}">${row.category}</option>` ); }); }, error: function () { alert("Unable to load categories"); } });
});
$("#category").on("change", function () {
const selectedVal = $(this).val(); const selectedText = $("#category option:selected").text().toLowerCase();
const isGovtSchool = selectedVal === "1";
// Reset counts & set amounts correctly userTypes.forEach(u => { u.count = 0; u.amount = isGovtSchool ? 0 : u.originalAmount; });
renderUserTypes();
// Hide / show total amount section if (isGovtSchool) { $("#totalAmount").closest(".d-flex").hide(); } else { $("#totalAmount").closest(".d-flex").show(); } // Hide all cards first // $("#govtschoolCard").addClass("d-none"); $("#schoolCollegeCard").addClass("d-none"); $("#organizationCard").addClass("d-none");
// Hide visitor details initially $("#visitorDetailsCard").addClass("d-none");
// If category is selected if (selectedVal) {
// Show visitor details (common for all) $("#visitorDetailsCard").removeClass("d-none");
// School / College if ( selectedText.includes("school") || selectedText.includes("college") ) { $("#schoolCollegeCard").removeClass("d-none"); }
// Organization / Association / Tourism else if ( selectedText.includes("organization") || selectedText.includes("association") || selectedText.includes("tourism") ) { $("#organizationCard").removeClass("d-none"); } } });
document.addEventListener("DOMContentLoaded", function () {
const phoneInput = document.getElementById("userinput"); const storedMobile = sessionStorage.getItem("bulkMobile");
if (phoneInput && storedMobile) { phoneInput.value = storedMobile; phoneInput.readOnly = true; // enforce readonly phoneInput.classList.add("readonly"); // optional styling }
});
document.addEventListener("DOMContentLoaded", function () {
const fp = flatpickr("#preferdate", { dateFormat: "Y-m-d", // backend format altInput: true, altFormat: "d-m-Y", minDate: new Date().fp_incr(10), disable: [ function (date) { return date.getDay() === 2; // Tuesday } ], disableMobile: true });
// Open calendar when icon is clicked document.querySelector(".input-group-text").addEventListener("click", function () { fp.open(); });
});
/*document.addEventListener("DOMContentLoaded", function () {
const dateInput = document.getElementById("preferdate");
const today = new Date(); today.setDate(today.getDate() + 10);
const yyyy = today.getFullYear(); const mm = String(today.getMonth() + 1).padStart(2, '0'); const dd = String(today.getDate()).padStart(2, '0');
dateInput.min = `${yyyy}-${mm}-${dd}`;
dateInput.addEventListener("keydown", function (e) { e.preventDefault(); });
});*/
// visitor category and calculate amount
let userTypes = [];
$(document).ready(function () {
$.ajax({ url: "/victoriapublichall/bookingapi/getamountbyusertype", type: "GET", success: function (data) { userTypes = data.map(row => ({ id: row.id, type: row.user_type, amount: row.amount, originalAmount: row.amount, count: 0 }));
renderUserTypes(); }, error: function () { alert("Unable to load user types"); } });
});
function renderUserTypes() {
const container = $("#userTypeContainer"); container.empty();
const isGovtSchool = $("#category").val() === "1";
userTypes.forEach((u, index) => {
container.append(` <div class="row align-items-center mb-2">
<div class="col-md-${isGovtSchool ? 6 : 4}"> <strong>${u.type}</strong> ${isGovtSchool ? "" : `<span class="text-muted ms-1">(₹${u.amount})</span>`} </div>
<!-- Count input --> <div class="col-md-${isGovtSchool ? 6 : 4}"> <input type="text" class="form-control" maxlength="3" inputmode="numeric" value="${u.count}" oninput=" this.value=this.value.replace(/[^0-9]/g,'').slice(0,3); updateCount(${index}, this.value) "> </div>
<!-- Amount column (hidden for Govt School) --> ${isGovtSchool ? "" : ` <div class="col-md-4 text-end"> ₹<span id="amount-${index}">${u.count * u.amount}</span> </div> `} </div> `); });
updateTotals(); }
function updateCount(index, value) {
let newCount = parseInt(value, 10); if (isNaN(newCount) || newCount < 0) newCount = 0;
// Calculate total EXCLUDING current index let totalWithoutCurrent = 0; userTypes.forEach((u, i) => { if (i !== index) { totalWithoutCurrent += u.count; } });
// HARD LIMIT CHECK if (totalWithoutCurrent + newCount > 480) { Swal.fire( "Limit Exceeded", "Total visitor count cannot exceed 480.", "warning" );
// Reset only this input renderUserTypes(); return; }
// Safe to update userTypes[index].count = newCount;
// Update row amount safely const amountEl = document.getElementById(`amount-${index}`); if (amountEl) { amountEl.textContent = newCount * userTypes[index].amount; }
updateTotals(); }
/* Update Totals */ function updateTotals() {
let totalPeople = 0; let totalAmount = 0;
userTypes.forEach(u => { totalPeople += u.count; totalAmount += u.count * u.amount; });
$("#totalPeople").text(totalPeople); $("#totalAmount").text("₹" + totalAmount); }
$(document).ready(function () {
$.ajax({ url: "/victoriapublichall/bookingapi/getidproofs", type: "GET", success: function (data) {
$(".idProofSelect").each(function () { const select = $(this); select.empty(); select.append('<option value="">-- Select ID Proof --</option>');
data.forEach(row => { select.append( `<option value="${row.id}">${row.id_name}</option>` ); }); }); } });
});
$(document).on("change", ".idProofSelect", function () {
const selectedText = $(this).find("option:selected").text().toLowerCase(); const input = $(this).closest(".row").find(".idProofNumber");
input.val(""); input.prop("disabled", true); input.removeAttr("maxlength"); input.off("input");
if (!selectedText || selectedText.includes("select")) { input.attr("placeholder", "Select ID Proof first"); return; }
input.prop("disabled", false);
if (selectedText.includes("aadhar")) { input.attr("placeholder", "Enter 12-digit Aadhaar Number"); input.attr("maxlength", "12"); input.on("input", function () { this.value = this.value.replace(/[^0-9]/g, ""); }); } else if (selectedText.includes("passport")) { input.attr("placeholder", "Enter Passport Number"); input.attr("maxlength", "9"); input.on("input", function () { this.value = this.value.replace(/[^a-zA-Z0-9]/g, "").toUpperCase(); }); } else { input.attr("placeholder", "Enter ID Proof Number"); } });
function validateBulkBookingForm() {
// Name if (!$("#name").val().trim()) { Swal.fire("Validation Error", "Please enter Name", "warning"); return false; }
// Mobile / Email if (!$("#userinput").val().trim()) { Swal.fire("Validation Error", "Please enter Mobile Number or Email", "warning"); return false; }
// Category if (!$("#category").val()) { Swal.fire("Validation Error", "Please select Category", "warning"); return false; }
// Preferred Date if (!$("#preferdate").val()) { Swal.fire("Validation Error", "Please select Preferred Date", "warning"); return false; }
// Visitor Count let totalPeople = parseInt($("#totalPeople").text(), 10); if (!totalPeople || totalPeople <= 0) { Swal.fire("Validation Error", "Please enter visitor count", "warning"); return false; }
if ($("#schoolCollegeCard").is(":visible")) {
if (!$("#privateInstitutionName").val().trim()) { Swal.fire("Validation Error", "Please enter School / College Name", "warning"); return false; }
const idTypeText = $("#schoolCollegeCard .idProofSelect option:selected") .text().toLowerCase(); const idNumber = $("#schoolCollegeCard .idProofNumber").val().trim();
if (!idTypeText || idTypeText.includes("select")) { Swal.fire("Validation Error", "Please select ID Proof", "warning"); return false; }
if (!idNumber) { Swal.fire("Validation Error", "Please enter ID Proof Number", "warning"); return false; }
// Aadhaar validation if (idTypeText.includes("aadhar") || idTypeText.includes("aadhaar")) { if (!/^[0-9]{12}$/.test(idNumber)) { Swal.fire( "Validation Error", "Aadhaar number must be exactly 12 digits", "warning" ); return false; } }
// Passport validation (Indian) if (idTypeText.includes("passport")) { if (!/^[A-Z][0-9]{7}$/.test(idNumber)) { Swal.fire( "Validation Error", "Passport number must be 1 uppercase letter followed by 7 digits ", "warning" ); return false; } } }
if ($("#organizationCard").is(":visible")) {
if (!$("#orgName").val().trim()) { Swal.fire("Validation Error", "Please enter Organization Name", "warning"); return false; }
const idTypeText = $("#organizationCard .idProofSelect option:selected") .text().toLowerCase(); const idNumber = $("#organizationCard .idProofNumber").val().trim();
if (!idTypeText || idTypeText.includes("select")) { Swal.fire("Validation Error", "Please select ID Proof", "warning"); return false; }
if (!idNumber) { Swal.fire("Validation Error", "Please enter ID Proof Number", "warning"); return false; }
// Aadhaar if (idTypeText.includes("aadhar") || idTypeText.includes("aadhaar")) { if (!/^[0-9]{12}$/.test(idNumber)) { Swal.fire( "Validation Error", "Aadhaar number must be exactly 12 digits", "warning" ); return false; } }
// Passport if (idTypeText.includes("passport")) { if (!/^[A-Z][0-9]{7}$/.test(idNumber)) { Swal.fire( "Validation Error", "Passport number must be 1 uppercase letter followed by 7 digits", "warning" ); return false; } } }
return true; }
function saveBulkBooking() {
let totalPeople = userTypes.reduce((sum, u) => sum + u.count, 0);
if (totalPeople <= 10) { Swal.fire( "Minimum Limit Required", "Total number of visitors must be more than 10.", "warning" ); return; }
if (totalPeople > 480) { Swal.fire("Limit Exceeded", "Total visitor count cannot exceed 480.", "warning"); return; }
// Terms check if (!$("#termsCheck").is(":checked")) { Swal.fire("Terms Required", "Please agree to the terms and conditions.", "warning"); return; }
// Local validation if (!validateBulkBookingForm()) return;
const userInput = $("#userinput").val().trim();
// CHECK DUPLICATE MOBILE / EMAIL $.ajax({ url: "/victoriapublichall/bookingapi/checkBulkBookingExists", type: "POST", data: { userInput: userInput }, success: function (res) {
if (res.exists) { Swal.fire( "Booking Not Allowed", "This Mobile Number / Email is already used for a bulk booking.", "warning" ); return; }
// ONLY IF NOT EXISTS → PROCEED TO SAVE submitBulkBooking(); } }); }
function submitBulkBooking() {
let idType = null; let idProofNumber = null;
if ($("#schoolCollegeCard").is(":visible")) { idType = $("#schoolCollegeCard .idProofSelect").val(); idProofNumber = $("#schoolCollegeCard .idProofNumber").val(); }
if ($("#organizationCard").is(":visible")) { idType = $("#organizationCard .idProofSelect").val(); idProofNumber = $("#organizationCard .idProofNumber").val(); }
let institutionName = null; let organizationName = null;
if ($("#schoolCollegeCard").is(":visible")) { institutionName = $("#privateInstitutionName").val(); }
if ($("#organizationCard").is(":visible")) { organizationName = $("#orgName").val(); }
const peopleDetails = []; userTypes.forEach(u => { if (u.count > 0) { peopleDetails.push({ id: u.id, count: u.count }); } });
const data = { name: $("#name").val(), userInput: $("#userinput").val(), visitDate: $("#preferdate").val(), categoryId: $("#category").val(), institutionName, organizationName, idType, idProofNumber, no_of_people: $("#totalPeople").text(), totalAmount: $("#totalAmount").text().replace("₹", ""), peopleDetails: JSON.stringify(peopleDetails), source: 1 };
$.ajax({ url: "/victoriapublichall/bookingapi/saveBulkRegistration", type: "POST", data: data, success: function (res) { Swal.fire({ title: "Request Submitted", text: "Your request has been raised successfully.\nRef ID: " + res.refId, icon: "success", allowOutsideClick: false, allowEscapeKey: false, confirmButtonText: "OK" }).then(() => { sessionStorage.setItem("bulkMobile", $("#userinput").val()); window.location.href = "/victoriapublichall/acknowledgement?refId=" + res.refId; }); } }); }
function goBack() { window.location.href = "/victoriapublichall"; }
$(document).ready(function () {
// Always keep submit disabled on load $("#submitBtn").prop("disabled", true);
// Enable submit only if checkbox is checked $("#termsCheck").on("change", function () { $("#submitBtn").prop("disabled", !this.checked); });
});
function allowOnlyAlphabets(input) { input.value = input.value.replace(/[^a-zA-Z\s]/g, ''); }
</script>
</body>
</html>
|