Cross-Department Coordination Hub

Cross-Department Coordination Hub

Active Projects Dashboard

${u.user}:

${u.text}

`).join(''); card.innerHTML = `

${project.title}

${project.status}

Contact: ${project.contact}

${project.involvedDepts.map(d => `${d}`).join('')}

${project.description}

Updates

${updatesHtml}
`; projectDashboard.appendChild(card); }); }; /** * Populates all forms and configuration inputs. */ const populateForms = () => { // Add Project Form const deptsCheckboxDiv = document.getElementById('departmentsCheckbox'); deptsCheckboxDiv.innerHTML = departments.map(d => ` `).join(''); const contactSelect = document.getElementById('keyContact'); contactSelect.innerHTML = teamMembers.map(m => ``).join(''); const statusSelect = document.getElementById('projectStatus'); statusSelect.innerHTML = statuses.map(s => ``).join(''); // Configuration Tab const deptsConfigDiv = document.getElementById('departmentsConfig'); deptsConfigDiv.innerHTML = departments.map((d, i) => `
`).join(''); const membersConfigDiv = document.getElementById('teamMembersConfig'); membersConfigDiv.innerHTML = teamMembers.map((m, i) => `
`).join(''); }; /** * Handles new project form submission. */ const handleProjectSubmit = (e) => { e.preventDefault(); const involvedDepts = Array.from(document.querySelectorAll('#departmentsCheckbox input:checked')).map(cb => cb.value); if (involvedDepts.length === 0) { alert('Please select at least one department.'); return; } const newProject = { id: nextProjectId++, title: document.getElementById('projectTitle').value, involvedDepts: involvedDepts, contact: document.getElementById('keyContact').value, status: document.getElementById('projectStatus').value, description: document.getElementById('projectDescription').value, updates: [] }; projects.push(newProject); projectForm.reset(); updateAll(); changeTab(0); }; /** * Generates and downloads a professional PDF report of all projects. */ const downloadPDF = () => { const { jsPDF } = window.jspdf; const doc = new jsPDF(); doc.setFontSize(22); doc.text('Cross-Department Project Report', 14, 20); doc.setFontSize(10); doc.setTextColor(150); doc.text(`Report generated on: ${new Date().toLocaleDateString()}`, 14, 26); let yPos = 40; projects.forEach(project => { if (yPos > 250) { doc.addPage(); yPos = 20; } doc.setFontSize(16); doc.setFont('helvetica', 'bold'); doc.setTextColor(0); doc.text(project.title, 14, yPos); yPos += 8; doc.setFontSize(11); doc.setFont('helvetica', 'normal'); doc.text(`Status: ${project.status} | Contact: ${project.contact}`, 14, yPos); yPos += 6; doc.text(`Departments: ${project.involvedDepts.join(', ')}`, 14, yPos); yPos += 10; if (project.updates.length > 0) { const latestUpdate = project.updates[project.updates.length - 1]; doc.setFont('helvetica', 'italic'); doc.setTextColor(100); const splitText = doc.splitTextToSize(`Latest Update from ${latestUpdate.user}: ${latestUpdate.text}`, 180); doc.text(splitText, 16, yPos); yPos += (splitText.length * 5) + 4; } else { doc.setFont('helvetica', 'italic'); doc.setTextColor(100); doc.text('No updates posted yet.', 16, yPos); yPos += 10; } yPos += 8; // Extra space }); doc.save('coordination-hub-report.pdf'); }; /** * Updates all dynamic parts of the tool. */ const updateAll = () => { renderDashboard(); populateForms(); updateNavButtons(); }; // --- Event Listeners --- prevBtn.addEventListener('click', () => changeTab(currentTab - 1)); nextBtn.addEventListener('click', () => changeTab(currentTab + 1)); projectForm.addEventListener('submit', handleProjectSubmit); pdfDownloadBtn.addEventListener('click', downloadPDF); addDepartmentBtn.addEventListener('click', () => { departments.push('New Department'); populateForms(); }); addTeamMemberBtn.addEventListener('click', () => { teamMembers.push('New Member (Dept)'); populateForms(); }); saveConfigBtn.addEventListener('click', () => { departments = Array.from(document.querySelectorAll('#departmentsConfig input')).map(i => i.value).filter(Boolean); teamMembers = Array.from(document.querySelectorAll('#teamMembersConfig input')).map(i => i.value).filter(Boolean); updateAll(); alert('Configuration Saved!'); }); // Event delegation for dynamic elements tabContent.addEventListener('click', e => { if (e.target.classList.contains('remove-btn')) { const type = e.target.dataset.type; const index = parseInt(e.target.dataset.index); if (type === 'department') departments.splice(index, 1); if (type === 'member') teamMembers.splice(index, 1); populateForms(); } if (e.target.classList.contains('add-update-btn')) { const card = e.target.closest('.project-card'); const projectId = parseInt(card.dataset.projectId); const project = projects.find(p => p.id === projectId); const textarea = card.querySelector('.update-input'); const updateText = textarea.value.trim(); if (project && updateText) { // In a real app, user would be identified. Here we use the key contact. project.updates.push({ user: project.contact, text: updateText }); textarea.value = ''; renderDashboard(); } } }); // Initial setup updateAll(); });
Scroll to Top