Template Library
Select a project template to view its details.
Manage Templates
Add, edit, or remove project templates from the library.
${this.selectedTemplate.description}
${phasesHtml}
${checklistHtml}
`; },
openEditModal(index = -1) {
const form = document.getElementById('p-tmpl-modal-form'); form.reset();
document.getElementById('p-tmpl-edit-index').value = index;
const template = (index > -1) ? this.templates[index] : { name: '', description: '', duration: '', phases: [], deliverables: [] };
document.getElementById('p-tmpl-modal-title').textContent = (index > -1) ? 'Edit Template' : 'Add New Template';
document.getElementById('p-tmpl-modal-name').value = template.name;
document.getElementById('p-tmpl-modal-desc').value = template.description;
document.getElementById('p-tmpl-modal-duration').value = template.duration;
const phasesContainer = document.getElementById('p-tmpl-modal-phases'); phasesContainer.innerHTML = '
Phases & Tasks
'; template.phases.forEach(p => this.addPhaseToModal(p));
const deliverablesContainer = document.getElementById('p-tmpl-modal-deliverables'); deliverablesContainer.innerHTML = '
Key Deliverables
'; template.deliverables.forEach(d => this.addDeliverableToModal(d));
document.getElementById('p-tmpl-edit-modal').style.display = 'block';
},
closeEditModal() { document.getElementById('p-tmpl-edit-modal').style.display = 'none'; },
addPhaseToModal(phase = {name: '', tasks: []}) { const container = document.getElementById('p-tmpl-modal-phases'); const phaseGroup = document.createElement('div'); phaseGroup.className = 'p-tmpl-phase-group'; phaseGroup.innerHTML = `
`; const taskContainer = phaseGroup.querySelector('.p-tmpl-task-container'); phase.tasks.forEach(t => this.addTaskToModal(taskContainer, t)); container.appendChild(phaseGroup); },
addTaskToModal(container, task = '') { container.innerHTML += `
`; },
addDeliverableToModal(deliverable = '') { document.getElementById('p-tmpl-modal-deliverables').innerHTML += `
`; },
saveTemplateFromModal() {
const index = document.getElementById('p-tmpl-edit-index').value;
const newTemplate = { name: document.getElementById('p-tmpl-modal-name').value, description: document.getElementById('p-tmpl-modal-desc').value, duration: document.getElementById('p-tmpl-modal-duration').value, phases: [], deliverables: [] };
document.querySelectorAll('.p-tmpl-phase-group').forEach(pg => { const phase = { name: pg.querySelector('.p-tmpl-phase-name').value, tasks: [] }; pg.querySelectorAll('.p-tmpl-task-name').forEach(t => phase.tasks.push(t.value)); newTemplate.phases.push(phase); });
document.querySelectorAll('.p-tmpl-deliverable-name').forEach(d => newTemplate.deliverables.push(d.value));
if (index > -1) { this.templates[index] = newTemplate; } else { this.templates.push(newTemplate); }
this.updateDashboard(); this.closeEditModal();
},
openTab(tabName) { this.currentTab = tabName; const detailTabBtn = document.querySelector('.p-tmpl-tab-button[data-tab="Details"]'); if(this.selectedTemplate){ detailTabBtn.classList.remove('p-tmpl-disabled'); } else { detailTabBtn.classList.add('p-tmpl-disabled'); if (tabName === 'Details') tabName = 'Dashboard'; } document.querySelectorAll('.p-tmpl-tab-content').forEach(c => c.classList.remove('active')); document.querySelectorAll('.p-tmpl-tab-button').forEach(b => b.classList.remove('active')); document.getElementById(`p-tmpl-${tabName}`).classList.add('active'); document.querySelector(`.p-tmpl-tab-button[data-tab='${tabName}']`).classList.add('active'); this.updateNavButtons(); },
navigateTabs(direction) { const tabs = ['Dashboard', 'Details', 'Config'].filter(t => t !== 'Details' || this.selectedTemplate); const nextIndex = tabs.indexOf(this.currentTab) + direction; if (nextIndex >= 0 && nextIndex < tabs.length) this.openTab(tabs[nextIndex]); },
updateNavButtons() { const tabs = ['Dashboard', 'Details', 'Config'].filter(t => t !== 'Details' || this.selectedTemplate); const currentIndex = tabs.indexOf(this.currentTab); document.getElementById('p-tmpl-prevBtn').style.visibility = (currentIndex > 0) ? 'visible' : 'hidden'; document.getElementById('p-tmpl-nextBtn').style.visibility = (currentIndex < tabs.length - 1) ? 'visible' : 'hidden'; },
generatePDF() { if (!this.selectedTemplate) { alert("Please select a template first."); return; } const element = document.getElementById('p-tmpl-detail-content-for-pdf'); html2pdf().from(element).set({ margin: 0.75, filename: `${this.selectedTemplate.name.replace(/\s+/g, '_')}_Template.pdf`, image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true }, jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' } }).save(); }
};
pTmplApp.init();
});