${event.source.charAt(0).toUpperCase() + event.source.slice(1)}
`;
calendarView.appendChild(eventCard);
});
}
function switchTab(tabName) {
state.currentTab = tabName;
tabPanes.forEach(pane => pane.classList.add('hidden'));
document.getElementById(tabName).classList.remove('hidden');
tabBtns.forEach(btn => {
if (btn.dataset.tab === tabName) {
btn.classList.add('tab-active');
btn.classList.remove('tab-inactive');
} else {
btn.classList.add('tab-inactive');
btn.classList.remove('tab-active');
}
});
updateNavButtons();
if (tabName === 'calendar') {
renderSyncedCalendar();
}
}
function updateNavButtons() {
const tabs = ['accounts', 'rules', 'calendar'];
const currentIndex = tabs.indexOf(state.currentTab);
prevTabBtn.disabled = currentIndex === 0;
nextTabBtn.disabled = currentIndex === tabs.length - 1;
}
function navigateTabs(direction) {
const tabs = ['accounts', 'rules', 'calendar'];
const currentIndex = tabs.indexOf(state.currentTab);
const newIndex = currentIndex + direction;
if (newIndex >= 0 && newIndex < tabs.length) {
switchTab(tabs[newIndex]);
}
}
// SECTION: UTILITY FUNCTIONS
// ==========================
function formatTime(date) {
return date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true });
}
// SECTION: PDF GENERATION
// =======================
function generatePDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
const events = getSyncedEvents();
doc.setFont('helvetica', 'bold');
doc.setFontSize(22);
doc.setTextColor('#1f2937');
doc.text('Synced Calendar Schedule', doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' });
const reportDate = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
doc.setFont('helvetica', 'normal');
doc.setFontSize(11);
doc.setTextColor('#6b7280');
doc.text(`Generated on: ${reportDate}`, doc.internal.pageSize.getWidth() / 2, 28, { align: 'center' });
const tableColumn = ["Date", "Time", "Event Title", "Source"];
const tableRows = [];
events.forEach(event => {
const eventData = [
event.start.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),
`${formatTime(event.start)} - ${formatTime(event.end)}`,
event.title,
event.source.charAt(0).toUpperCase() + event.source.slice(1)
];
tableRows.push(eventData);
});
doc.autoTable({
head: [tableColumn],
body: tableRows,
startY: 40,
theme: 'grid',
headStyles: { fillColor: [243, 244, 246], textColor: [31, 41, 55] }
});
doc.save(`Synced_Schedule_${new Date().toISOString().split('T')[0]}.pdf`);
}
// SECTION: EVENT LISTENERS
// ========================
function setupEventListeners() {
tabBtns.forEach(btn => btn.addEventListener('click', () => switchTab(btn.dataset.tab)));
prevTabBtn.addEventListener('click', () => navigateTabs(-1));
nextTabBtn.addEventListener('click', () => navigateTabs(1));
syncDirectionSelect.addEventListener('change', updateSyncRules);
privacyRadios.forEach(radio => radio.addEventListener('change', updateSyncRules));
downloadPdfBtn.addEventListener('click', generatePDF);
setupDynamicEventListeners();
}
function setupDynamicEventListeners() {
// For dynamically added/removed connect/disconnect buttons
document.querySelectorAll('.connect-btn').forEach(btn => {
btn.addEventListener('click', (e) => connectAccount(e.target.dataset.account));
});
document.querySelectorAll('.disconnect-btn').forEach(btn => {
btn.addEventListener('click', (e) => disconnectAccount(e.target.dataset.account));
});
}
// Initial application start
renderAccountStatus();
setupEventListeners();
});
