// ==================== MOCK DATA ====================
var bookings = [];
var currentDate = new Date(2026, 2, 1); // March 2026
var currentView = "month";
var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var dayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
// ==================== INIT ====================
document.addEventListener("DOMContentLoaded", function () {
updateUserInfo();
setupSidebar();
fetchBookings();
});
function fetchBookings() {
fetch('/api/calendar-bookings')
.then(function (response) {
console.log("STATUS:", response.status); // 👈 ADD
return response.json();
})
.then(function (data) {
console.log("DATA:", data); // 👈 ADD
bookings = data;
renderCalendar();
})
.catch(function (error) {
console.error("Error fetching bookings:", error);
});
}
function updateUserInfo() {
var name = sessionStorage.getItem("userName") || "Admin";
var role = sessionStorage.getItem("userRole") || "admin";
var roleNames = { "super-admin": "Super Administrator", "admin": "Administrator", "sub-admin": "Service Provider" };
document.getElementById("navUserName").textContent = name;
document.getElementById("sidebarName").textContent = name;
document.getElementById("sidebarAvatar").textContent = name.charAt(0).toUpperCase();
document.getElementById("sidebarRole").textContent = roleNames[role] || "Administrator";
}
function setupSidebar() {
var role = sessionStorage.getItem("userRole");
var isSuperAdmin = (role === "super-admin");
var userMgmtMenu = document.getElementById("userMgmtMenu");
if (userMgmtMenu) userMgmtMenu.style.display = isSuperAdmin ? "block" : "none";
var activityLogMenu = document.getElementById("activityLogMenu");
if (activityLogMenu) activityLogMenu.style.display = isSuperAdmin ? "block" : "none";
}
// ==================== VIEW TOGGLE ====================
function switchView(view) {
currentView = view;
document.querySelectorAll(".view-btn").forEach(function (btn) {
btn.classList.toggle("active", btn.dataset.view === view);
});
document.getElementById("monthView").style.display = view === "month" ? "block" : "none";
document.getElementById("weekView").style.display = view === "week" ? "block" : "none";
renderCalendar();
}
// ==================== NAVIGATION ====================
function navigateCal(direction) {
if (currentView === "month") {
currentDate.setMonth(currentDate.getMonth() + direction);
} else {
currentDate.setDate(currentDate.getDate() + (direction * 7));
}
renderCalendar();
}
function goToday() {
currentDate = new Date(2026, 2, 23); // Today: March 23, 2026
renderCalendar();
}
// ==================== RENDER ====================
function renderCalendar() {
if (currentView === "month") {
renderMonthView();
} else {
renderWeekView();
}
document.getElementById("calTitle").textContent = monthNames[currentDate.getMonth()] + " " + currentDate.getFullYear();
}
// ==================== MONTH VIEW ====================
function renderMonthView() {
var year = currentDate.getFullYear();
var month = currentDate.getMonth();
var firstDay = new Date(year, month, 1).getDay();
var daysInMonth = new Date(year, month + 1, 0).getDate();
var daysInPrevMonth = new Date(year, month, 0).getDate();
var today = new Date(2026, 2, 23);
var html = "";
// Previous month days
for (var i = firstDay - 1; i >= 0; i--) {
var day = daysInPrevMonth - i;
html += '
';
html += '
' + day + '
';
html += '
';
}
// Current month days
for (var d = 1; d <= daysInMonth; d++) {
var dateStr = year + "-" + String(month + 1).padStart(2, "0") + "-" + String(d).padStart(2, "0"); var dayBookings = getBookingsForDate(dateStr);
var isToday = (today.getFullYear() === year && today.getMonth() === month && today.getDate() === d);
var hasBooking = dayBookings.length > 0;
var cellClass = "cal-cell";
if (isToday) cellClass += " today";
if (!hasBooking) cellClass += " available-day";
html += '
';
html += '
' + d + '
';
// Show booking events (max 3)
var shown = Math.min(dayBookings.length, 3);
for (var b = 0; b < shown; b++) {
var bk = dayBookings[b];
html += '
' + bk.customerName + ' - ' + bk.bookingType + '
';
}
if (dayBookings.length > 3) {
html += '
+' + (dayBookings.length - 3) + ' more
';
}
if (!hasBooking) {
html += 'Available';
}
html += '
';
}
// Next month days
var totalCells = firstDay + daysInMonth;
var remaining = totalCells % 7 === 0 ? 0 : 7 - (totalCells % 7);
for (var n = 1; n <= remaining; n++) {
html += '
';
html += '
' + n + '
';
html += '
';
}
document.getElementById("calBody").innerHTML = html;
}
// ==================== WEEK VIEW ====================
function renderWeekView() {
var startOfWeek = new Date(currentDate);
var dayOfWeek = startOfWeek.getDay();
startOfWeek.setDate(startOfWeek.getDate() - dayOfWeek);
var today = new Date(2026, 2, 23);
var html = "";
for (var d = 0; d < 7; d++) {
var day = new Date(startOfWeek);
day.setDate(startOfWeek.getDate() + d);
var isToday = (day.getDate() === today.getDate() && day.getMonth() === today.getMonth() && day.getFullYear() === today.getFullYear());
var dateStr = day.getFullYear() + "-" + String(day.getMonth() + 1).padStart(2, "0") + "-" + String(day.getDate()).padStart(2, "0");
var dayBookings = getBookingsForDate(dateStr);
html += '
';
html += '
';
html += '' + dayNamesShort[d] + '';
html += '' + day.getDate() + '';
html += '
';
// 17 time slots (6 AM to 10 PM)
for (var h = 6; h <= 22; h++) {
html += '
';
// Check if any booking covers this hour
dayBookings.forEach(function (bk) {
var startHour = 6;
var endHour = 23;
if (bk.bookingType === "Full Day") {
startHour = 6; endHour = 23;
} else if (bk.bookingType === "Half Day") {
if (bk.halfDaySlot === "Evening") { startHour = 14; endHour = 23; }
else { startHour = 6; endHour = 14; }
} else if (bk.bookingType === "Hourly" && bk.startTime) {
startHour = parseInt(bk.startTime.split(":")[0]);
endHour = parseInt(bk.endTime.split(":")[0]);
}
if (h === startHour && bk.status !== "cancelled") {
var height = (endHour - startHour) * 50;
html += '
' +
bk.customerName + ' - ' + bk.bookingType + '
';
}
});
html += '
';
}
html += '
';
}
document.getElementById("weekDays").innerHTML = html;
// Update title for week view
var endOfWeek = new Date(startOfWeek);
endOfWeek.setDate(startOfWeek.getDate() + 6);
document.getElementById("calTitle").textContent =
monthNames[startOfWeek.getMonth()] + " " + startOfWeek.getDate() + " - " +
monthNames[endOfWeek.getMonth()] + " " + endOfWeek.getDate() + ", " + endOfWeek.getFullYear();
}
// ==================== DETAIL MODAL ====================
function openDetail(year, month, day) {
var date = new Date(year, month, day);
var dateStr = year + "-" + String(month + 1).padStart(2, "0") + "-" + String(day).padStart(2, "0");
var dayBookings = getBookingsForDate(dateStr);
document.getElementById("detailDate").textContent = monthNames[month] + " " + day + ", " + year;
document.getElementById("detailDay").textContent = dayNames[date.getDay()];
var body = document.getElementById("detailBody");
if (dayBookings.length === 0) {
body.innerHTML = '