Created
January 3, 2025 13:22
-
-
Save SitesByYogi/d44f081714c91c839304752d6508b521 to your computer and use it in GitHub Desktop.
Booking Calendar Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Enqueue necessary scripts and styles for the booking calendar | |
function booking_calendar_assets() { | |
wp_enqueue_script('moment-js', 'https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js', [], null, true); | |
wp_enqueue_script('fullcalendar-js', 'https://cdn.jsdelivr.net/npm/[email protected]/main.min.js', ['moment-js'], null, true); | |
wp_enqueue_style('fullcalendar-css', 'https://cdn.jsdelivr.net/npm/[email protected]/main.min.css', [], null); | |
wp_add_inline_script( | |
'fullcalendar-js', | |
" | |
document.addEventListener('DOMContentLoaded', function () { | |
const timeSlots = [ | |
'7:00 AM', '8:00 AM', '9:00 AM', '10:00 AM', '11:00 AM', | |
'12:00 PM', '1:00 PM', '2:00 PM', '3:00 PM', '4:00 PM', | |
'5:00 PM', '6:00 PM' | |
]; | |
const timeSlotsContainer = document.getElementById('time-slots'); | |
let lastSelectedDate = null; | |
let selectedDate = null; | |
let selectedTime = null; | |
function formatDate(dateStr) { | |
const date = new Date(dateStr); | |
return new Intl.DateTimeFormat('en-US', { | |
weekday: 'long', | |
year: 'numeric', | |
month: 'long', | |
day: 'numeric' | |
}).format(date); | |
} | |
function renderTimeSlots(dateStr) { | |
const formattedDate = formatDate(dateStr); | |
selectedDate = dateStr; | |
timeSlotsContainer.innerHTML = ''; | |
const message = document.createElement('p'); | |
message.textContent = `Available Times ${formattedDate}`; | |
message.style.marginBottom = '10px'; | |
timeSlotsContainer.appendChild(message); | |
jQuery.ajax({ | |
url: '" . admin_url('admin-ajax.php') . "', | |
method: 'POST', | |
data: { | |
action: 'booking_calendar_get_booked_slots', | |
date: dateStr, | |
}, | |
success: function (response) { | |
const bookedTimes = response.success ? response.data.booked_times : []; | |
const slotsWrapper = document.createElement('div'); | |
slotsWrapper.classList.add('slots-wrapper'); | |
timeSlots.slice(0, 9).forEach(time => { // Limit to 9 slots | |
const timeSlot = document.createElement('div'); | |
timeSlot.classList.add('time-slot'); | |
timeSlot.textContent = time; | |
if (bookedTimes.includes(time)) { | |
timeSlot.classList.add('disabled'); | |
timeSlot.textContent += ' (Booked)'; | |
} else { | |
timeSlot.addEventListener('click', () => { | |
selectTimeSlot(timeSlot); | |
selectedTime = time; | |
}); | |
} | |
slotsWrapper.appendChild(timeSlot); | |
}); | |
timeSlotsContainer.appendChild(slotsWrapper); | |
const submitButton = document.createElement('button'); | |
submitButton.textContent = 'Submit Booking'; | |
submitButton.classList.add('submit-button'); | |
submitButton.addEventListener('click', submitBooking); | |
timeSlotsContainer.appendChild(submitButton); | |
}, | |
error: function () { | |
alert('Failed to fetch booked slots.'); | |
} | |
}); | |
} | |
function selectTimeSlot(selectedSlot) { | |
document.querySelectorAll('.time-slot').forEach(slot => { | |
slot.classList.remove('selected'); | |
}); | |
selectedSlot.classList.add('selected'); | |
} | |
function submitBooking() { | |
if (!selectedDate || !selectedTime) { | |
alert('Please select a date and time before submitting.'); | |
return; | |
} | |
jQuery.ajax({ | |
url: '" . admin_url('admin-ajax.php') . "', | |
method: 'POST', | |
data: { | |
action: 'booking_calendar_send_email', | |
date: selectedDate, | |
time: selectedTime, | |
}, | |
success: function (response) { | |
if (response.success) { | |
alert('Booking submitted successfully!'); | |
selectedDate = null; | |
selectedTime = null; | |
timeSlotsContainer.innerHTML = ''; | |
} else { | |
alert('Failed to submit booking: ' + response.data.message); | |
} | |
}, | |
error: function () { | |
alert('An error occurred while submitting the booking.'); | |
} | |
}); | |
} | |
const calendarEl = document.getElementById('calendar'); | |
const calendar = new FullCalendar.Calendar(calendarEl, { | |
initialView: 'dayGridMonth', | |
validRange: { | |
start: new Date().toISOString().split('T')[0] | |
}, | |
dateClick: function (info) { | |
if (lastSelectedDate) { | |
lastSelectedDate.classList.remove('selected-date'); | |
} | |
info.dayEl.classList.add('selected-date'); | |
lastSelectedDate = info.dayEl; | |
renderTimeSlots(info.dateStr); | |
} | |
}); | |
calendar.render(); | |
}); | |
" | |
); | |
} | |
add_action('wp_enqueue_scripts', 'booking_calendar_assets'); | |
// Shortcode to display the booking calendar | |
function booking_calendar_shortcode() { | |
ob_start(); | |
?> | |
<div class="booking-calendar"> | |
<div id="calendar" class="calendar"></div> | |
<div id="time-slots" class="time-slots"></div> | |
</div> | |
<style> | |
.booking-calendar { | |
font-family: Arial, sans-serif; | |
text-align: center; | |
margin: 20px auto; | |
padding: 20px; | |
border-radius: 10px; | |
max-width: 800px; | |
} | |
.calendar { | |
margin: 20px auto; | |
} | |
.time-slots { | |
margin-top: 20px; | |
} | |
.time-slots p { | |
font-size: 1.2em; | |
font-weight: bold; | |
} | |
.slots-wrapper { | |
display: grid; | |
grid-template-columns: repeat(3, 1fr); /* 3 columns */ | |
gap: 10px; /* Space between slots */ | |
margin-top: 10px; | |
justify-items: center; /* Center align items */ | |
max-width: 300px; /* Optional: set a width for the grid container */ | |
margin: 0 auto; /* Center the grid container */ | |
} | |
.time-slot { | |
padding: 0px 40px; | |
background-color: #ffffff; | |
color: #000000; | |
border: 1px solid #cccccc; | |
border-radius: 5px; | |
cursor: pointer; | |
text-align: center; | |
transition: background-color 0.3s ease, color 0.3s ease; | |
} | |
.time-slot:hover { | |
background-color: #f0f0f0; | |
} | |
.time-slot.selected { | |
background-color: #ff0000; | |
color: #ffffff; | |
border-color: #ff0000; | |
} | |
.time-slot.disabled { | |
background-color: #cccccc; | |
color: #666666; | |
cursor: not-allowed; | |
} | |
.selected-date { | |
background-color: red !important; | |
color: white !important; | |
border-radius: 0%; | |
transition: background-color 0.3s ease; | |
} | |
.submit-button { | |
padding: 10px 20px; | |
background-color: #18496D; | |
color: white; | |
border: none; | |
border-radius: 5px; | |
cursor: pointer; | |
margin-top: 20px; | |
} | |
.submit-button:hover { | |
background-color: #0056b3; | |
} | |
</style> | |
<?php | |
return ob_get_clean(); | |
} | |
add_shortcode('booking_calendar', 'booking_calendar_shortcode'); | |
// AJAX handler for booking email submission | |
function booking_calendar_send_email() { | |
if (!isset($_POST['date']) || !isset($_POST['time'])) { | |
wp_send_json_error(['message' => 'Date and time are required.']); | |
} | |
$date = sanitize_text_field($_POST['date']); | |
$time = sanitize_text_field($_POST['time']); | |
$admin_email = get_option('admin_email'); | |
$subject = 'New Booking Request'; | |
$message = "A new booking has been made.\n\nDate: $date\nTime: $time"; | |
if (wp_mail($admin_email, $subject, $message)) { | |
wp_send_json_success(['message' => 'Booking email sent successfully.']); | |
} else { | |
wp_send_json_error(['message' => 'Failed to send email.']); | |
} | |
} | |
add_action('wp_ajax_booking_calendar_send_email', 'booking_calendar_send_email'); | |
add_action('wp_ajax_nopriv_booking_calendar_send_email', 'booking_calendar_send_email'); | |
// AJAX handler to fetch booked time slots | |
function booking_calendar_get_booked_slots() { | |
if (!isset($_POST['date'])) { | |
wp_send_json_error(['message' => 'Date is required.']); | |
} | |
$date = sanitize_text_field($_POST['date']); | |
// Mock data: Replace with a database query to get actual booked slots | |
$booked_slots = [ | |
'2025-01-02' => ['10:00 AM', '2:00 PM'], | |
'2025-01-03' => ['9:00 AM', '3:00 PM'] | |
]; | |
$booked_times = isset($booked_slots[$date]) ? $booked_slots[$date] : []; | |
wp_send_json_success(['booked_times' => $booked_times]); | |
} | |
add_action('wp_ajax_booking_calendar_get_booked_slots', 'booking_calendar_get_booked_slots'); | |
add_action('wp_ajax_nopriv_booking_calendar_get_booked_slots', 'booking_calendar_get_booked_slots'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment