Smart Business Meeting Room Reservation System

Smart Business Meeting Room Reservation System

Today's Schedule

${room.amenities.join(', ')}

`).join(''); } // --- TAB NAVIGATION --- function setActiveTab(tabId) { currentTab = tabId; tabButtons.forEach(btn => { btn.classList.toggle('active', btn.dataset.tab === tabId); }); tabPanes.forEach(pane => { pane.style.display = pane.id === tabId ? 'block' : 'none'; }); updateNavButtons(); } function updateNavButtons() { const currentIndex = tabs.indexOf(currentTab); prevTabBtn.disabled = currentIndex === 0; nextTabBtn.disabled = currentIndex === tabs.length - 1; } // --- LOGIC & EVENT HANDLERS --- bookingForm.addEventListener('submit', (e) => { e.preventDefault(); const newReservation = { id: Date.now(), roomId: parseInt(bookingRoomSelect.value), title: meetingTitleInput.value, date: bookingDateInput.value, startTime: startTimeInput.value, endTime: endTimeInput.value, }; // Validation if (newReservation.startTime >= newReservation.endTime) { showModal('Invalid Time', 'End time must be after start time.'); return; } // Conflict Check const hasConflict = reservations.some(r => r.roomId === newReservation.roomId && r.date === newReservation.date && ( (newReservation.startTime >= r.startTime && newReservation.startTime < r.endTime) || (newReservation.endTime > r.startTime && newReservation.endTime <= r.endTime) || (newReservation.startTime <= r.startTime && newReservation.endTime >= r.endTime) ) ); if (hasConflict) { showModal('Booking Conflict', 'This room is already booked for the selected time slot.'); } else { reservations.push(newReservation); showModal('Success!', 'Your meeting room has been successfully booked.'); bookingForm.reset(); const today = new Date().toISOString().split('T')[0]; bookingDateInput.value = today; updateAll(); setActiveTab('dashboard'); // Navigate to dashboard after booking } }); roomForm.addEventListener('submit', (e) => { e.preventDefault(); const id = parseInt(editRoomIdInput.value); const roomData = { name: roomNameInput.value, capacity: parseInt(roomCapacityInput.value), amenities: roomAmenitiesInput.value.split(',').map(a => a.trim()).filter(Boolean) }; if (id) { // Update const index = rooms.findIndex(r => r.id === id); if (index !== -1) { rooms[index] = { ...rooms[index], ...roomData }; } } else { // Add roomData.id = rooms.length > 0 ? Math.max(...rooms.map(r => r.id)) + 1 : 1; rooms.push(roomData); } resetRoomForm(); updateAll(); }); function resetRoomForm() { roomForm.reset(); editRoomIdInput.value = ''; roomFormTitle.textContent = 'Add New Room'; roomSubmitBtn.textContent = 'Add Room'; roomCancelEditBtn.classList.add('hidden'); } downloadPdfBtn.addEventListener('click', () => { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const selectedDate = scheduleDatePicker.value; const formattedDate = new Date(selectedDate + 'T00:00:00').toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); doc.setFontSize(18); doc.text('Meeting Room Schedule', 14, 22); doc.setFontSize(11); doc.setTextColor(100); doc.text(`Date: ${formattedDate}`, 14, 30); const dailyReservations = reservations.filter(r => r.date === selectedDate); if (dailyReservations.length === 0) { doc.text('No meetings scheduled for this day.', 14, 40); } else { const head = [['Time', 'Room', 'Meeting Title']]; const body = dailyReservations .sort((a,b) => a.startTime.localeCompare(b.startTime)) .map(r => { const room = rooms.find(rm => rm.id === r.roomId); return [`${r.startTime} - ${r.endTime}`, room ? room.name : 'Unknown Room', r.title]; }); doc.autoTable({ head: head, body: body, startY: 40, theme: 'striped', headStyles: { fillColor: [59, 130, 246] }, // blue-500 }); } doc.save(`schedule_${selectedDate}.pdf`); }); // --- MODAL --- function showModal(title, message) { modalTitle.textContent = title; modalMessage.textContent = message; modal.classList.add('visible'); } modalCloseBtn.addEventListener('click', () => modal.classList.remove('visible')); modal.addEventListener('click', (e) => { if (e.target === modal) { modal.classList.remove('visible'); } }); // --- GLOBAL API for inline event handlers --- window.app = { editRoom: (id) => { const room = rooms.find(r => r.id === id); if (room) { editRoomIdInput.value = room.id; roomNameInput.value = room.name; roomCapacityInput.value = room.capacity; roomAmenitiesInput.value = room.amenities.join(', '); roomFormTitle.textContent = 'Edit Room'; roomSubmitBtn.textContent = 'Update Room'; roomCancelEditBtn.classList.remove('hidden'); roomNameInput.focus(); } }, deleteRoom: (id) => { const hasFutureReservations = reservations.some(r => r.roomId === id && new Date(r.date) >= new Date(new Date().toISOString().split('T')[0])); if (hasFutureReservations) { showModal('Action Denied', 'Cannot delete room with active or future reservations.'); return; } rooms = rooms.filter(r => r.id !== id); updateAll(); } }; // --- ATTACH EVENT LISTENERS --- tabButtons.forEach(button => button.addEventListener('click', () => setActiveTab(button.dataset.tab))); prevTabBtn.addEventListener('click', () => navigateTabs(-1)); nextTabBtn.addEventListener('click', () => navigateTabs(1)); scheduleDatePicker.addEventListener('change', renderSchedule); roomCancelEditBtn.addEventListener('click', resetRoomForm); function navigateTabs(direction) { const currentIndex = tabs.indexOf(currentTab); const newIndex = currentIndex + direction; if (newIndex >= 0 && newIndex < tabs.length) { setActiveTab(tabs[newIndex]); } } // --- START THE APP --- initialize(); });
Scroll to Top