Professional Learning Community (PLC) Meeting Protocol

PLC Meeting Protocol

Meeting Details (Editable)

Meeting Details

Core PLC Questions Focus

Agenda Items

Current Agenda

No agenda items added yet.

No agenda items added yet.

"; return; } agendaItems.forEach(item => { const itemEl = document.createElement("div"); itemEl.className = "plc-agenda-item"; itemEl.dataset.id = item.id; itemEl.innerHTML = ` ${escapeHTML(item.text)} `; configAgendaList.appendChild(itemEl); }); } /** * Handles clicks in the config agenda list (for remove) */ function handleConfigListClick(e) { if (e.target.dataset.action === "remove") { const itemEl = e.target.closest(".plc-agenda-item"); if (itemEl) { agendaItems = agendaItems.filter(item => item.id !== itemEl.dataset.id); updateConfigAgendaDisplay(); // Update this list } } } /** * Populates the dashboard from the config data and agenda items */ function handleGenerateDashboard() { // Transfer basic info dashGroup.value = configGroup.value; dashDate.value = configDate.value; dashFacilitator.value = configFacilitator.value; dashTimekeeper.value = configTimekeeper.value; dashNotetaker.value = configNotetaker.value; // Transfer core questions dashQ1.value = configQ1.value; dashQ2.value = configQ2.value; dashQ3.value = configQ3.value; dashQ4.value = configQ4.value; // Populate dashboard agenda dashAgendaList.innerHTML = ""; // Clear if (agendaItems.length === 0) { const li = document.createElement('li'); li.textContent = 'No agenda items specified.'; dashAgendaList.appendChild(li); } else { agendaItems.forEach(item => { const li = document.createElement('li'); li.className = 'plc-dash-agenda-item'; li.dataset.id = item.id; li.innerHTML = ` `; dashAgendaList.appendChild(li); }); } // Clear action items/decisions dashActions.value = ""; dashDecisions.value = ""; showTab("plc-tab-dashboard"); } /** * Handles removing an item directly from the dashboard agenda */ function handleDashboardAgendaClick(e) { if (e.target.dataset.action === "remove") { const itemEl = e.target.closest(".plc-dash-agenda-item"); if (itemEl) { // Find and remove from master list agendaItems = agendaItems.filter(item => item.id !== itemEl.dataset.id); // Remove from dashboard view itemEl.remove(); // Update config list display updateConfigAgendaDisplay(); // Add message if list becomes empty if (agendaItems.length === 0) { const li = document.createElement('li'); li.textContent = 'No agenda items specified.'; dashAgendaList.appendChild(li); } } } } /** * Updates the master `agendaItems` array when dashboard agenda text changes */ function handleDashboardAgendaInput(e) { const itemEl = e.target.closest(".plc-dash-agenda-item"); if (!itemEl || !e.target.classList.contains('plc-dash-agenda-text')) return; const itemId = itemEl.dataset.id; const item = agendaItems.find(i => i.id === itemId); if (item) { item.text = e.target.value; // Also update the config list display in the background updateConfigAgendaDisplay(); } } /** * Generates a PDF report from the dashboard data */ function downloadPDF() { if (typeof window.jspdf === 'undefined') { alert("Error: PDF library (jsPDF) could not be loaded. Please try again."); return; } // Get potentially edited values from dashboard const group = dashGroup.value || "[Group Name]"; const date = dashDate.value || "[Date]"; const facilitator = dashFacilitator.value || "[Facilitator]"; const timekeeper = dashTimekeeper.value || "[Timekeeper]"; const notetaker = dashNotetaker.value || "[Note Taker]"; const q1 = dashQ1.value || "[Response]"; const q2 = dashQ2.value || "[Response]"; const q3 = dashQ3.value || "[Response]"; const q4 = dashQ4.value || "[Response]"; const actions = dashActions.value || "None recorded."; const decisions = dashDecisions.value || "None recorded."; // Get agenda items from dashboard const agenda = []; const dashAgendaItems = dashAgendaList.querySelectorAll('.plc-dash-agenda-item'); dashAgendaItems.forEach(li => { const input = li.querySelector('.plc-dash-agenda-text'); if (input) agenda.push(input.value); }); const { jsPDF } = window.jspdf; const doc = new jsPDF("p", "pt", "a4"); const margin = 40; let yPos = margin; const lineHeight = 16; const usableWidth = doc.internal.pageSize.getWidth() - margin * 2; // Function to add a section with title and text function addSection(title, text, isBold = false, fontSize = 11) { const titleHeight = 20; const textLines = doc.splitTextToSize(text, usableWidth); const textHeight = textLines.length * lineHeight * (fontSize / 11); // Adjust height for font size if (yPos + titleHeight + textHeight > doc.internal.pageSize.getHeight() - margin) { doc.addPage(); yPos = margin; } doc.setFontSize(14); doc.setFont(undefined, 'bold'); doc.text(title, margin, yPos); yPos += lineHeight * 1.5; doc.setFontSize(fontSize); doc.setFont(undefined, isBold ? 'bold' : 'normal'); doc.text(textLines, margin, yPos); yPos += textHeight + lineHeight * 1.5; // Add space after section } // Function to add list items function addList(title, items) { const titleHeight = 20; let listHeight = 0; items.forEach(item => { listHeight += doc.splitTextToSize(`- ${item}`, usableWidth - 15).length * lineHeight; // Indent slightly }); if (yPos + titleHeight + listHeight > doc.internal.pageSize.getHeight() - margin) { doc.addPage(); yPos = margin; } doc.setFontSize(14); doc.setFont(undefined, 'bold'); doc.text(title, margin, yPos); yPos += lineHeight * 1.5; doc.setFontSize(11); doc.setFont(undefined, 'normal'); items.forEach(item => { const itemLines = doc.splitTextToSize(`- ${item}`, usableWidth - 15); doc.text(itemLines, margin + 15, yPos); yPos += itemLines.length * lineHeight; }); yPos += lineHeight * 0.5; // Space after list } // Add Title doc.setFontSize(18); doc.setFont(undefined, 'bold'); doc.text("PLC Meeting Protocol", doc.internal.pageSize.getWidth() / 2, yPos, { align: 'center' }); yPos += lineHeight * 2; // Add Meeting Details doc.setFontSize(11); doc.setFont(undefined, 'normal'); doc.text(`Group: ${group}`, margin, yPos); doc.text(`Date: ${date}`, margin + 250, yPos); yPos += lineHeight * 1.5; doc.text(`Facilitator: ${facilitator}`, margin, yPos); doc.text(`Timekeeper: ${timekeeper}`, margin + 250, yPos); yPos += lineHeight; doc.text(`Note Taker: ${notetaker}`, margin, yPos); yPos += lineHeight * 2.5; // Add Core Questions addSection("Core Question 1: What do we want students to learn?", q1); addSection("Core Question 2: How will we know if they have learned it?", q2); addSection("Core Question 3: What will we do if they haven't learned it?", q3); addSection("Core Question 4: What will we do if they have learned it?", q4); // Add Agenda addList("Agenda", agenda.length > 0 ? agenda : ["No items specified."]); // Add Actions & Decisions addSection("Action Items / Next Steps", actions); addSection("Decisions Made", decisions); doc.save(`${group.replace(/ /g,"_")}_PLC_Protocol_${date}.pdf`); } /** * Helper to escape HTML */ function escapeHTML(str) { if (!str) return ""; return str .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // --- 4. INITIALIZATION & EVENT LISTENERS --- // Tab Listeners tabButtons.forEach((btn) => { btn.addEventListener("click", () => showTab(btn.dataset.target)); }); navButtons.forEach((btn) => { btn.addEventListener("click", () => showTab(btn.dataset.target)); }); // Config Tab Listeners if (addAgendaForm) { addAgendaForm.addEventListener("submit", handleAddAgenda); } if (configAgendaList) { configAgendaList.addEventListener("click", handleConfigListClick); } if (generateBtn) { generateBtn.addEventListener("click", handleGenerateDashboard); } // Dashboard Tab Listeners if (pdfBtn) { pdfBtn.addEventListener("click", downloadPDF); } if (dashAgendaList) { dashAgendaList.addEventListener("click", handleDashboardAgendaClick); dashAgendaList.addEventListener("input", handleDashboardAgendaInput); } // Set default date configDate.valueAsDate = new Date(); // Initial State updateConfigAgendaDisplay(); // Show empty message initially showTab("plc-tab-dashboard"); // Start on dashboard });
Scroll to Top