Dirty 30 in Jamaica 🌴✨

Grand Palladium Jamaica Resort & Spa

January 15 – 18, 2027

Celebrating Jamiah 🌴✨

Join us for a luxury tropical getaway filled with beach dinners, excursions, spa days, and unforgettable Dirty 30 memories in Jamaica.

🌴 Resort Experience

Grand Palladium Jamaica Resort & Spa

Adults-only luxury vibe (18+), all-inclusive beachfront resort experience with pools, swim-up bars, nightly entertainment, international dining, and oceanfront suites.

💰 Pricing & Payment Options

Member Rate (2 Guests): $1,502

Deposit Option Available — secure now, pay over time

Promo Code: 8PAQQN40I5

Flexible payment plans available through Pay Later Travel. Reserve your spot with a deposit and split payments weekly or bi-weekly.

✨ Itinerary

Jan 15: Arrival + resort vibes

Jan 16: Excursions + birthday beach dinner

Jan 17: Pool + nightlife + relaxation

Jan 18: Spa morning + departure

🌊 Excursions

Clear Kayak Photoshoot – $30

Jet Skis – $143

Bamboo Rafting – $21

Dunn’s River Falls – $69–$149

Chukka Ocean Outpost – $164+

📲 SMS Updates

activities: getActivities(), sms: document.getElementById("sms").checked, notes: document.getElementById("notes").value, status: "confirmed", updatedAt: new Date().toISOString() }; // SAVE OR UPDATE (PHONE = UNIQUE ID) await db.collection("guests").doc(phone).set(guestData, { merge: true }); // trigger celebration (we will expand in Part 4) triggerRSVPCelebration(); e.target.reset(); }); async function loadGuestByPhone(phone){ let doc = await db.collection("guests").doc(phone).get(); if(doc.exists){ let d = doc.data(); document.getElementById("name").value = d.name || ""; document.getElementById("email").value = d.email || ""; document.getElementById("plusOne").value = d.plusOne || ""; document.getElementById("airline").value = d.airline || ""; document.getElementById("flight").value = d.flight || ""; document.getElementById("airport").value = d.airport || ""; document.getElementById("arrival").value = d.arrival || ""; document.getElementById("departure").value = d.departure || ""; document.getElementById("room").value = d.room || ""; document.getElementById("dinner").value = d.dinner || ""; document.getElementById("notes").value = d.notes || ""; alert("Your RSVP has been loaded. You can now update it."); } }

🔐 Luxury Admin Dashboard

Search, manage, and export all Dirty 30 RSVPs

async function loadGuests(){ const snap = await db.collection("guests").get(); const container = document.getElementById("guestContainer"); container.innerHTML = ""; snap.forEach(doc=>{ const g = doc.data(); const block = `

${g.name || "No Name"}

Phone: ${g.phone || ""}

Email: ${g.email || ""}

Plus One: ${g.plusOne || "None"}

Room: ${g.room || ""}

Dinner: ${g.dinner || ""}

Flight: ${g.flight || "Not Added"}

Airline: ${g.airline || ""}

Airport: ${g.airport || ""}

Arrival: ${g.arrival || ""}

Departure: ${g.departure || ""}

Activities: ${(g.activities || []).join(", ")}

Notes: ${g.notes || ""}

Status: ${g.status || "confirmed"}

`; container.innerHTML += block; }); } async function markVIP(phone){ await db.collection("guests").doc(phone).set({ status:"VIP" },{merge:true}); alert("Guest marked VIP 🌟"); loadGuests(); } async function deleteGuest(phone){ if(confirm("Remove this guest?")){ await db.collection("guests").doc(phone).delete(); alert("Guest removed"); loadGuests(); } } function exportCSV(){ db.collection("guests").get().then(snap=>{ let rows = [ ["Name","Phone","Email","PlusOne","Room","Dinner","Flight","Status"] ]; snap.forEach(doc=>{ let g = doc.data(); rows.push([ g.name, g.phone, g.email, g.plusOne, g.room, g.dinner, g.flight, g.status ]); }); let csv = rows.map(r=>r.join(",")).join("\n"); let blob = new Blob([csv], {type:"text/csv"}); let url = URL.createObjectURL(blob); let a = document.createElement("a"); a.href = url; a.download = "dirty30_guest_list.csv"; a.click(); }); } document.getElementById("adminSearch").addEventListener("input", async (e)=>{ const value = e.target.value.toLowerCase(); const snap = await db.collection("guests").get(); const container = document.getElementById("guestContainer"); container.innerHTML = ""; snap.forEach(doc=>{ const g = doc.data(); if( (g.name && g.name.toLowerCase().includes(value)) || (g.phone && g.phone.includes(value)) || (g.email && g.email.toLowerCase().includes(value)) ){ container.innerHTML += `

${g.name}

${g.phone}

${g.email}

`; } }); }); #celebration{ position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.75); display:flex; align-items:center; justify-content:center; z-index:9999; } .celebration-box{ text-align:center; padding:40px; border-radius:20px; background:rgba(20,20,20,.95); box-shadow:0 0 50px rgba(255,215,0,.4); color:#ffd700; animation:pop .6s ease; } @keyframes pop{ from{transform:scale(.3);opacity:0} to{transform:scale(1);opacity:1} } /* AIRPLANE */ .plane{ position:fixed; top:20%; left:-200px; font-size:40px; z-index:9998; animation:fly 3s linear forwards; filter:drop-shadow(0 0 10px gold); } @keyframes fly{ to{ left:120%; transform:rotate(10deg); } } function triggerRSVPCelebration(){ // SHOW OVERLAY document.getElementById("celebration").classList.remove("hidden"); // PLAY SOUND let sound = document.getElementById("yaySound"); if(sound){ sound.currentTime = 0; sound.play(); } // FIREWORK BURST for(let i=0;i<25;i++){ setTimeout(()=>{ particles.push({ x: Math.random()*window.innerWidth, y: Math.random()*window.innerHeight/2, vy: Math.random()*6 + 2 }); }, i*80); } // AIRPLANE ANIMATION let plane = document.createElement("div"); plane.className = "plane"; plane.innerHTML = "✈️✨"; document.body.appendChild(plane); // REMOVE PLANE AFTER ANIMATION setTimeout(()=>{ plane.remove(); }, 3500); // HIDE CELEBRATION SCREEN setTimeout(()=>{ document.getElementById("celebration").classList.add("hidden"); }, 3000); } document.getElementById("rsvpForm").addEventListener("submit", async (e)=>{ e.preventDefault(); const phone = document.getElementById("phone").value; await db.collection("guests").doc(phone).set({ name: document.getElementById("name").value, phone: phone, email: document.getElementById("email").value, plusOne: document.getElementById("plusOne").value, airline: document.getElementById("airline").value, flight: document.getElementById("flight").value, airport: document.getElementById("airport").value, arrival: document.getElementById("arrival").value, departure: document.getElementById("departure").value, room: document.getElementById("room").value, dinner: document.getElementById("dinner").value, activities: getActivities(), sms: document.getElementById("sms").checked, notes: document.getElementById("notes").value, status: "confirmed", updatedAt: new Date().toISOString() }); // 🎆 TRIGGER FINAL EXPERIENCE triggerRSVPCelebration(); // RESET FORM e.target.reset(); });