data hub

Fast, friendly data migrations — done with care, precision, and a smile. Import your data in minutes 👀


Wedding Questionnaire — Luci Sullivan Photo

Wedding details

Contact details

Wedding party

Event times

Shot list — before ceremony

Check everything you'd like included and add any special notes below.

Shot list — ceremony

Family photos

Check each grouping and add first & last names — this keeps things moving quickly so your family gets to cocktail hour!

Wedding party photos

Reception

My style is to capture your day in its truest form — not to make it feel like one big photoshoot, but to have your images feel like a reflection of you, your love, and your day. When the day comes I won't be checking a shot list. I want you to look back on these photos and remember exactly what it felt like.

— LUCI SULLIVAN PHOTO

✓

Thank you!

Your questionnaire has been submitted. Luci will be in touch soon.

const BEFORE = ["Invitations","Wedding Dress","Wedding Shoes & Accessories","Bride & Bridesmaids Getting Ready","Bride & Bridesmaids Robe/PJ Shots","Bride Getting In Dress","Bridal Portraits","Groom & Groomsmen Getting Ready","Groom Portraits","First Look Bride/Groom","Bride/Groom Reading Note/Opening Gift","Bride/Bridesmaids First Look","Bride/Parents First Look"]; const CEREMONY = ["Bridal Processional","Guests Seeing the Bride","Back of Bride's Dress","Groom At the Altar","Groom Seeing the Bride","Ring Exchange","The Kiss","Bride and Groom Exit","Kiss At End of Aisle"]; const FAMILY = ["Bride + Mother","Bride + Father","Bride + Parents","Bride + Siblings","Bride + Grandparents","Groom + Mother","Groom + Father","Groom + Parents","Groom + Siblings","Groom + Grandparents","Bride & Groom + Bride's Parents","Bride & Groom + Groom's Parents","Bride & Groom + Both Sets of Parents","Bride & Groom + Bride's Grandparents","Bride & Groom + Groom's Grandparents","Bride & Groom + Bride's Siblings","Bride & Groom + Groom's Siblings"]; const PARTY = ["Bride + Bridesmaids Group","Bride + Individual Bridesmaids","Bride + Groomsmen Group","Groom + Groomsmen Group","Groom + Individual Groomsmen","Groom + Bridesmaids Group","Bride & Groom + Wedding Full Party","Bride & Groom + Flower Girl","Bride & Groom + Ring Bearer"]; const RECEPTION = ["Cocktail Hour","Bride & Groom Room Reveal (before guest arrival)","Decorated Room","Table Details","Grand Entrance","Toasts","First Dance","Father/Daughter Dance","Mother/Son Dance","Cake Cutting","Champagne Tower Pour","Bouquet Toss","Garter Removal/Toss","Guests Dancing","Bride & Groom Special Exit"]; function makeChecklist(items, containerId, showNameInput=false) { const el = document.getElementById(containerId); items.forEach((item,i) => { const id = containerId+'_'+i; const wrap = document.createElement('div'); const lbl = document.createElement('label'); lbl.className = 'cb-row'; lbl.innerHTML = ` ${item}`; wrap.appendChild(lbl); if (showNameInput) { const inp = document.createElement('input'); inp.type = 'text'; inp.placeholder = 'Enter full names...'; inp.className = 'name-input'; inp.id = id+'_names'; wrap.appendChild(inp); lbl.querySelector('input').addEventListener('change', function(){ inp.classList.toggle('show', this.checked); }); } el.appendChild(wrap); }); } makeChecklist(BEFORE, 'beforeList'); makeChecklist(CEREMONY, 'ceremonyList'); makeChecklist(FAMILY, 'familyList', true); makeChecklist(PARTY, 'partyList'); makeChecklist(RECEPTION, 'receptionList'); function getVal(id){ return (document.getElementById(id)||{}).value||''; } function getChecklist(items, containerId, withNames=false) { const result = {}; items.forEach((item,i) => { const cb = document.getElementById(containerId+'_'+i); if (cb && cb.checked) { if (withNames) { const ni = document.getElementById(containerId+'_'+i+'_names'); result[item] = { checked: true, names: ni ? ni.value : '' }; } else { result[item] = true; } } }); return result; } async function submitForm() { const btn = document.getElementById('submitBtn'); const errEl = document.getElementById('submitError'); btn.disabled = true; btn.textContent = 'Submitting...'; errEl.style.display = 'none'; const data = { submittedAt: Date.now(), weddingDate: getVal('weddingDate'), coverage: getVal('coverage'), venue: getVal('venue'), venueAddress: getVal('venueAddress'), colors: getVal('colors'), pinterest: getVal('pinterest'), brideName: getVal('brideName'), bridePhone: getVal('bridePhone'), groomName: getVal('groomName'), groomPhone: getVal('groomPhone'), homeAddress: getVal('homeAddress'), planner: getVal('planner'), moh: getVal('moh'), bridesmaids: getVal('bridesmaids'), bestman: getVal('bestman'), groomsmen: getVal('groomsmen'), timeCeremony: getVal('timeCeremony'), timeCocktail: getVal('timeCocktail'), timeDinner: getVal('timeDinner'), timeReception: getVal('timeReception'), additionalDetails: getVal('additionalDetails'), notesBefore: getVal('notesBefore'), notesCeremony: getVal('notesCeremony'), notesFamily: getVal('notesFamily'), notesReception: getVal('notesReception'), shotList: { before: getChecklist(BEFORE,'beforeList'), ceremony: getChecklist(CEREMONY,'ceremonyList'), party: getChecklist(PARTY,'partyList'), reception: getChecklist(RECEPTION,'receptionList'), }, familyPhotos: getChecklist(FAMILY,'familyList',true), }; if (!data.brideName && !data.groomName) { errEl.textContent = 'Please enter at least the bride and groom names before submitting.'; errEl.style.display = 'block'; btn.disabled = false; btn.textContent = 'Submit questionnaire'; return; } try { const key = 'submission:' + Date.now(); await window.storage.set(key, JSON.stringify(data)); document.getElementById('formWrap').classList.add('hide'); document.getElementById('successMsg').classList.add('show'); } catch(e) { errEl.textContent = 'Submission failed — please try again or contact Luci directly.'; errEl.style.display = 'block'; btn.disabled = false; btn.textContent = 'Submit questionnaire'; } }