Online Secure Employee Travel Itinerary & Booking Manager

Secure Employee Travel Itinerary & Booking Manager

Secure Employee Travel Itinerary & Booking Manager

Upcoming Trips

${m.title}

Location: ${m.location}

Starts: ${formatDate(m.startTime)}

Ends: ${formatDate(m.endTime)}

Notes: ${m.notes}

`).join('')}
` : ''}
`; // This is the full view with buttons itineraryDetailView.innerHTML = ` ${printableContent}
`; itineraryListView.classList.add('hidden'); itineraryDetailView.classList.remove('hidden'); // Add event listeners to newly created buttons document.getElementById('back-to-list-btn').addEventListener('click', () => { itineraryDetailView.classList.add('hidden'); itineraryListView.classList.remove('hidden'); }); document.querySelector('.edit-itinerary-btn').addEventListener('click', (e) => populateFormForEdit(e.target.dataset.id)); document.querySelector('.delete-itinerary-btn').addEventListener('click', (e) => deleteItinerary(e.target.dataset.id)); document.getElementById('download-pdf-btn').addEventListener('click', () => downloadPDF(itinerary)); } function deleteItinerary(itineraryId) { // Using a simple confirmation as a placeholder for a custom modal if (confirm('Are you sure you want to delete this itinerary? This action cannot be undone.')) { state.itineraries = state.itineraries.filter(i => i.id !== itineraryId); renderDashboard(); itineraryDetailView.classList.add('hidden'); itineraryListView.classList.remove('hidden'); } } // --- PDF DOWNLOAD LOGIC --- // function downloadPDF(itinerary) { const { jsPDF } = window.jspdf; const pdfContent = document.getElementById('pdf-content'); if (!pdfContent) return; // Use html2canvas to render the div to a canvas html2canvas(pdfContent, { scale: 2 }).then(canvas => { const imgData = canvas.toDataURL('image/png'); // Calculate dimensions for the PDF const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; let imgWidth = pdfWidth - 20; // with margin let imgHeight = imgWidth / ratio; let heightLeft = imgHeight; let position = 10; // top margin pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= pdfHeight; while (heightLeft >= 0) { position = heightLeft - imgHeight + 10; // top margin for new page pdf.addPage(); pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= pdfHeight; } // Generate a filename const fileName = `Itinerary-${itinerary.employeeName.replace(' ', '_')}-${itinerary.tripName.replace(' ', '_')}.pdf`; pdf.save(fileName); }); } // --- CONFIGURATION LOGIC --- // function renderConfigLists() { // Render Employees employeeList.innerHTML = state.config.employees.map(emp => `
  • ${emp.name} - ${emp.title}
  • `).join(''); // Render Airlines airlineList.innerHTML = state.config.airlines.map(airline => `
  • ${airline}
  • `).join(''); // Render Hotels hotelList.innerHTML = state.config.hotels.map(hotel => `
  • ${hotel}
  • `).join(''); // Render Car Rentals carRentalList.innerHTML = state.config.carRentals.map(car => `
  • ${car}
  • `).join(''); // Update dropdowns employeeNameSelect.innerHTML = state.config.employees.map(emp => ``).join(''); } function updateConfigFromDOM() { state.config.employees = Array.from(employeeList.children).map(li => ({ id: li.dataset.id, name: li.querySelector('span').childNodes[0].textContent.trim(), title: li.querySelector('em').textContent.substring(2) })); state.config.airlines = Array.from(airlineList.children).map(li => li.querySelector('span').textContent); state.config.hotels = Array.from(hotelList.children).map(li => li.querySelector('span').textContent); state.config.carRentals = Array.from(carRentalList.children).map(li => li.querySelector('span').textContent); renderConfigLists(); // Re-render to update dropdowns } // Event listeners for config buttons addEmployeeBtn.addEventListener('click', () => { const name = newEmployeeNameInput.value.trim(); const title = newEmployeeTitleInput.value.trim(); if (name && title) { state.config.employees.push({ id: generateId(), name, title }); newEmployeeNameInput.value = ''; newEmployeeTitleInput.value = ''; renderConfigLists(); } }); addAirlineBtn.addEventListener('click', () => { const name = newAirlineNameInput.value.trim(); if (name && !state.config.airlines.includes(name)) { state.config.airlines.push(name); newAirlineNameInput.value = ''; renderConfigLists(); } }); addHotelBtn.addEventListener('click', () => { const name = newHotelNameInput.value.trim(); if (name && !state.config.hotels.includes(name)) { state.config.hotels.push(name); newHotelNameInput.value = ''; renderConfigLists(); } }); addCarRentalBtn.addEventListener('click', () => { const name = newCarRentalNameInput.value.trim(); if (name && !state.config.carRentals.includes(name)) { state.config.carRentals.push(name); newCarRentalNameInput.value = ''; renderConfigLists(); } }); // Use MutationObserver to automatically update state when items are removed via inline onclick const observer = new MutationObserver(updateConfigFromDOM); observer.observe(employeeList, { childList: true }); observer.observe(airlineList, { childList: true }); observer.observe(hotelList, { childList: true }); observer.observe(carRentalList, { childList: true }); // --- INITIALIZATION --- // function initializeApp() { // Null checks for critical elements if (!tabButtons.dashboard || !tabPanels.dashboard || !itineraryForm) { console.error("Critical UI elements are missing. Tool cannot initialize."); return; } addFlightBtn.addEventListener('click', () => addFlightSegment()); addAccommodationBtn.addEventListener('click', () => addAccommodationSegment()); addTransportBtn.addEventListener('click', () => addTransportSegment()); addMeetingBtn.addEventListener('click', () => addMeetingSegment()); clearFormBtn.addEventListener('click', clearForm); renderConfigLists(); renderDashboard(); showTab('dashboard'); // Start on the dashboard clearForm(); // Set up the form with one empty flight segment } initializeApp(); });
    Scroll to Top