`;
}).join('');
}
function updateSummary() {
summaryAndDownload.classList.remove('hidden');
let totalWorkMinutes = 0, totalBreakMinutes = 0;
generatedSchedule.forEach(item => {
const start = new Date(`1970-01-01T${item.startTime.replace(/( AM| PM)/, '')}:00`);
const end = new Date(`1970-01-01T${item.endTime.replace(/( AM| PM)/, '')}:00`);
// Handle PM times for correct date object parsing
if (item.startTime.includes('PM') && start.getHours() < 12) start.setHours(start.getHours() + 12);
if (item.endTime.includes('PM') && end.getHours() < 12) end.setHours(end.getHours() + 12);
if (item.endTime.includes('AM') && item.startTime.includes('PM')) end.setDate(end.getDate() + 1); // Handle overnight case
const duration = (end - start) / 60000;
if (item.type === 'Work') {
totalWorkMinutes += duration;
} else {
totalBreakMinutes += duration;
}
});
const ctx = document.getElementById('timeBreakdownChart').getContext('2d');
if (timeBreakdownChartInstance) timeBreakdownChartInstance.destroy();
timeBreakdownChartInstance = new Chart(ctx, {
type: 'doughnut',
data: {
labels: [`Work (${(totalWorkMinutes/60).toFixed(1)} hrs)`, `Breaks (${(totalBreakMinutes/60).toFixed(1)} hrs)`],
datasets: [{
data: [totalWorkMinutes, totalBreakMinutes],
backgroundColor: ['#6366f1', '#34d399'],
hoverOffset: 4
}]
},
options: { responsive: true, plugins: { legend: { position: 'top' } } }
});
}
// --- PDF GENERATION ---
async function generatePdf() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' });
doc.setFont("helvetica", "bold");
doc.setFontSize(22);
doc.setTextColor("#4338ca");
doc.text("Optimized Work Schedule", doc.internal.pageSize.width / 2, 60, { align: 'center' });
const totalWorkMinutes = generatedSchedule.filter(i => i.type === 'Work').reduce((acc, i) => acc + (new Date(`1970-01-01T${i.endTime}`) - new Date(`1970-01-01T${i.startTime}`))/60000, 0);
const tableData = generatedSchedule.map(item => [
`${item.startTime} - ${item.endTime}`,
item.type,
item.task
]);
doc.autoTable({
startY: 100,
head: [['Time Slot', 'Type', 'Assigned Task']],
body: tableData,
theme: 'grid',
headStyles: { fillColor: '#6366f1' },
didParseCell: function (data) {
if (data.row.section === 'body' && data.cell.raw === 'Break') {
data.cell.styles.fillColor = '#d1fae5';
data.cell.styles.textColor = '#065f46';
}
}
});
doc.save(`Optimized-Schedule_${new Date().toISOString().split('T')[0]}.pdf`);
}
// --- TAB NAVIGATION LOGIC ---
function switchTab(tabIndex) {
currentTabIndex = tabIndex;
tabsContainer.querySelectorAll('button').forEach((btn, index) => {
btn.classList.toggle('tab-active', index === tabIndex);
btn.classList.toggle('tab-inactive', index !== tabIndex);
});
tabContents.forEach((content, index) => {
content.classList.toggle('hidden', index !== tabIndex);
});
updateButtonStates();
}
function updateButtonStates() {
prevBtn.disabled = currentTabIndex === 0;
nextBtn.disabled = currentTabIndex === tabs.length - 1;
prevBtn.classList.toggle('opacity-50', prevBtn.disabled);
nextBtn.classList.toggle('opacity-50', nextBtn.disabled);
}
// --- EVENT LISTENERS ---
saveSettingsBtn.addEventListener('click', saveSettings);
generateScheduleBtn.addEventListener('click', generateSchedule);
downloadPdfBtn.addEventListener('click', generatePdf);
tabsContainer.querySelectorAll('button').forEach((btn, index) => {
btn.addEventListener('click', () => switchTab(index));
});
prevBtn.addEventListener('click', () => {
if (currentTabIndex > 0) switchTab(currentTabIndex - 1);
});
nextBtn.addEventListener('click', () => {
if (currentTabIndex < tabs.length - 1) switchTab(currentTabIndex + 1);
});
// --- RUN INITIALIZATION ---
initialize();
});