Foraging Seasonal Availability Calendar Creator
Seasonal Availability
| Item | Spring | Summer | Fall | Winter |
|---|
Edit Foragable Items
Add New Item
Current Item List
No items in list.
'; return; } foragables.forEach((item, index) => { const itemEl = document.createElement("div"); itemEl.className = "fsc-config-item"; itemEl.innerHTML = `
${item.name}
${ item.seasons.length > 0 ? item.seasons.join(", ") : "No seasons" }
`;
configList.appendChild(itemEl);
});
}
/**
* Handles adding a new item from the config form.
*/
function handleAddItem() {
if (
!itemNameInput ||
!checkSpring ||
!checkSummer ||
!checkFall ||
!checkWinter
)
return;
const name = itemNameInput.value.trim();
if (!name) {
// Simple non-blocking feedback
itemNameInput.style.borderColor = "red";
return;
}
itemNameInput.style.borderColor = "#ced4da"; // Reset border
const seasons = [];
if (checkSpring.checked) seasons.push("Spring");
if (checkSummer.checked) seasons.push("Summer");
if (checkFall.checked) seasons.push("Fall");
if (checkWinter.checked) seasons.push("Winter");
foragables.push({ name, seasons });
// Update both UI sections
populateCalendarTable();
populateConfigList();
// Clear form
itemNameInput.value = "";
checkSpring.checked = false;
checkSummer.checked = false;
checkFall.checked = false;
checkWinter.checked = false;
}
/**
* Handles clicks in the config list (for removing items).
*/
function handleConfigListClick(e) {
if (e.target.classList.contains("fsc-remove-btn")) {
const index = parseInt(e.target.dataset.index, 10);
foragables.splice(index, 1);
// Update both UI sections
populateCalendarTable();
populateConfigList();
}
}
/**
* Resets the data to the default list.
*/
function resetData() {
if (confirm("Are you sure you want to reset to the default list?")) {
foragables = JSON.parse(JSON.stringify(defaultData));
populateCalendarTable();
populateConfigList();
}
}
/**
* Handles downloading the report as a PDF.
*/
function downloadPDF() {
if (!reportContent || !window.html2canvas || !window.jspdf) {
console.error("PDF generation libraries or report element not found!");
return;
}
// Clone the node
const contentToPrint = reportContent.cloneNode(true);
contentToPrint.classList.add("fsc-pdf-export");
contentToPrint.style.position = "absolute";
contentToPrint.style.left = "-9999px";
contentToPrint.style.top = "0";
// Set a defined width for consistent rendering
contentToPrint.style.width = "800px";
document.body.appendChild(contentToPrint);
html2canvas(contentToPrint, {
scale: 2, // Improve resolution
useCORS: true,
}).then((canvas) => {
const imgData = canvas.toDataURL("image/png");
const { jsPDF } = window.jspdf;
// Create a standard A4 size PDF
const pdf = new jsPDF({
orientation: "p",
unit: "pt",
format: "a4",
});
// Get PDF page dimensions
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
// Get canvas dimensions
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
// Calculate the new height based on the aspect ratio to fit the width
const margin = 40; // 40pt margin
const usableWidth = pdfWidth - margin * 2;
let imgHeight = (usableWidth / canvasWidth) * canvasHeight;
let imgWidth = usableWidth;
// Check if the calculated height is too large for one page
if (imgHeight > pdfHeight - margin * 2) {
imgHeight = pdfHeight - margin * 2;
imgWidth = (imgHeight / canvasHeight) * canvasWidth;
}
// Calculate centering
const xPos = (pdfWidth - imgWidth) / 2;
const yPos = margin;
// Add the image to the PDF, scaled to fit
pdf.addImage(imgData, "PNG", xPos, yPos, imgWidth, imgHeight);
pdf.save("foraging-seasonal-calendar.pdf");
// Clean up
document.body.removeChild(contentToPrint);
});
}
// --- INITIALIZE TOOL ---
init();
});
${ item.seasons.length > 0 ? item.seasons.join(", ") : "No seasons" }
