Explore these further and integrate what works best for your style.
";
} else {
blueprint += "
You're open to suggestions! Consider starting with Time Blocking (scheduling specific time for tasks) or the Pomodoro Technique (short focused work sprints) as they are widely effective.
";
}
// Section 6: Tooling Your Productivity
blueprint += "
6. Tooling Your Productivity
";
blueprint += `
Your tool preference is: ${data.toolPreference}. `;
if (data.toolPreference.includes("Digital")) blueprint += "Explore apps for task management (e.g., Todoist, Asana, Trello), calendar management, note-taking (e.g., Evernote, Notion), and focus (e.g., Freedom, Forest).";
else if (data.toolPreference.includes("Analog")) blueprint += "A good quality notebook/planner, pens, and sticky notes can be very effective. Consider bullet journaling or a structured paper planner.";
else blueprint += "Find a balance that suits you. Perhaps a digital calendar священникамиh a paper to-do list, or a project management app with a notebook for brainstorming.";
blueprint += " The key is consistency and finding tools that you genuinely enjoy using.
";
// Section 7: Managing Distractions
blueprint += "
7. Managing Distractions & Maintaining Focus
";
blueprint += `
You handle distractions by: ${data.distractionHandling}. `;
if (data.distractionHandling.includes("Minimize/defer")) blueprint += "This is a strong approach. Continue to proactively create a distraction-free environment and schedule specific times to check communications.";
else if (data.distractionHandling.includes("Address immediately")) blueprint += "While this can feel productive, it often leads to context switching which reduces overall efficiency. Try to batch communications or use the 'Two-Minute Rule' selectively.";
else if (data.distractionHandling.includes("Struggle to refocus")) blueprint += "Recognizing this is the first step. Implement strategies like the Pomodoro Technique to build focus, and make it harder for distractions to reach you during focus blocks.";
else if (data.distractionHandling.includes("Take breaks then refocus")) blueprint += "This is a good recovery strategy. Ensure your breaks are refreshing and don't lead to further distractions. A short walk or some stretching can help reset focus.";
blueprint += "
";
// Section 8: Key Action Steps
blueprint += "
8. Your Blueprint Summary - Key Action Steps
";
blueprint += "
Based on your inputs, here are a few key actions to start with:
";
blueprint += `- Clarify & Prioritize: Revisit your main goal: '${data.mainGoal || 'Define a Clear Goal'}'. Break it down and prioritize tasks related to it, perhaps using the Eisenhower Matrix if you're tackling 'Overwhelm' or 'Poor Planning'.
`;
blueprint += `- Optimize Your Focus Time: Schedule your most important work during your ${data.peakEnergy}. If 'Distractions' or 'Lack of Focus' are issues, actively create a focused environment and consider a technique like Time Blocking or Pomodoro.
`;
blueprint += `- Experiment & Adapt: Pick one or two new strategies or techniques mentioned (e.g., from the ${data.techniques.join(', ') || 'suggested techniques'} list) and try them consistently for a week. See what fits your ${data.workStyle} and adjust.
`;
blueprint += `- Consistent Review: Based on your ${data.planningHorizon}, set up a regular review (e.g., daily or weekly) to check progress, adjust plans, and reinforce good habits.
`;
blueprint += "
";
generatedBlueprintHTML = blueprint; // Store for PDF
document.getElementById('ppbg-blueprint-output').innerHTML = blueprint;
document.getElementById('ppbg-pdf-download').style.display = 'inline-block';
}
function ppbgDownloadPDF() {
if (!generatedBlueprintHTML) {
alert("Please generate your blueprint first.");
return;
}
const doc = new jsPDF('p', 'pt', 'a4');
const FONT_FAMILY = "helvetica";
const ACCENT_COLOR_HEX = getComputedStyle(document.documentElement).getPropertyValue('--accent-color').trim();
const PRIMARY_TEXT_COLOR_HEX = getComputedStyle(document.documentElement).getPropertyValue('--primary-text').trim();
const HEADING_COLOR_HEX = getComputedStyle(document.documentElement).getPropertyValue('--blueprint-heading-color').trim();
const BUTTON_TEXT_COLOR_HEX = getComputedStyle(document.documentElement).getPropertyValue('--button-text-color').trim();
const margin = 40;
const pageWidth = doc.internal.pageSize.getWidth();
const usableWidth = pageWidth - (2 * margin);
let yPos = 40;
// PDF Header
doc.setFillColor(ACCENT_COLOR_HEX);
doc.rect(0, 0, pageWidth, yPos + 10, 'F');
doc.setFont(FONT_FAMILY, "bold");
doc.setFontSize(18);
doc.setTextColor(BUTTON_TEXT_COLOR_HEX);
doc.text("Your Personal Productivity Blueprint", pageWidth / 2, yPos, { align: "center" });
yPos += 30;
// Generated Date
doc.setFont(FONT_FAMILY, "italic");
doc.setFontSize(9);
doc.setTextColor(PRIMARY_TEXT_COLOR_HEX);
const reportDate = new Date().toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' });
doc.text(`Generated on: ${reportDate}`, margin, yPos);
yPos += 20;
// --- Function to add HTML content to PDF ---
// This is a simplified parser. For complex HTML, a dedicated library would be better.
const addHtmlContent = (htmlString) => {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlString;
const processNode = (node) => {
if (yPos > doc.internal.pageSize.getHeight() - margin * 1.5) { // Check for page break
doc.addPage();
yPos = margin;
}
switch(node.nodeName) {
case 'H2':
doc.setFont(FONT_FAMILY, "bold");
doc.setFontSize(16);
doc.setTextColor(HEADING_COLOR_HEX);
yPos += 5; // Extra space before H2
const h2Lines = doc.splitTextToSize(node.textContent.trim(), usableWidth);
doc.text(h2Lines, margin, yPos);
yPos += (h2Lines.length * 16 * 0.7) + 8; // Adjust spacing
break;
case 'H3':
doc.setFont(FONT_FAMILY, "bold");
doc.setFontSize(13);
doc.setTextColor(HEADING_COLOR_HEX);
yPos += 8; // Extra space before H3
const h3Lines = doc.splitTextToSize(node.textContent.trim(), usableWidth);
doc.text(h3Lines, margin, yPos);
yPos += (h3Lines.length * 13 * 0.7) + 6;
break;
case 'P':
doc.setFont(FONT_FAMILY, "normal");
doc.setFontSize(10);
doc.setTextColor(PRIMARY_TEXT_COLOR_HEX);
// Handle P tags with STRONG tags inside for inline bolding
let pContent = [];
let currentStyle = 'normal';
node.childNodes.forEach(childNode => {
if (childNode.nodeName === 'STRONG') {
pContent.push({ text: childNode.textContent, bold: true });
} else if (childNode.nodeType === Node.TEXT_NODE) {
pContent.push({ text: childNode.textContent, bold: false });
} else if (childNode.nodeName === 'EM') {
pContent.push({ text: childNode.textContent, italic: true });
}
});
let currentX = margin;
pContent.forEach(segment => {
doc.setFont(FONT_FAMILY, segment.bold ? "bold" : (segment.italic ? "italic" : "normal"));
const segmentLines = doc.splitTextToSize(segment.text, usableWidth - (currentX - margin));
segmentLines.forEach((line, index) => {
if (index > 0 || (currentX + doc.getStringUnitWidth(line) * doc.getFontSize() / doc.internal.scaleFactor) > (margin + usableWidth) ) {
// New line needed due to length or it's a subsequent line of a segment
yPos += (10 * 1.2); // Line height
currentX = margin;
if (yPos > doc.internal.pageSize.getHeight() - margin * 1.5) {doc.addPage(); yPos = margin;}
}
doc.text(line, currentX, yPos);
currentX += doc.getStringUnitWidth(line) * doc.getFontSize() / doc.internal.scaleFactor + (segment.text.endsWith(' ') ? (doc.getStringUnitWidth(' ') * doc.getFontSize() / doc.internal.scaleFactor) : 0);
});
});
yPos += (10 * 1.2) + 5; // Move to next line plus some margin
doc.setFont(FONT_FAMILY, "normal"); // Reset font style
break;
case 'UL':
case 'OL':
doc.setFont(FONT_FAMILY, "normal");
doc.setFontSize(10);
doc.setTextColor(PRIMARY_TEXT_COLOR_HEX);
Array.from(node.children).filter(child => child.nodeName === 'LI').forEach((li, idx) => {
if (yPos > doc.internal.pageSize.getHeight() - margin * 1.5) { doc.addPage(); yPos = margin; }
const bullet = (node.nodeName === 'OL' ? `${idx + 1}. ` : `• `);
// Handle LI tags with STRONG tags inside
let liCurrentX = margin + 10;
li.childNodes.forEach(childNode => {
doc.setFont(FONT_FAMILY, childNode.nodeName === 'STRONG' ? "bold" : "normal");
const textToSplit = childNode.textContent.trim();
const itemLines = doc.splitTextToSize(textToSplit, usableWidth - 15); // 15 for bullet and indent
itemLines.forEach((line, lineIdx) => {
if (lineIdx === 0) {
doc.text(bullet + line, margin + 5, yPos);
} else {
doc.text(line, margin + 15, yPos); // Indent subsequent lines
}
if (lineIdx < itemLines.length -1) yPos += (10 * 1.2);
});
});
yPos += (10 * 1.2) + 3; // Space after list item
doc.setFont(FONT_FAMILY, "normal"); // Reset
});
yPos += 5; // Extra space after list
break;
}
// Recursively process children if any (though this basic parser might not need deep recursion)
// Array.from(node.children).forEach(child => processNode(child));
};
Array.from(tempDiv.children).forEach(childElement => processNode(childElement));
};
// --- End of addHtmlContent function ---
addHtmlContent(generatedBlueprintHTML); // Parse and add the stored HTML
// Footer
const pageCount = doc.internal.getNumberOfPages();
for (let i = 1; i <= pageCount; i++) {
doc.setPage(i);
const pageHeight = doc.internal.pageSize.getHeight();
doc.setLineWidth(0.5);
doc.setDrawColor(ACCENT_COLOR_HEX);
doc.line(margin, pageHeight - 30, pageWidth - margin, pageHeight - 30);
doc.setFont(FONT_FAMILY, "normal");
doc.setFontSize(8);
doc.setTextColor(PRIMARY_TEXT_COLOR_HEX);
doc.text(`Personal Productivity Blueprint - Page ${i} of ${pageCount}`, pageWidth / 2, pageHeight - 20, { align: "center" });
}
doc.save("Personal_Productivity_Blueprint.pdf");
}
// Link "Other" checkbox to its text input visibility
document.getElementById('ch-other').addEventListener('change', function() {
document.getElementById('ch-other-text').style.display = this.checked ? 'block' : 'none';
if (!this.checked) {
document.getElementById('ch-other-text').value = '';
}
});