Short-Term Rental Cleaning Fee Estimator Short-Term Rental Cleaning Fee Estimator Calculate a fair and competitive cleaning fee for your rental property. Dashboard Data Configuration Your fee estimate will appear here. Please fill out the 'Data Configuration' tab first. Download Fee Breakdown Property Details Number of Bedrooms Studio 1 Bedroom 2 Bedrooms 3 Bedrooms 4 Bedrooms 5+ Bedrooms Number of Bathrooms 1 Bathroom 1.5 Bathrooms 2 Bathrooms 2.5 Bathrooms 3 Bathrooms 3.5+ Bathrooms Local Hourly Labor Rate ($) Additional Services Pets Allowed Smoking Allowed On-site Laundry (Linens & Towels) Deep Clean / First Clean Calculate Fee & View Dashboard → Based on an estimated ${results.totalHours.toFixed(2)} hours of work. Fee Breakdown Base Cleaning Fee $${results.baseFee.toFixed(2)} ${extrasHtml} `; downloadBtn.classList.remove('hidden'); const ctx = document.getElementById('feeChart')?.getContext('2d'); if(ctx) { if (feeChart) feeChart.destroy(); feeChart = new Chart(ctx, { type: 'doughnut', data: { labels: Object.keys(results.breakdown), datasets: [{ data: Object.values(results.breakdown), backgroundColor: ['#0ea5e9', '#10b981'], borderColor: '#ffffff', borderWidth: 3 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom' }, tooltip: { callbacks: { label: (c) => `${c.label}: $${c.raw.toFixed(2)}` } } } } }); } } function downloadPDF() { const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const contentToPrint = document.getElementById('dashboard-content'); if (!contentToPrint) return; html2canvas(contentToPrint, { scale: 2, useCORS: true, onclone: (doc) => { const chartCanvas = doc.getElementById('feeChart'); if (chartCanvas && feeChart) { const img = new Image(); img.src = feeChart.toBase64Image(); img.style.maxWidth = '100%'; img.style.height = 'auto'; chartCanvas.parentNode.replaceChild(img, chartCanvas); } } }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = (canvas.height * pdfWidth) / canvas.width; pdf.addImage(imgData, 'PNG', 10, 10, pdfWidth - 20, pdfHeight > 277 ? 277 : pdfHeight - 20); pdf.save('Cleaning-Fee-Estimate.pdf'); }); }