[
MAINHACK
]
Mail Test
BC
Config Scan
HOME
Create...
New File
New Folder
Viewing / Editing File: booking.php
<?php include("admin/includes/functions/functions.php");?> <?php include("db.php");?> <?php //$shopname = $_SESSION['business_name_Xw211qAAsq4']; $shopname = isset($_GET['shopname']) ? htmlspecialchars($_GET['shopname']) : null; ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?php echo $shopname;?></title> <!-- Include SweetAlert2 CSS and JS --> <link href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <style> body { font-family: 'Roboto', sans-serif; margin: 0; padding: 0; background-color: #f8f9fa; color: #333; } .header { background-color: #2c3e50; color: white; padding: 1rem; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); flex-wrap: wrap; position: relative; overflow: hidden; } .logo { display: flex; align-items: center; } .logo span { font-size: 1.5rem; margin-left: 0.5rem; } .info { display: flex; align-items: center; flex-wrap: wrap; } .info p { margin: 0 1rem 0 0; font-size: 0.9rem; } .buttons { display: flex; gap: 1rem; } .buttons button { background: none; border: 1px solid #fff; color: #fff; padding: 0.5rem 1rem; border-radius: 4px; cursor: pointer; transition: background 0.3s; } .buttons button:hover { background: #34495e; } /* Slider Styling */ .slider { position: relative; width: 40%; height: 100px; overflow: hidden; } .slider img { width: 100%; height: 100%; object-fit: cover; position: absolute; top: 0; left: 100%; transition: left 0.5s ease-in-out; } .slider img.active { left: 0; } .customer-details { margin-bottom: 1.5rem; background: #fff; padding: 1.5rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .customer-details h4 { color: #2c3e50; margin-bottom: 1.5rem; font-size: 1.3rem; border-bottom: 2px solid #3498db; padding-bottom: 0.5rem; } .customer-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } .customer-details label { display: block; margin-bottom: 0.4rem; font-weight: 500; color: #34495e; font-size: 0.95rem; } .customer-details input, .customer-details textarea { width: 100%; padding: 0.75rem; border: 1px solid #bdc3c7; border-radius: 4px; box-sizing: border-box; font-size: 1rem; transition: border-color 0.3s, box-shadow 0.3s; } .customer-details input:focus, .customer-details textarea:focus { border-color: #3498db; outline: none; box-shadow: 0 0 5px rgba(52, 152, 219, 0.3); } .customer-details textarea { height: 100px; resize: vertical; } .full-width { grid-column: 1 / -1; } .customer-details input:required:invalid:not(:placeholder-shown), .customer-details input:required:invalid:focus { border-color: #e74c3c; } .customer-details .required::after { content: ' *'; color: #e74c3c; } .customer-details input::placeholder, .customer-details textarea::placeholder { color: #95a5a6; font-style: italic; } .main { display: flex; flex-wrap: wrap; padding: 1rem; gap: 1rem; } .sidebar, .services, .hair-services, .cart { background-color: white; border-radius: 8px; padding: 1rem; border: 1px solid #e0e0e0; } .left-sidebar, .right-sidebar, .services, .hair-services { flex: 1 1 100%; } .services h2, .hair-services h2, .cart h3 { margin-top: 0; color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 0.5rem; font-size: clamp(1.2rem, 2.5vw, 1.5rem); } .services ul { list-style: none; padding: 0; } .services ul li { margin: 0.5rem 0; padding: 0.5rem; border-radius: 4px; transition: background-color 0.3s; cursor: pointer; } .services ul li:hover, .services ul li.active { background-color: #ecf0f1; } .hair-services .service { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem 0; border-bottom: 1px solid #e0e0e0; } .hair-services .service:last-child { border-bottom: none; } .cart .cart-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem; padding-bottom: 0.5rem; border-bottom: 1px solid #e0e0e0; } .cart .cart-header span { font-size: 0.9rem; color: #7f8c8d; } .cart .cart-item { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem 0; border-bottom: 1px solid #e0e0e0; } .cart .cart-item:last-child { border-bottom: none; } .cart .cart-item .item-name { font-weight: bold; } .cart .cart-item .item-duration { color: #7f8c8d; font-size: 0.9rem; } .cart .cart-total { margin-top: 1rem; text-align: right; } .cart .cart-action button { background-color: #16a085; border: none; color: white; padding: 0.75rem; cursor: pointer; border-radius: 4px; width: 100%; font-size: 1rem; transition: background-color 0.3s, transform 0.3s; } .cart .cart-action button:hover { background-color: #1abc9c; transform: scale(1.05); } .booking-form { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); z-index: 1001; justify-content: center; align-items: center; overflow-y: auto; } .booking-form.active { display: flex; } .booking-container { background-color: white; border-radius: 8px; padding: 1rem; width: 90%; max-width: 800px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); max-height: 90vh; overflow-y: auto; } .booking-section { margin-bottom: 1rem; } .booking-section h4 { margin: 0 0 0.5rem 0; font-size: 1rem; color: #2c3e50; } .staff-selection, .date-selection { display: flex; flex-wrap: wrap; gap: 0.5rem; } .staff-selection label, .date-selection button { padding: 0.5rem 0.75rem; border: 1px solid #bdc3c7; border-radius: 4px; cursor: pointer; background-color: white; transition: background-color 0.3s; } .staff-selection label:hover, .date-selection button:hover { background-color: #ecf0f1; } .staff-selection label.checked, .date-selection button.selected { background-color: #3498db; color: white; border-color: #3498db; } .time-selection { display: grid; grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 0.5rem; } .time-selection button { padding: 0.5rem; border: 1px solid #bdc3c7; border-radius: 4px; cursor: pointer; background-color: white; transition: background-color 0.3s; } .time-selection button:hover { background-color: #ecf0f1; } .time-selection button.selected { background-color: #3498db; color: white; border-color: #3498db; } .book-now button { background-color: #16a085; border: none; color: white; padding: 0.75rem; cursor: pointer; border-radius: 4px; width: 100%; font-size: 1rem; transition: background-color 0.3s, transform 0.3s; } .book-now button:hover { background-color: #1abc9c; transform: scale(1.05); } @media (max-width: 480px) { .header { flex-direction: column; align-items: flex-start; } .header .info { align-items: flex-start; width: 100%; } .header .buttons { flex-direction: column; width: 100%; } .header .buttons button { width: 100%; } .main { padding: 0.5rem; } .booking-container { width: 100%; border-radius: 0; height: 100%; max-height: 100vh; } .staff-selection, .date-selection { flex-direction: column; } .time-selection { grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); } } @media (min-width: 481px) and (max-width: 768px) { .header { flex-direction: row; } .header .buttons { flex-direction: row; } .main { flex-direction: column; } .booking-container { width: 95%; } } @media (min-width: 769px) { .main { flex-wrap: nowrap; } .left-sidebar, .right-sidebar { flex: 1 1 20%; position: sticky; top: 1rem; height: calc(100vh - 2rem); overflow-y: auto; } .left-sidebar { margin-right: 1rem; } .right-sidebar { margin-left: 1rem; flex: 1 1 30%; } .services, .hair-services { flex: 2 1 50%; margin: 0; } } @media (min-width: 1024px) { .header .logo img { width: 50px; } .header .logo h1 { font-size: 1.5rem; } .main { gap: 1.5rem; } } .close-btn { position: absolute; top: 10px; right: 0px; background: #e74c3c; color: white; border: none; border-radius: 50%; width: 30px; height: 30px; font-size: 1.2rem; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.3s; } .close-btn:hover { background: #c0392b; } .book-now button { background: #3498db; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; transition: background 0.3s; } .book-now button:hover { background: #2980b9; } .cart-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; padding: 0.5rem; border-bottom: 1px solid #ecf0f1; } .item-name, .item-duration { color: #34495e; margin-right: 1rem; } .item-price { color: #2c3e50; font-weight: 500; margin-right: 1rem; } .remove-btn { background: #e74c3c; color: white; border: none; border-radius: 4px; padding: 0.25rem 0.5rem; cursor: pointer; font-size: 0.8rem; transition: background 0.3s; } .remove-btn:hover { background: #c0392b; } .total { font-size: 1.1rem; font-weight: 500; color: #2c3e50; margin-top: 1rem; } .search-bar { margin-bottom: 1rem; } #service-search { width: 100%; padding: 0.75rem; border: 1px solid #bdc3c7; border-radius: 4px; font-size: 1rem; box-sizing: border-box; transition: border-color 0.3s, box-shadow 0.3s; } #service-search:focus { border-color: #3498db; outline: none; box-shadow: 0 0 5px rgba(52, 152, 219, 0.3); } #service-search::placeholder { color: #95a5a6; font-style: italic; } button.disabled { opacity: 0.4; cursor: not-allowed; } </style> </head> <body> <div class="header"> <div class="logo"> <!--<span>m</span>--> <span><?php echo $shopname;?></span> </div> <div class="info"> <p>ⓘ 9:00 AM to 9:00 PM</p> <div class="buttons"> <!-- <button>Book Now</button> --> <button>Guest Booking</button> </div> </div> <!-- <div class="slider"> <img src="https://via.placeholder.com/300x100?text=Image+1" class="active" alt="Salon Image 1"> <img src="https://via.placeholder.com/300x100?text=Image+2" alt="Salon Image 2"> <img src="https://via.placeholder.com/300x100?text=Image+3" alt="Salon Image 3"> </div> --> </div> <div class="main"> <div class="sidebar left-sidebar"> <div class="services"> <h2>Categories</h2> <ul id="category-list"> <?php try { $stmt = $con->query("SELECT category_id, category_name FROM service_categories WHERE cat_status = '1' and business_name = '$shopname'"); if ($stmt->rowCount() == 0) { echo "<li>No categories found</li>"; } while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo '<li class="category-item" data-category-id="' . htmlspecialchars($row['category_id']) . '">' . htmlspecialchars($row['category_name']) . '</li>'; } } catch (PDOException $e) { echo "<li>Error: " . $e->getMessage() . "</li>"; } ?> </ul> </div> </div> <!-- <div class="hair-services" id="service-display"> <h2>Services</h2> <div id="service-list"></div> </div> --> <div class="hair-services" id="service-display"> <h2>Services</h2> <!-- Add Search Input --> <div class="search-bar"> <input type="text" id="service-search" placeholder="Search services..." onkeyup="searchServices()"> </div> <div id="service-list"></div> </div> <div class="sidebar right-sidebar"> <div class="cart" id="cart"> <div class="cart-empty" id="cart-empty"> <div class="icon">📦</div> <h5>Your Cart is Empty</h5> <!-- <p>Good looks always gives you the confidence! Go ahead, select some services.</p> --> </div> <div class="cart-header"> <span id="cart-count">0 SERVICES</span> </div> <div id="cart-items"></div> <div class="cart-total"> <div class="total">Total <span id="cart-total">0.00</span></div> </div> <div class="cart-action"> <button onclick="showBookingForm()">Select Staff, Date & Time</button> </div> </div> </div> </div> <div class="booking-form" id="bookingForm"> <div class="booking-container"> <div class="booking-section customer-details"> <h4>Customer Details</h4><button class="close-btn" onclick="closeBookingForm()">×</button> <div class="customer-form-grid"> <div> <label for="first_name" class="required">First name</label> <input type="text" id="first_name" placeholder="Enter your full name" required> </div> <div> <label for="customer_name" class="required">Last Name</label> <input type="text" id="last_name" placeholder="Enter your full name" required> </div> <div> <label for="customer_email" class="required">Email</label> <input type="email" id="customer_email" placeholder="Enter your email" required> </div> <div> <label for="customer_phone" class="required">Phone Number</label> <input type="tel" id="customer_phone" placeholder="Enter your phone number" required> </div> <!-- <div class="full-width"> <label for="booking_note">Booking Note</label> <textarea id="booking_note" placeholder="Any special requests or notes (optional)"></textarea> </div> --> </div> </div> <div class="booking-section"> <h4>Select Staff</h4> <div class="staff-selection"> <!-- <label><input type="radio" name="staff" value="no-preference" checked> No preference</label> --> <?php try { $stmt = $con->query("SELECT employee_id, first_name, last_name FROM employees WHERE status = 'active' AND business_name = '$shopname'"); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $employee_name = $row['first_name'] . ' ' . $row['last_name']; echo '<label><input type="radio" name="staff" value="' . htmlspecialchars($row['employee_id']) . '">' . htmlspecialchars($employee_name) . '</label>'; } } catch (PDOException $e) { // Output JavaScript to trigger SweetAlert2 echo '<script> Swal.fire({ icon: "error", title: "Error Fetching Employees", text: "Select at least one stylist", confirmButtonText: "OK", confirmButtonColor: "#3085d6" }); </script>'; } ?> </div> </div> <div class="booking-section"> <h2>Select Date</h2> <div class="date-selection" id="date-selection"></div> </div> <div class="booking-section"> <h4>Select Time</h4> <div class="time-selection" id="time-selection"></div> </div> <div class="cart-summary"> <h4>Cart</h4> <div id="cart-summary-items"></div> <p>Date & Time: <span id="selectedDateTime"></span></p> <p>Total: <span id="summary-total">0.00</span></p> </div> <div class="book-now"> <button onclick="bookNow()">Book Now</button> </div> </div> </div> <script> let cart = []; // Ensure cart is globally accessible let slideIndex = 0; const slides = document.querySelectorAll('.slider img'); document.addEventListener('DOMContentLoaded', () => { const categoryItems = document.querySelectorAll('.category-item'); categoryItems.forEach(item => { item.addEventListener('click', () => { categoryItems.forEach(i => i.classList.remove('active')); item.classList.add('active'); const categoryId = item.getAttribute('data-category-id'); loadServices(categoryId); }); }); // Load all services initially if no category is selected if (categoryItems.length > 0) { loadServices(); } else { loadServices(); } generateWeekDates(); generateTimeSlots(); startSlider(); updateCartDisplay(); // Initialize cart display }); function startSlider() { setInterval(() => { slides.forEach(slide => slide.classList.remove('active')); slideIndex = (slideIndex + 1) % slides.length; slides[slideIndex].classList.add('active'); }, 3000); } function generateWeekDates() { const dateSelection = document.getElementById('date-selection'); if (!dateSelection) return; const today = new Date(); const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; dateSelection.innerHTML = ''; for (let i = 0; i < 7; i++) { const date = new Date(today); // Clone today date.setDate(today.getDate() + i); // Add days const dayName = days[date.getDay()]; const day = date.getDate(); const month = date.toLocaleString('default', { month: 'short' }); const dateStr = `${dayName} ${day} ${month}`; const button = document.createElement('button'); button.textContent = dateStr; button.setAttribute('data-date', date.toISOString().split('T')[0]); if (i === 0) button.classList.add('selected'); button.addEventListener('click', () => selectDate(button)); dateSelection.appendChild(button); } } // function generateWeekDates() { // const dateSelection = document.getElementById('date-selection'); // const today = new Date(); // const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; // dateSelection.innerHTML = ''; // for (let i = 0; i < 7; i++) { // const date = new Date(today); // date.setDate(today.getDate() + i); // const dayName = days[date.getDay()]; // const day = date.getDate(); // const month = date.toLocaleString('default', { month: 'short' }); // const dateStr = `${dayName} ${day} ${month}`; // const button = document.createElement('button'); // button.textContent = dateStr; // button.setAttribute('data-date', date.toISOString().split('T')[0]); // if (i === 0) button.classList.add('selected'); // button.onclick = () => selectDate(button); // dateSelection.appendChild(button); // } // } // function generateTimeSlots(selectedDate) { // const timeSelection = document.getElementById('time-selection'); // timeSelection.innerHTML = ''; // const startHour = 8; // const endHour = 21; // 9:00 PM // let firstSlot = true; // for (let hour = startHour; hour < endHour; hour++) { // for (let minute of [0, 30]) { // const date = new Date(selectedDate); // date.setHours(hour, minute, 0, 0); // const displayHour = hour > 12 ? hour - 12 : hour === 0 ? 12 : hour; // const period = hour >= 12 ? 'PM' : 'AM'; // const timeStr = `${displayHour}:${minute.toString().padStart(2, '0')} ${period}`; // const button = document.createElement('button'); // button.textContent = timeStr; // button.setAttribute('data-time', date.toISOString()); // button.onclick = () => selectTime(button); // if (firstSlot) { // button.classList.add('selected'); // firstSlot = false; // } // timeSelection.appendChild(button); // } // } // } function generateTimeSlots(selectedDateStr) { const timeSelection = document.getElementById('time-selection'); timeSelection.innerHTML = ''; const startHour = 8; const endHour = 21; // up to 9:00 PM const now = new Date(); const selectedDate = new Date(selectedDateStr); const isToday = now.toDateString() === selectedDate.toDateString(); let firstEnabledSlot = true; for (let hour = startHour; hour < endHour; hour++) { for (let minute of [0, 30]) { const slotTime = new Date(selectedDate); slotTime.setHours(hour, minute, 0, 0); const displayHour = hour > 12 ? hour - 12 : hour === 0 ? 12 : hour; const period = hour >= 12 ? 'PM' : 'AM'; const timeStr = `${displayHour}:${minute.toString().padStart(2, '0')} ${period}`; const button = document.createElement('button'); button.textContent = timeStr; button.setAttribute('data-time', slotTime.toISOString()); const isPast = isToday && slotTime < now; if (isPast) { button.disabled = true; button.classList.add('disabled'); } else { button.onclick = () => selectTime(button); if (firstEnabledSlot) { button.classList.add('selected'); firstEnabledSlot = false; } } timeSelection.appendChild(button); } } } // Global variable to store all services let allServices = []; function loadServices(categoryId) { const urlParams = new URLSearchParams(window.location.search); const shopname = urlParams.get('shopname') || ''; const effectiveCategoryId = categoryId || null; fetch(`get_services.php?category_id=${effectiveCategoryId}&shopname=${encodeURIComponent(shopname)}`) .then(response => { if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); return response.text(); }) .then(text => { console.log('Raw response from get_services.php:', text); try { const data = JSON.parse(text); const serviceList = document.getElementById('service-list'); serviceList.innerHTML = ''; if (data.error) { serviceList.innerHTML = `<p>${data.error}</p>`; return; } if (data.length === 0) { serviceList.innerHTML = '<p>No services available</p>'; return; } // Store the services globally for filtering allServices = data; // Display all services initially displayServices(allServices); } catch (e) { document.getElementById('service-list').innerHTML = `<p>Error parsing JSON: ${e.message}. Raw response: ${text.substring(0, 100)}...</p>`; console.error('JSON parsing error:', e, 'Raw response:', text); } }) .catch(error => { document.getElementById('service-list').innerHTML = `<p>Error loading services: ${error.message}</p>`; console.error('Fetch error:', error); }); } function displayServices(services) { const serviceList = document.getElementById('service-list'); const searchInput = document.getElementById('service-search').value.toLowerCase(); serviceList.innerHTML = ''; if (services.length === 0) { serviceList.innerHTML = '<p>No services found</p>'; return; } services.forEach(service => { const durationDisplay = service.service_duration >= 60 ? `${Math.floor(service.service_duration / 60)} Hr${service.service_duration % 60 > 0 ? ` ${service.service_duration % 60} Mins` : ''}` : `${service.service_duration} Mins`; // Highlight the search term in the service name const serviceName = searchInput ? service.service_name.replace( new RegExp(searchInput, 'gi'), match => `<span class="highlight">${match}</span>` ) : service.service_name; const serviceDiv = document.createElement('div'); serviceDiv.className = 'service'; serviceDiv.innerHTML = ` <label> <input type="checkbox" name="hair-service" value="${service.service_price}" data-service-id="${service.service_id}" data-service-name="${service.service_name}" data-duration="${service.service_duration}" onchange="updateCart(this)"> ${serviceName}<br><small>${durationDisplay}</small> </label> <span>GHC ${parseFloat(service.service_price).toFixed(2)}</span> `; serviceList.appendChild(serviceDiv); }); } // Function to filter services based on search input function searchServices() { const searchInput = document.getElementById('service-search').value.toLowerCase(); const filteredServices = allServices.filter(service => service.service_name.toLowerCase().includes(searchInput) ); displayServices(filteredServices); } function updateCart(checkbox) { const servicePrice = parseFloat(checkbox.value); const serviceId = checkbox.getAttribute('data-service-id'); const serviceName = checkbox.getAttribute('data-service-name'); const serviceDuration = parseInt(checkbox.getAttribute('data-duration')); // Find if the item already exists in the cart const existingItemIndex = cart.findIndex(item => item.service_id === serviceId); if (checkbox.checked) { // Add item if it doesn't exist if (existingItemIndex === -1) { cart.push({ service_id: serviceId, name: serviceName, price: servicePrice, duration: serviceDuration }); } } else { // Remove item if unchecked if (existingItemIndex !== -1) { cart.splice(existingItemIndex, 1); } } updateCartDisplay(); } function removeFromCart(serviceId) { // Find and remove the item from the cart const existingItemIndex = cart.findIndex(item => item.service_id === serviceId); if (existingItemIndex !== -1) { cart.splice(existingItemIndex, 1); // Uncheck the corresponding checkbox if it exists const checkbox = document.querySelector(`input[data-service-id="${serviceId}"]`); if (checkbox) { checkbox.checked = false; } updateCartDisplay(); } } function updateCartDisplay() { const cartEmpty = document.getElementById('cart-empty'); const cartHeader = document.querySelector('.cart-header'); const cartItems = document.getElementById('cart-items'); const cartTotal = document.querySelector('.cart-total'); const cartAction = document.querySelector('.cart-action'); if (cart.length === 0) { cartEmpty.style.display = 'flex'; cartHeader.classList.remove('active'); cartItems.classList.remove('active'); cartTotal.classList.remove('active'); cartAction.classList.remove('active'); } else { cartEmpty.style.display = 'none'; cartHeader.classList.add('active'); cartItems.classList.add('active'); cartTotal.classList.add('active'); cartAction.classList.add('active'); cartItems.innerHTML = ''; cart.forEach(item => { const durationDisplay = item.duration >= 60 ? `${Math.floor(item.duration / 60)} Hr${item.duration % 60 > 0 ? ` ${item.duration % 60} Mins` : ''}` : `${item.duration} Mins`; cartItems.innerHTML += ` <div class="cart-item"> <div> <div class="item-name">${item.name}</div> <div class="item-duration">${durationDisplay}</div> </div> <div class="item-price">${item.price.toFixed(2)}</div> <button class="remove-btn" onclick="removeFromCart('${item.service_id}')">X</button> </div> `; }); const total = cart.reduce((sum, item) => sum + item.price, 0); document.getElementById('cart-count').textContent = `${cart.length} SERVICES`; document.getElementById('cart-total').textContent = `${total.toFixed(2)}`; document.getElementById('summary-total').textContent = `${total.toFixed(2)}`; } } function showBookingForm() { if (cart.length === 0) { Swal.fire({ icon: 'warning', title: 'No Services Selected', text: 'Please select at least one service before proceeding to booking.', confirmButtonText: 'OK', confirmButtonColor: '#3085d6' }); return; } document.getElementById('bookingForm').classList.add('active'); } function closeBookingForm() { document.getElementById('bookingForm').classList.remove('active'); } // function selectDate(button) { // document.querySelectorAll('.date-selection button').forEach(btn => btn.classList.remove('selected')); // button.classList.add('selected'); // updateSelectedDateTime(); // } function selectDate(button) { document.querySelectorAll('#date-selection button').forEach(btn => btn.classList.remove('selected') ); button.classList.add('selected'); const selectedDate = button.getAttribute('data-date'); generateTimeSlots(selectedDate); } function selectTime(button) { document.querySelectorAll('.time-selection button').forEach(btn => btn.classList.remove('selected')); button.classList.add('selected'); updateSelectedDateTime(); } function updateSelectedDateTime() { const selectedDate = document.querySelector('.date-selection button.selected'); const selectedTime = document.querySelector('.time-selection button.selected'); if (selectedDate && selectedTime) { document.getElementById('selectedDateTime').textContent = `${selectedDate.textContent}, ${selectedTime.textContent} 2025`; } } function formatTimeToMySQL(timeStr) { const [time, period] = timeStr.split(' '); let [hours, minutes] = time.split(':'); hours = parseInt(hours); if (period === 'PM' && hours !== 12) hours += 12; if (period === 'AM' && hours === 12) hours = 0; return `${hours.toString().padStart(2, '0')}:${minutes}:00`; } function bookNow() { if (cart.length === 0) { Swal.fire({ icon: 'warning', title: 'No Services Selected', text: 'Please select at least one service.', confirmButtonText: 'OK', confirmButtonColor: '#3085d6' }); return; } const selectedDateButton = document.querySelector('.date-selection button.selected'); const selectedTimeButton = document.querySelector('.time-selection button.selected'); const selectedStaff = document.querySelector('input[name="staff"]:checked').value; const firstname = document.getElementById('first_name').value.trim(); const lastname = document.getElementById('last_name').value.trim(); const customerEmail = document.getElementById('customer_email').value.trim(); const customerPhone = document.getElementById('customer_phone').value.trim(); //const bookingNote = document.getElementById('booking_note').value.trim(); // Extract shopname from URL const urlParams = new URLSearchParams(window.location.search); const shopname = urlParams.get('shopname') || ''; if (!selectedDateButton || !selectedTimeButton) { Swal.fire({ icon: 'warning', title: 'Missing Date/Time', text: 'Please select date and time.', confirmButtonText: 'OK', confirmButtonColor: '#3085d6' }); return; } if (!firstname || !lastname || !customerEmail || !customerPhone) { Swal.fire({ icon: 'warning', title: 'Incomplete Details', text: 'Please fill in all required customer details.', confirmButtonText: 'OK', confirmButtonColor: '#3085d6' }); return; } if (!shopname) { Swal.fire({ icon: 'error', title: 'Shopname Missing', text: 'Shopname is missing from the URL.', confirmButtonText: 'OK', confirmButtonColor: '#3085d6' }); return; } const total = cart.reduce((sum, item) => sum + item.price, 0); const bookingTime = formatTimeToMySQL(selectedTimeButton.textContent); const bookingData = { employee_id: selectedStaff, shopname: shopname, booking_date: selectedDateButton.getAttribute('data-date'), booking_time: bookingTime, total_amount: total, customer_first: firstname, customer_last: lastname, customer_email: customerEmail, customer_phone: customerPhone, // booking_note: bookingNote, services: cart.map(item => ({ service_id: item.service_id, price: item.price })) }; console.log('Sending booking data:', bookingData); fetch('save_booking.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(bookingData) }) .then(response => { console.log('Response status:', response.status); if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } return response.text(); }) .then(text => { console.log('Raw response:', text); try { const data = JSON.parse(text); if (data.success) { Swal.fire({ icon: 'success', title: 'Booking Confirmed!', text: `Booking successful! Your booking ID is ${data.booking_id}`, confirmButtonText: 'OK', confirmButtonColor: '#3085d6' }).then(() => { document.getElementById('bookingForm').classList.remove('active'); cart = []; updateCartDisplay(); document.getElementById('customer_first').value = ''; document.getElementById('customer_last').value = ''; document.getElementById('customer_email').value = ''; document.getElementById('customer_phone').value = ''; // document.getElementById('booking_note').value = ''; }); } else { Swal.fire({ icon: 'error', title: 'Booking Failed', text: `Booking failed: ${data.message}`, confirmButtonText: 'OK', confirmButtonColor: '#3085d6' }); } } catch (e) { throw new Error('Invalid JSON: ' + e.message); } }) .catch(error => { console.error('Fetch error:', error); Swal.fire({ icon: 'error', title: 'Error', text: `Error saving booking: ${error.message}`, confirmButtonText: 'OK', confirmButtonColor: '#3085d6' }); }); } </script> </body> </html>
Save Changes
Cancel / Back
Close ×
Server Info
Hostname: server1.winmanyltd.com
Server IP: 203.161.60.52
PHP Version: 8.3.27
Server Software: Apache
System: Linux server1.winmanyltd.com 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64
HDD Total: 117.98 GB
HDD Free: 59.71 GB
Domains on IP: N/A (Requires external lookup)
System Features
Safe Mode:
Off
disable_functions:
None
allow_url_fopen:
On
allow_url_include:
Off
magic_quotes_gpc:
Off
register_globals:
Off
open_basedir:
None
cURL:
Enabled
ZipArchive:
Enabled
MySQLi:
Enabled
PDO:
Enabled
wget:
Yes
curl (cmd):
Yes
perl:
Yes
python:
Yes (py3)
gcc:
Yes
pkexec:
Yes
git:
Yes
User Info
Username: eliosofonline
User ID (UID): 1002
Group ID (GID): 1003
Script Owner UID: 1002
Current Dir Owner: 1002