Plump Treatment Logger

Plump Treatment Logger

Professional Treatment Tracking

Brooklyn
Tribeca
Hoboken
Miami
SoHo
Uptown
West Village

Select Treatment Category

💉

Dermal Fillers

Juvederm, Restylane

Botox

All Botox types

🧬

Biostimulants

Sculptra, Radiesse, PRP

🔄

Dissolvers

Kybella, Hylenex

Dermal Fillers

Ultra
Ultra Plus
Voluma
Vollure
Volbella
Skinvive
Resty L
Kysse
Refyne
Defyne
Lyft
Contour
0.25cc
0.5cc
0.75cc
1.0cc
1.25cc
1.5cc
1.75cc
2.0cc
2.25cc
2.5cc
2.75cc
3.0cc

Botox Treatment

Botox Cosmetic

Dysport

Botox equivalency only

Letybo

25% off

Biostimulants

Dissolvers

detailsDiv = document.getElementById('discount-details'); if (!discountDiv || !detailsDiv) return; const currentTotal = appState.treatments .filter(t => t.category === 'Filler') .reduce((sum, t) => sum + t.amount, 0); const potentialTotal = currentTotal + (appState.currentFillerDose || 0); let discountText = ''; let savingsAmount = 0; if (potentialTotal >= 3) { // Calculate actual savings with tiered pricing let totalWithoutDiscount = 0; let totalWithDiscount = 0; // Calculate current treatments appState.treatments .filter(t => t.category === 'Filler') .forEach(t => { totalWithoutDiscount += calculateFillerPrice(t.amount, 'standard'); }); // Add potential new filler if (appState.currentFillerDose) { totalWithoutDiscount += calculateFillerPrice(appState.currentFillerDose, 'standard'); } totalWithDiscount = totalWithoutDiscount * 0.9; // 10% off savingsAmount = totalWithoutDiscount - totalWithDiscount; discountText = `10% OFF all fillers! (${potentialTotal}cc total) - Save $${savingsAmount.toFixed(2)}`; } else if (potentialTotal >= 2) { // Calculate 5% savings let totalWithoutDiscount = 0; let totalWithDiscount = 0; appState.treatments .filter(t => t.category === 'Filler') .forEach(t => { totalWithoutDiscount += calculateFillerPrice(t.amount, 'standard'); }); if (appState.currentFillerDose) { totalWithoutDiscount += calculateFillerPrice(appState.currentFillerDose, 'standard'); } totalWithDiscount = totalWithoutDiscount * 0.95; // 5% off savingsAmount = totalWithoutDiscount - totalWithDiscount; discountText = `5% OFF all fillers! (${potentialTotal}cc total) - Save $${savingsAmount.toFixed(2)}`; } else if (potentialTotal >= 1.5) { const needed = (2 - potentialTotal).toFixed(2); discountText = `Add ${needed}cc more for 5% OFF all fillers!`; } // Show why 1cc is cost-effective if (appState.currentFillerDose === 1.0 && discountText === '') { const halfCcCost = calculateFillerPrice(0.5, 'standard') * 2; const oneCcCost = calculateFillerPrice(1.0, 'standard'); const savings = halfCcCost - oneCcCost; discountText = `💡 1cc saves $${savings.toFixed(2)} vs two 0.5cc syringes!`; } if (discountText) { detailsDiv.innerHTML = discountText; discountDiv.style.display = 'block'; } else { discountDiv.style.display = 'none'; } } catch (error) { console.error('Error updating filler discount display:', error); } } function resetFillerType() { appState.currentFillerType = null; appState.currentFillerDose = null; document.getElementById('filler-type').value = ''; document.getElementById('selected-dose').value = ''; document.querySelectorAll('.filler-grid .option-btn').forEach(btn => btn.classList.remove('selected')); document.querySelectorAll('.dose-grid .dose-btn').forEach(btn => btn.classList.remove('selected')); document.getElementById('add-filler-btn').style.display = 'none'; document.getElementById('add-continue-btn').style.display = 'none'; updateFillerDiscountDisplay(); } function addSelectedFiller() { try { const type = appState.currentFillerType; const amount = appState.currentFillerDose; if (!type || !amount) { showError('filler-error', 'Please select both filler type and dose'); return; } appState.treatments.push({ category: 'Filler', type: type, amount: amount, code: `FILL_${amount.toString().replace('.', '')}` }); // Log filler addition for analytics console.log('Filler added:', { type, amount, timestamp: new Date() }); updateFillerList(); resetFillerType(); updatePriceFooter(); showPage('category-page'); } catch (error) { console.error('Error in addSelectedFiller:', error); showError('filler-error', 'Error adding filler. Please try again.'); } } function addSelectedFillerAndContinue() { try { const type = appState.currentFillerType; const amount = appState.currentFillerDose; if (!type || !amount) { showError('filler-error', 'Please select both filler type and dose'); return; } appState.treatments.push({ category: 'Filler', type: type, amount: amount, code: `FILL_${amount.toString().replace('.', '')}` }); updateFillerList(); updatePriceFooter(); // Reset dose but keep type selected appState.currentFillerDose = null; document.getElementById('selected-dose').value = ''; document.querySelectorAll('.dose-grid .dose-btn').forEach(btn => btn.classList.remove('selected')); document.getElementById('add-filler-btn').style.display = 'none'; document.getElementById('add-continue-btn').style.display = 'none'; updateFillerDiscountDisplay(); showSuccess('filler-error', `${type} ${amount}cc added! Select another dose or choose a different type.`); } catch (error) { console.error('Error in addSelectedFillerAndContinue:', error); showError('filler-error', 'Error adding filler. Please try again.'); } } function updateFillerList() { try { const fillerList = document.getElementById('filler-list'); if (!fillerList) return; const fillers = appState.treatments.filter(t => t.category === 'Filler'); if (fillers.length === 0) { fillerList.innerHTML = ''; return; } // Calculate prices with bulk discounts const totalAmount = fillers.reduce((sum, f) => sum + f.amount, 0); let discount = 0; if (totalAmount >= 3) discount = 0.10; else if (totalAmount >= 2) discount = 0.05; fillerList.innerHTML = `

Selected Fillers:

${fillers.map((filler, index) => { const memberPrice = calculateFillerPrice(filler.amount, 'member') * (1 - discount); const standardPrice = calculateFillerPrice(filler.amount, 'standard') * (1 - discount); return `
${filler.type} - ${filler.amount}cc
Member: $${memberPrice.toFixed(2)} | Standard: $${standardPrice.toFixed(2)} ${discount > 0 ? ` (${discount * 100}% bulk discount applied)` : ''}
`; }).join('')} ${totalAmount >= 2 ? `
💰 Bulk Discount Active! ${discount * 100}% off all fillers (${totalAmount}cc total)
` : ''} `; } catch (error) { console.error('Error updating filler list:', error); } } /* ======================================== BOTOX FUNCTIONS ======================================== */ function selectBotoxType(type, element) { try { document.querySelectorAll('#botox-page .category-card').forEach(card => card.classList.remove('selected')); element.classList.add('selected'); appState.currentBotoxType = type; document.getElementById('botox-mode-section').style.display = 'block'; if (appState.currentBotoxMode === 'areas') { updateLipFlipAvailability(); } updateBotoxPricing(); } catch (error) { console.error('Error in selectBotoxType:', error); } } function selectBotoxMode(mode, element) { document.querySelectorAll('#botox-mode-section .option-btn').forEach(btn => btn.classList.remove('selected')); element.classList.add('selected'); document.getElementById('botox-mode').value = mode; appState.currentBotoxMode = mode; const areasSection = document.getElementById('botox-areas-section'); const areaUnitsSection = document.getElementById('botox-area-units-section'); const unitsSection = document.getElementById('botox-units-section'); if (mode === 'areas') { areasSection.style.display = 'block'; areaUnitsSection.style.display = 'block'; unitsSection.style.display = 'none'; updateLipFlipAvailability(); } else if (mode === 'units') { areasSection.style.display = 'none'; areaUnitsSection.style.display = 'none'; unitsSection.style.display = 'block'; } else if (mode === 'minitox') { areasSection.style.display = 'none'; areaUnitsSection.style.display = 'none'; unitsSection.style.display = 'block'; } updateBotoxPricing(); } function updateLipFlipAvailability() { const lipFlipBtn = document.getElementById('lip-flip-btn'); if (lipFlipBtn) { if (appState.currentBotoxType === 'Botox Cosmetic') { lipFlipBtn.style.opacity = '1'; lipFlipBtn.style.pointerEvents = 'auto'; lipFlipBtn.style.background = '#f8f9fa'; lipFlipBtn.style.color = '#333'; } else { lipFlipBtn.style.opacity = '0.3'; lipFlipBtn.style.pointerEvents = 'none'; lipFlipBtn.style.background = '#e9ecef'; lipFlipBtn.style.color = '#999'; lipFlipBtn.classList.remove('active-area'); appState.currentBotoxAreas = appState.currentBotoxAreas.filter(area => area !== 'Lip Flip/Gummy Smile'); } } } function toggleArea(area, element) { try { if (element.classList.contains('active-area')) { element.classList.remove('active-area'); appState.currentBotoxAreas = appState.currentBotoxAreas.filter(a => a !== area); } else { element.classList.add('active-area'); appState.currentBotoxAreas.push(area); } updateBotoxPricing(); } catch (error) { console.error('Error in toggleArea:', error); } } function updateBotoxPricing() { try { const pricingDiv = document.getElementById('botox-pricing'); const addBtn = document.getElementById('add-botox-btn'); const continueBtn = document.getElementById('add-botox-continue-btn'); const unitHint = document.getElementById('unit-discount-hint'); const areaUnitHint = document.getElementById('area-unit-discount-hint'); const mode = appState.currentBotoxMode; const areas = appState.currentBotoxAreas.length; let units = 0; if (mode === 'areas') { units = parseInt(document.getElementById('botox-area-units').value) || 0; } else { units = parseInt(document.getElementById('botox-units').value) || 0; } // Show hints for bulk pricing if (areaUnitHint && mode === 'areas') { if (units >= 80 && units < 100) { areaUnitHint.style.display = 'block'; } else { areaUnitHint.style.display = 'none'; } } if (unitHint && (mode === 'units' || mode === 'minitox')) { if (units >= 90 && units < 100) { unitHint.style.display = 'block'; unitHint.innerHTML = '💡 Bulk Discount Available! Add ' + (100 - units) + ' more units for 10% off unit pricing'; } else if (units >= 100) { unitHint.style.display = 'block'; unitHint.innerHTML = '🎉 Bulk Discount Applied! 10% off unit pricing for 100+ units'; unitHint.style.background = '#e6f3e6'; unitHint.style.borderColor = '#28a745'; unitHint.style.color = '#155724'; } else { unitHint.style.display = 'none'; } } if (!appState.currentBotoxType || !mode) { if (pricingDiv) pricingDiv.style.display = 'none'; if (addBtn) addBtn.style.display = 'none'; if (continueBtn) continueBtn.style.display = 'none'; return; } let memberPrice = 0; let standardPrice = 0; let canProceed = false; if (mode === 'areas') { if (areas > 0) { if (areas === 1 && appState.currentBotoxAreas[0] === 'Lip Flip/Gummy Smile') { memberPrice = PRICING.botox.member.lipFlipSolo; standardPrice = PRICING.botox.standard.lipFlipSolo; } else { memberPrice = PRICING.botox.member.areas[areas] || 0; standardPrice = PRICING.botox.standard.areas[areas] || 0; } canProceed = true; } } else if (mode === 'minitox') { if (units > 0) { memberPrice = PRICING.botox.member.minitox; standardPrice = PRICING.botox.standard.minitox; canProceed = true; } } else if (mode === 'units') { if (units > 0) { const memberUnitPrice = units >= 100 ? PRICING.botox.member.unitPriceHigh : PRICING.botox.member.unitPrice; const standardUnitPrice = units >= 100 ? PRICING.botox.standard.unitPriceHigh : PRICING.botox.standard.unitPrice; memberPrice = units * memberUnitPrice; standardPrice = units * standardUnitPrice; canProceed = true; } } // Apply Letybo discount if (appState.currentBotoxType === 'Letybo') { memberPrice *= 0.75; standardPrice *= 0.75; } if (canProceed && pricingDiv) { let extraInfo = ''; if (appState.currentBotoxType === 'Letybo') { extraInfo += '
✨ 25% Letybo discount applied
'; } if (mode === 'units' && units >= 100) { extraInfo += '
💰 10% bulk discount for 100+ units applied
'; } pricingDiv.innerHTML = `
Member Price:$${memberPrice.toFixed(2)}
Standard Price:$${standardPrice.toFixed(2)}
${extraInfo} `; pricingDiv.style.display = 'block'; if (addBtn) addBtn.style.display = 'block'; if (continueBtn) continueBtn.style.display = 'block'; } else { if (pricingDiv) pricingDiv.style.display = 'none'; if (addBtn) addBtn.style.display = 'none'; if (continueBtn) continueBtn.style.display = 'none'; } } catch (error) { console.error('Error in updateBotoxPricing:', error); } } function addBotoxAndContinue() { try { const mode = appState.currentBotoxMode; const areas = appState.currentBotoxAreas.slice(); let units = 0; if (mode === 'areas') { units = parseInt(document.getElementById('botox-area-units').value) || 0; } else { units = parseInt(document.getElementById('botox-units').value) || 0; } if (!appState.currentBotoxType || !mode || units <= 0) { showError('botox-error', 'Please complete all Botox fields with valid values'); return; } if (mode === 'areas' && areas.length === 0) { showError('botox-error', 'Please select at least one treatment area'); return; } const treatment = { category: 'Botox', type: appState.currentBotoxType, mode: mode, units: units, areas: areas, code: `BOTOX_${appState.currentBotoxType.replace(' ', '_').toUpperCase()}` }; appState.treatments.push(treatment); // Log Botox addition for analytics console.log('Botox added:', { type: appState.currentBotoxType, mode, units, areas, timestamp: new Date() }); // Reset form but keep type selected appState.currentBotoxMode = null; appState.currentBotoxAreas = []; document.getElementById('botox-area-units').value = ''; document.getElementById('botox-units').value = ''; document.getElementById('botox-areas-section').style.display = 'none'; document.getElementById('botox-area-units-section').style.display = 'none'; document.getElementById('botox-units-section').style.display = 'none'; document.getElementById('botox-pricing').style.display = 'none'; document.getElementById('add-botox-btn').style.display = 'none'; document.getElementById('add-botox-continue-btn').style.display = 'none'; document.getElementById('botox-mode').value = ''; document.querySelectorAll('#botox-mode-section .option-btn').forEach(btn => btn.classList.remove('selected')); document.querySelectorAll('#botox-areas-section .option-btn').forEach(btn => btn.classList.remove('active-area')); updatePriceFooter(); // Calculate total units for this Botox type const totalUnits = appState.treatments .filter(t => t.category === 'Botox' && t.type === appState.currentBotoxType) .reduce((sum, t) => sum + t.units, 0); if (totalUnits >= 80 && totalUnits < 100) { showSuccess('botox-error', `${appState.currentBotoxType} added! Total ${appState.currentBotoxType} units: ${totalUnits}. Add ${100 - totalUnits} more for bulk pricing!`); } else if (totalUnits >= 100) { showSuccess('botox-error', `${appState.currentBotoxType} added! Total ${appState.currentBotoxType} units: ${totalUnits} - Bulk pricing active!`); } else { showSuccess('botox-error', `${appState.currentBotoxType} treatment added! Select mode to add more.`); } } catch (error) { console.error('Error in addBotoxAndContinue:', error); showError('botox-error', 'Error adding Botox treatment. Please try again.'); } } function addBotox() { try { const mode = appState.currentBotoxMode; const areas = appState.currentBotoxAreas.slice(); let units = 0; if (mode === 'areas') { units = parseInt(document.getElementById('botox-area-units').value) || 0; } else { units = parseInt(document.getElementById('botox-units').value) || 0; } if (!appState.currentBotoxType || !mode || units <= 0) { showError('botox-error', 'Please complete all Botox fields with valid values'); return; } if (mode === 'areas' && areas.length === 0) { showError('botox-error', 'Please select at least one treatment area'); return; } const treatment = { category: 'Botox', type: appState.currentBotoxType, mode: mode, units: units, areas: areas, code: `BOTOX_${appState.currentBotoxType.replace(' ', '_').toUpperCase()}` }; appState.treatments.push(treatment); resetBotoxForm(); updatePriceFooter(); showPage('category-page'); } catch (error) { console.error('Error in addBotox:', error); showError('botox-error', 'Error adding Botox treatment. Please try again.'); } } function resetBotoxForm() { try { appState.currentBotoxType = null; appState.currentBotoxMode = null; appState.currentBotoxAreas = []; document.getElementById('botox-area-units').value = ''; document.getElementById('botox-units').value = ''; document.getElementById('botox-mode-section').style.display = 'none'; document.getElementById('botox-areas-section').style.display = 'none'; document.getElementById('botox-area-units-section').style.display = 'none'; document.getElementById('botox-units-section').style.display = 'none'; document.getElementById('botox-pricing').style.display = 'none'; document.getElementById('add-botox-btn').style.display = 'none'; document.getElementById('add-botox-continue-btn').style.display = 'none'; document.getElementById('botox-mode').value = ''; document.querySelectorAll('#botox-page .category-card').forEach(card => card.classList.remove('selected')); document.querySelectorAll('#botox-mode-section .option-btn').forEach(btn => btn.classList.remove('selected')); document.querySelectorAll('#botox-areas-section .option-btn').forEach(btn => btn.classList.remove('active-area')); } catch (error) { console.error('Error in resetBotoxForm:', error); } } /* ======================================== BIOSTIMULANTS FUNCTIONS ======================================== */ function addBiostimulants() { try { const sculptraInput = document.getElementById('sculptra-qty'); const radiesseInput = document.getElementById('radiesse-qty'); const prpInput = document.getElementById('prp-check'); const sculptraQty = sculptraInput ? parseInt(sculptraInput.value) || 0 : 0; const radiesseQty = radiesseInput ? parseInt(radiesseInput.value) || 0 : 0; const prpChecked = prpInput ? prpInput.checked : false; if (sculptraQty <= 0 && radiesseQty <= 0 && !prpChecked) { showError('biostim-error', 'Please select at least one biostimulant treatment'); return; } // Remove existing biostimulant treatments to avoid duplicates appState.treatments = appState.treatments.filter(t => !['Sculptra', 'Radiesse', 'PRP'].includes(t.type)); if (sculptraQty > 0) { appState.treatments.push({ category: 'Biostimulant', type: 'Sculptra', amount: sculptraQty, code: 'BIO_SCULP' }); } if (radiesseQty > 0) { appState.treatments.push({ category: 'Biostimulant', type: 'Radiesse', amount: radiesseQty, code: 'BIO_RADI' }); } if (prpChecked) { appState.treatments.push({ category: 'Biostimulant', type: 'PRP', amount: 1, code: 'BIO_PRP' }); } // Clear inputs sculptraInput.value = ''; radiesseInput.value = ''; prpInput.checked = false; updatePriceFooter(); showPage('category-page'); } catch (error) { console.error('Error in addBiostimulants:', error); showError('biostim-error', 'Error adding biostimulant treatments. Please try again.'); } } /* ======================================== DISSOLVERS FUNCTIONS ======================================== */ function addDissolvers() { try { const kybellaInput = document.getElementById('kybella-qty'); const hylenexInput = document.getElementById('hylenex-qty'); const kybellaQty = kybellaInput ? parseInt(kybellaInput.value) || 0 : 0; const hylenexQty = hylenexInput ? parseInt(hylenexInput.value) || 0 : 0; if (kybellaQty <= 0 && hylenexQty <= 0) { showError('dissolver-error', 'Please select at least one dissolver treatment'); return; } // Remove existing dissolver treatments to avoid duplicates appState.treatments = appState.treatments.filter(t => !['Kybella', 'Hylenex'].includes(t.type)); if (kybellaQty > 0) { appState.treatments.push({ category: 'Dissolver', type: 'Kybella', amount: kybellaQty, code: 'DIS_KYB' }); } if (hylenexQty > 0) { appState.treatments.push({ category: 'Dissolver', type: 'Hylenex', amount: hylenexQty, code: 'DIS_HYL' }); } // Clear inputs kybellaInput.value = ''; hylenexInput.value = ''; updatePriceFooter(); showPage('category-page'); } catch (error) { console.error('Error in addDissolvers:', error); showError('dissolver-error', 'Error adding dissolver treatments. Please try again.'); } } /* ======================================== SUMMARY FUNCTIONS ======================================== */ function selectPricingType(type, element) { document.querySelectorAll('#summary-page .location-grid .option-btn').forEach(btn => { btn.classList.remove('selected'); if (btn.textContent.includes('COMPED')) { btn.style.background = '#28a745'; btn.style.color = 'white'; btn.style.borderColor = '#28a745'; } }); element.classList.add('selected'); if (type === 'comped') { element.style.background = '#155724'; element.style.borderColor = '#155724'; } document.getElementById('pricing-type').value = type; updatePriceFooter(); updateSavingsDisplay(); } function updateSummary() { try { const summaryDiv = document.getElementById('treatment-summary'); if (!summaryDiv) return; if (appState.treatments.length === 0) { summaryDiv.innerHTML = '

No treatments added yet.

'; updateSavingsDisplay(); return; } // Group treatments by category for better organization const groupedTreatments = { 'Filler': [], 'Botox': [], 'Biostimulant': [], 'Dissolver': [] }; appState.treatments.forEach(treatment => { groupedTreatments[treatment.category].push(treatment); }); // Calculate prices with proper bulk discounts for fillers const totalFillerAmount = groupedTreatments['Filler'].reduce((sum, t) => sum + t.amount, 0); let fillerDiscount = 0; if (totalFillerAmount >= 3) fillerDiscount = 0.10; else if (totalFillerAmount >= 2) fillerDiscount = 0.05; summaryDiv.innerHTML = `

Selected Treatments:

${Object.entries(groupedTreatments).map(([category, treatments]) => { if (treatments.length === 0) return ''; return `
${category}
${treatments.map((treatment, index) => { let memberPrice = 0; let standardPrice = 0; if (category === 'Filler') { memberPrice = calculateFillerPrice(treatment.amount, 'member') * (1 - fillerDiscount); standardPrice = calculateFillerPrice(treatment.amount, 'standard') * (1 - fillerDiscount); } else { memberPrice = calculateTreatmentPrice(treatment, 'member'); standardPrice = calculateTreatmentPrice(treatment, 'standard'); } let details = ''; if (treatment.category === 'Botox') { if (treatment.mode === 'areas') { details = `${treatment.areas.join(', ')}, ${treatment.units} units`; } else if (treatment.mode === 'minitox') { details = `Mini-Tox, ${treatment.units} units`; } else { details = `${treatment.units} units`; } } else if (treatment.category === 'Filler') { details = `${treatment.amount}cc`; } else { details = treatment.amount > 1 ? `${treatment.amount} units` : '1 treatment'; } return `
${treatment.type} - ${details}
Member: $${memberPrice.toFixed(2)} | Standard: $${standardPrice.toFixed(2)} ${category === 'Filler' && fillerDiscount > 0 ? ` (${fillerDiscount * 100}% bulk discount)` : ''}
`; }).join('')}
`; }).join('')} `; updateSavingsDisplay(); } catch (error) { console.error('Error updating summary:', error); } } function removeTreatmentByIndex(index) { try { if (index >= 0 && index < appState.treatments.length) { appState.treatments.splice(index, 1); updateSummary(); updateFillerList(); updatePriceFooter(); updateSavingsDisplay(); updateFillerDiscountDisplay(); } } catch (error) { console.error('Error removing treatment:', error); } } /* ======================================== SUBMISSION FUNCTIONS ======================================== */ async function submitTreatment() { try { const patientInput = document.getElementById('patient-initials'); const notesInput = document.getElementById('notes'); const pricingInput = document.getElementById('pricing-type'); const patientInitials = patientInput ? patientInput.value.trim() : ''; const notes = notesInput ? notesInput.value.trim() : ''; const pricingType = pricingInput ? pricingInput.value : 'standard'; if (!patientInitials) { showError('summary-error', 'Patient initials are required'); return; } if (appState.treatments.length === 0) { showError('summary-error', 'Please add at least one treatment'); return; } showPage('loading-page'); const now = new Date(); // Calculate proper totals const fillerTreatments = appState.treatments.filter(t => t.category === 'Filler'); const totalFillerAmount = fillerTreatments.reduce((sum, t) => sum + t.amount, 0); let fillerDiscount = 0; if (totalFillerAmount >= 3) fillerDiscount = 0.10; else if (totalFillerAmount >= 2) fillerDiscount = 0.05; // Calculate member total let totalMemberPrice = 0; fillerTreatments.forEach(t => { totalMemberPrice += calculateFillerPrice(t.amount, 'member') * (1 - fillerDiscount); }); appState.treatments.filter(t => t.category !== 'Filler').forEach(t => { totalMemberPrice += calculateTreatmentPrice(t, 'member'); }); // Calculate standard total let totalStandardPrice = 0; fillerTreatments.forEach(t => { totalStandardPrice += calculateFillerPrice(t.amount, 'standard') * (1 - fillerDiscount); }); appState.treatments.filter(t => t.category !== 'Filler').forEach(t => { totalStandardPrice += calculateTreatmentPrice(t, 'standard'); }); const appliedPrice = pricingType === 'comped' ? 0 : pricingType === 'member' ? totalMemberPrice : totalStandardPrice; const submissionData = { date: now.toLocaleDateString('en-US'), time: now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }), staffName: appState.staff.name || '', location: appState.staff.location || '', patientInitials: patientInitials, notes: notes, pricingType: pricingType, totalMemberPrice: totalMemberPrice, totalStandardPrice: totalStandardPrice, appliedPrice: appliedPrice, treatments: JSON.stringify(appState.treatments) }; // Log submission for analytics console.log('Submitting treatment data:', submissionData); // Simulate Google Sheets submission // In production, replace this with actual Google Apps Script web app URL await simulateSubmission(submissionData); showPage('success-page'); } catch (error) { console.error('Submission error:', error); showError('summary-error', `Failed to submit: ${error.message}. Please try again.`); showPage('summary-page'); } } // Simulate submission for demo purposes async function simulateSubmission(data) { return new Promise((resolve) => { console.log('Simulated Google Sheets submission:', data); // Simulate network delay setTimeout(() => { console.log('Submission successful!'); resolve(); }, 2000); }); } /* ======================================== RESET AND INITIALIZATION ======================================== */ function resetApp() { try { // Keep staff info but reset treatments appState = { staff: appState.staff, treatments: [], currentBotoxType: null, currentBotoxMode: null, currentBotoxAreas: [], currentFillerType: null, currentFillerDose: null }; // Reset all form fields const fieldsToReset = [ 'patient-initials', 'notes', 'filler-type', 'selected-dose', 'sculptra-qty', 'radiesse-qty', 'kybella-qty', 'hylenex-qty', 'botox-area-units', 'botox-units' ]; fieldsToReset.forEach(id => { const element = document.getElementById(id); if (element) element.value = ''; }); // Reset checkboxes const prpCheck = document.getElementById('prp-check'); if (prpCheck) prpCheck.checked = false; // Reset pricing type document.getElementById('pricing-type').value = 'standard'; // Clear all selections document.querySelectorAll('.option-btn').forEach(btn => btn.classList.remove('selected')); document.querySelectorAll('.category-card').forEach(card => card.classList.remove('selected')); // Reset forms resetBotoxForm(); resetFillerType(); updateFillerList(); updatePriceFooter(); updateSavingsDisplay(); showPage('category-page'); } catch (error) { console.error('Error in resetApp:', error); } } /* ======================================== EVENT LISTENERS AND INITIALIZATION ======================================== */ document.addEventListener('DOMContentLoaded', function() { try { // Initialize Botox unit input listeners const botoxAreaUnitsInput = document.getElementById('botox-area-units'); const botoxUnitsInput = document.getElementById('botox-units'); if (botoxAreaUnitsInput) { botoxAreaUnitsInput.addEventListener('input', updateBotoxPricing); } if (botoxUnitsInput) { botoxUnitsInput.addEventListener('input', updateBotoxPricing); } // Add Enter key support for login const staffNameInput = document.getElementById('staff-name'); if (staffNameInput) { staffNameInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') handleLogin(); }); } // Add Enter key support for patient initials const patientInitialsInput = document.getElementById('patient-initials'); if (patientInitialsInput) { patientInitialsInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') submitTreatment(); }); } // Add keyboard navigation support document.querySelectorAll('.option-btn, .category-card').forEach(element => { element.addEventListener('keypress', function(e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); element.click(); } }); }); // Initialize price footer updatePriceFooter(); // Log application start for analytics console.log('Plump Treatment Logger initialized', { version: '2.0', timestamp: new Date(), features: ['Tiered Filler Pricing', 'Bulk Discounts', 'Multiple Treatment Types'] }); } catch (error) { console.error('Error during initialization:', error); } }); /* ======================================== GOOGLE APPS SCRIPT INTEGRATION Instructions for Google Sheets integration: 1. Create a new Google Sheet 2. Go to Extensions > Apps Script 3. Replace the code with the following: function doPost(e) { try { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const data = JSON.parse(e.postData.contents); // Add headers if this is the first entry if (sheet.getLastRow() === 0) { sheet.appendRow([ 'Date', 'Time', 'Staff Name', 'Location', 'Patient Initials', 'Pricing Type', 'Member Price', 'Standard Price', 'Applied Price', 'Treatments', 'Notes' ]); } // Add the data sheet.appendRow([ data.date, data.time, data.staffName, data.location, data.patientInitials, data.pricingType, data.totalMemberPrice, data.totalStandardPrice, data.appliedPrice, data.treatments, data.notes ]); return ContentService.createTextOutput('Success'); } catch (error) { return ContentService.createTextOutput('Error: ' + error.toString()); } } 4. Deploy as Web App 5. Copy the Web App URL 6. Replace 'YOUR_WEB_APP_URL_HERE' in the submitTreatment function ======================================== */ // Console warning about Google Sheets integration console.warn('Remember to set up Google Sheets integration by replacing the Web App URL in the submitTreatment function');