Project: ${data.project} | Log Date: ${new Date().toLocaleDateString()}
`;
// 2. Assessment
html += `
Target Species & Habitat Assessment
Habitat Type: ${data.habitat}
Current Status: ${data.status}
Target Species: ${data.species}
`;
// 3. Goals
html += `
Goals & Expected Outcomes
${data.goals}
`;
// 4. Action Plan Table (Using dynamic table for structure)
if (actions.length > 0) {
html += `
Action Plan & Monitoring Schedule
`;
let tableHtml = `
| Action / Intervention |
Success Metric (KPI) |
Timeline |
`;
actions.forEach(item => {
tableHtml += `
| ${item.desc} |
${item.metric} |
${item.timeline} |
`;
});
tableHtml += `
`;
html += tableHtml;
}
// 5. Signature Block Placeholder
html += `
Plan Approved By: ___________________________________
Date Approved: ___________________
`;
container.innerHTML = html;
}
function whrpgSwitchTab(tabId) {
document.querySelectorAll('.whrpg-tab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('.whrpg-content').forEach(c => c.classList.remove('active'));
const idx = tabId === 'builder' ? 0 : 1;
document.querySelectorAll('.whrpg-tab-btn')[idx].classList.add('active');
document.getElementById('whrpg-' + tabId).classList.add('active');
if (tabId === 'preview') {
whrpgRenderPlan();
}
}
function whrpgLoadExample() {
if(!confirm("Overwrite current inputs with example Riparian Zone Restoration data?")) return;
document.getElementById('inp-project').value = "Willow Creek Riparian Zone Buffer";
document.getElementById('inp-species').value = "Willow, Cottonwood, River Otter";
document.getElementById('inp-habitat').value = "Riparian";
document.getElementById('inp-status').value = "Degraded";
document.getElementById('inp-goals').value = "Reduce annual soil loss by 50% along the creek banks. Increase vegetative species diversity by 30%. Re-establish stable bank cover within 2 years.";
// Clear and fill actions
document.getElementById('whrpg-action-rows-container').innerHTML = '';
whrpgAddActionRow("Install coconut fiber bio-logs along 400m of creek bank.", "Erosion Rate (cm/yr)", "Q1 2026");
whrpgAddActionRow("Plant 1000 riparian saplings (willow/cottonwood).", "Native Vegetative Cover (%)", "Q2 2026");
whrpgAddActionRow("Monitor invasive species (e.g., kudzu).", "Invasive Species Cover (%)", "Ongoing Quarterly");
whrpgRenderPlan();
whrpgSwitchTab('preview');
}
/* --- PDF Generation --- */
async function whrpgGeneratePDF() {
whrpgRenderPlan(); // Final render
const data = {
project: document.getElementById('inp-project').value || "Project Name",
species: document.getElementById('inp-species').value || "Target Species",
habitat: document.getElementById('inp-habitat').value,
status: document.getElementById('inp-status').value,
goals: document.getElementById('inp-goals').value || "Goals pending."
};
const actions = whrpgGetActionData();
if (actions.length === 0) {
alert("Please add actions to the plan before generating the PDF.");
return;
}
const { jsPDF } = window.jspdf;
const doc = new jsPDF('p', 'mm', 'a4');
const green = [0, 100, 0];
let y = 20;
// 1. Header
doc.setFillColor(...green);
doc.rect(0, 0, 210, 20, 'F');
doc.setTextColor(255, 255, 255);
doc.setFontSize(16);
doc.text(`Wildlife Habitat Restoration Plan`, 14, 13);
// 2. Project Context
doc.setTextColor(0, 0, 0);
doc.setFontSize(10);
doc.text(`Project: ${data.project}`, 14, y + 10);
doc.text(`Habitat Type: ${data.habitat}`, 100, y + 10);
doc.text(`Target Species: ${data.species}`, 14, y + 16);
doc.text(`Current Status: ${data.status}`, 100, y + 16);
y += 35;
// 3. Goals
doc.setFontSize(12);
doc.setFont("helvetica", "bold");
doc.setTextColor(...green);
doc.text("I. Goals & Expected Outcomes", 14, y);
y += 5;
doc.setFontSize(10);
doc.setFont("times", "normal");
doc.setTextColor(50, 50, 50);
const splitGoals = doc.splitTextToSize(data.goals, 180);
doc.text(splitGoals, 18, y);
y += (splitGoals.length * 5) + 8;
// 4. Action Plan Table
doc.setFontSize(12);
doc.setFont("helvetica", "bold");
doc.setTextColor(...green);
doc.text("II. Restoration Action Plan & Monitoring Schedule", 14, y);
y += 5;
const tableBody = actions.map((item, index) => [
index + 1,
item.desc,
item.metric,
item.timeline
]);
doc.autoTable({
startY: y,
head: [['#', 'Action / Intervention', 'Success Metric (KPI)', 'Timeline']],
body: tableBody,
theme: 'grid',
headStyles: { fillColor: green, fontSize: 10 },
styles: { fontSize: 9 },
columnStyles: {
0: { cellWidth: 10, halign: 'center', fontStyle: 'bold' },
1: { cellWidth: 70, overflow: 'linebreak' },
2: { cellWidth: 60, overflow: 'linebreak' },
3: { cellWidth: 'auto', fontStyle: 'bold' }
}
});
y = doc.lastAutoTable.finalY + 15;
// 5. Conclusion/Approval
doc.setFontSize(10);
doc.text("This plan must be reviewed annually to verify KPI adherence and site changes.", 14, y);
y += 20;
doc.text("Plan Manager Signature: ___________________________", 14, y);
doc.text("Date Reviewed: _______________", 140, y);
doc.save(`HabitatPlan_${data.project.replace(/\s/g, '_')}.pdf`);
}