Spa Day Planner
Design your perfect relaxation itinerary
Reservation Details
Preferences
Treatment Menu
Your Package
No treatments selected.
Total Duration:
0 min
Total Cost:
$0.00
*Exceeds budget goal
Proposed Itinerary
Includes 15-min transition buffer between services.
Summary
Arrival: --:--
Estimated Departure: --:--
Additional Notes & Requests
Ready to Relax?
Download your personalized itinerary PDF to take with you or send to the booking team.
Spa Itinerary
Plan prepared for:
| Date: |
Occasion: |
Guests: |
Selected Treatments
| Service | Duration | Cost |
|---|---|---|
| Total: |
Schedule
Notes:
Generated by Serenity Spa Planner
No treatments selected.
'; } else { basket.forEach((item, index) => { totalCost += item.cost; totalTime += item.duration; const div = document.createElement('div'); div.className = 'basket-item'; div.innerHTML = ` ${item.name} $${item.cost} × `; list.appendChild(div); }); } // Update Totals document.getElementById('spa-total-cost').innerText = '$' + totalCost.toFixed(2); document.getElementById('spa-total-time').innerText = totalTime + ' min'; // Check Budget const budget = parseFloat(document.getElementById('spa-budget').value) || 0; const warning = document.getElementById('spa-budget-warning'); if(budget > 0 && totalCost > budget) { warning.style.display = 'block'; } else { warning.style.display = 'none'; } } // --- Logic: Schedule Builder --- window.spaBuildItinerary = function() { const startInput = document.getElementById('spa-start-time').value; const lunchTime = parseInt(document.getElementById('spa-add-lunch').value); const buffer = 15; // min between services const timeline = document.getElementById('spa-timeline-container'); timeline.innerHTML = ''; if(basket.length === 0) { timeline.innerHTML = 'Please select treatments first.
'; return; } let [hrs, mins] = startInput.split(':').map(Number); let currentTime = new Date(); currentTime.setHours(hrs, mins, 0, 0); // Helper to fmt time const fmtTime = (date) => date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); document.getElementById('summ-start').innerText = fmtTime(currentTime); // Build List including breaks let scheduleItems = [...basket]; // Insert Lunch if > 0, ideally in middle (simplified here: after 2nd service or halfway) if(lunchTime > 0 && scheduleItems.length > 1) { const insertIndex = Math.ceil(scheduleItems.length / 2); scheduleItems.splice(insertIndex, 0, { name: 'Break / Lunch', duration: lunchTime, isBreak: true }); } scheduleItems.forEach((item, index) => { const startStr = fmtTime(currentTime); // Calculate End currentTime.setMinutes(currentTime.getMinutes() + item.duration); const endStr = fmtTime(currentTime); // Add to Timeline const div = document.createElement('div'); div.className = 'timeline-item'; div.innerHTML = `${startStr}
${item.name}
Until ${endStr} (${item.duration} min)
`;
timeline.appendChild(div);
// Add Buffer if not last item
if(index < scheduleItems.length - 1 && !item.isBreak) {
// buffer visual
currentTime.setMinutes(currentTime.getMinutes() + buffer);
}
});
document.getElementById('summ-end').innerText = fmtTime(currentTime);
};
// --- Navigation ---
window.spaNextTab = function(tabId) {
document.querySelectorAll('#spa-planner-tool .tab-content').forEach(t => t.classList.remove('active'));
document.querySelectorAll('#spa-planner-tool .tab-btn').forEach(t => t.classList.remove('active'));
document.getElementById(tabId).classList.add('active');
document.querySelector(`.tab-btn[data-tab="${tabId}"]`).classList.add('active');
document.getElementById('spa-planner-tool').scrollIntoView({ behavior: 'smooth' });
};
document.querySelectorAll('#spa-planner-tool .tab-btn').forEach(btn => {
btn.addEventListener('click', function() {
const id = this.getAttribute('data-tab');
spaNextTab(id);
if(id === 'spa-tab-itinerary') spaBuildItinerary();
});
});
// --- PDF Generation ---
document.getElementById('spa-download-btn').addEventListener('click', function() {
// Populate PDF Data
document.getElementById('pdf-guest-name').innerText = document.getElementById('spa-guest-name').value || 'Guest';
document.getElementById('pdf-date').innerText = document.getElementById('spa-date').value;
document.getElementById('pdf-occasion').innerText = document.getElementById('spa-occasion').value;
document.getElementById('pdf-guests').innerText = document.getElementById('spa-party-size').value;
document.getElementById('pdf-notes').innerText = document.getElementById('spa-notes').value;
// Treatments Table
const tBody = document.getElementById('pdf-treatments-body');
tBody.innerHTML = '';
let costTotal = 0;
let timeTotal = 0;
basket.forEach(item => {
costTotal += item.cost;
timeTotal += item.duration;
tBody.innerHTML += `
Until ${endStr} (${item.duration} min)
