Fitness Plan Generator

Personal Fitness Plan Generator

Personal Fitness Plan Generator

1. Personal Profile & Goals

2. Exercise Library

Available Exercises

    No exercises added yet.

3. Weekly Training Schedule

Paste the Name/Sets/Reps of exercises into the boxes below (one per line, e.g., Squats 3x10). Use 'REST' for off days.

Mon
Tue
Wed
Thu
Fri
Sat
Sun

No exercises added yet.

'; return; } exercises.forEach((ex, index) => { const li = document.createElement('li'); li.className = 'fpg-list-item'; li.innerHTML = ` ${ex.name} (${ex.sets}) `; li.querySelector('button').addEventListener('click', () => removeExercise(index)); exerciseList.appendChild(li); }); } function addExercise() { const name = exerciseNameInput.value.trim(); const sets = defaultSetsInput.value.trim(); if (!name || !sets) { alert("Please enter both an Exercise Name and Default Sets/Reps."); return; } if (exercises.some(ex => ex.name.toLowerCase() === name.toLowerCase())) { alert("This exercise is already in your library."); return; } exercises.push({ name, sets }); renderExercises(); // Clear form exerciseNameInput.value = ''; defaultSetsInput.value = '3x10'; } function removeExercise(index) { exercises.splice(index, 1); renderExercises(); } // --- PDF Generation (Ensured functionality) --- function downloadPDF() { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('Error: jsPDF library loaded.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF('landscape', 'pt', 'a4'); const margin = 40; const pageWidth = doc.internal.pageSize.getWidth(); let currentY = margin; // --- Gather Data --- const planName = planNameInput.value || 'Untitled Fitness Plan'; const focus = focusSelect.value; const duration = durationInput.value || 'N/A'; const goalStatement = goalStatementTextarea.value || 'N/A'; // --- Helper function to add structured text sections --- function addTextSection(title, content, startY) { const estimatedHeight = 15 + (content.split('\n').length * 12) + 10; if (startY + estimatedHeight > doc.internal.pageSize.getHeight() - margin) { doc.addPage(); startY = margin; } doc.setFontSize(12); doc.setFont('helvetica', 'bold'); doc.setTextColor(13, 148, 136); // teal-600 doc.text(title, margin, startY); doc.setFontSize(10); doc.setFont('helvetica', 'normal'); doc.setTextColor(51, 65, 85); const lines = doc.splitTextToSize(content || 'N/A', pageWidth - margin * 2); doc.text(lines, margin, startY + 15); return startY + 15 + lines.length * 12 + 10; } // --- Header --- doc.setFontSize(22); doc.setFont('helvetica', 'bold'); doc.setTextColor(13, 148, 136); doc.text(planName, pageWidth / 2, currentY, { align: 'center' }); currentY += 15; doc.setFontSize(14); doc.text(`Focus: ${focus} | Duration: ${duration} Weeks`, pageWidth / 2, currentY, { align: 'center' }); currentY += 30; // --- Section 1: Goal --- currentY = addTextSection("1. Specific Goal Statement", goalStatement, currentY); // --- Section 2: Exercise Library --- doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text("2. Exercise Library & Default Parameters", margin, currentY); currentY += 10; if (exercises.length > 0) { const libraryData = exercises.map(ex => [ex.name, ex.sets]); doc.autoTable({ startY: currentY, head: [['Exercise', 'Default Sets x Reps']], body: libraryData, theme: 'striped', headStyles: { fillColor: [13, 148, 136] }, styles: { fontSize: 9, minCellHeight: 12 }, columnStyles: { 0: { fontStyle: 'bold' } }, margin: { left: margin, right: pageWidth / 2 + 10 } }); currentY = doc.autoTable.previous.finalY + 20; } // --- Section 3: Weekly Schedule --- doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text("3. Weekly Training Schedule", margin, currentY); currentY += 15; const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; const scheduleData = [days]; // Create a single row of schedule content const contentRow = Array.from(scheduleSlots).map(slot => slot.value.trim()); scheduleData.push(contentRow); doc.autoTable({ startY: currentY, head: [scheduleData[0]], body: [scheduleData[1]], theme: 'grid', headStyles: { fillColor: [13, 148, 136], textColor: [255, 255, 255] }, styles: { fontSize: 8, minCellHeight: 60, overflow: 'linebreak' }, columnStyles: { 0: { cellWidth: 'auto' } }, margin: { left: margin, right: margin }, didDrawCell: (data) => { // Apply background color to REST days const content = data.cell.text.join(' ').trim(); if (content.toUpperCase() === 'REST') { doc.setFillColor(241, 245, 249); // slate-100 doc.rect(data.cell.x, data.cell.y, data.cell.width, data.cell.height, 'F'); } } }); doc.save('fitness-plan.pdf'); } // --- Event Listeners and Initial Load --- addExerciseBtn.addEventListener('click', addExercise); exerciseList.addEventListener('click', (e) => { if (e.target.classList.contains('fpg-btn-red')) { const index = parseInt(e.target.dataset.index); removeExercise(index); } }); pdfBtn.addEventListener('click', downloadPDF); // Initial load renderExercises(); });
Scroll to Top