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 = `
`;
}).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');
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
`;
}).join('')}
${totalAmount >= 2 ? `
Member: $${memberPrice.toFixed(2)} |
Standard: $${standardPrice.toFixed(2)}
${discount > 0 ? ` (${discount * 100}% bulk discount applied)` : ''}
💰 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}
`;
}).join('')}
Member: $${memberPrice.toFixed(2)} | Standard: $${standardPrice.toFixed(2)}
${category === 'Filler' && fillerDiscount > 0 ? ` (${fillerDiscount * 100}% bulk discount)` : ''}