1import{r as p,n as e,P as S,E as P,_ as O,q as A}from"./index-DK4OAi_c.js";import{R as I}from"./RelatedContent-BBF0IE62.js";import{S as L}from"./StickyPrintGuide-Csm76Q0a.js";import{L as T}from"./lock-keyhole-B4zBeik9.js";import{T as R}from"./trash-2-ClY16q4E.js";import{P as E}from"./plus-B-PbMA1j.js";import{P as D}from"./printer-DsQon_Z2.js";import{D as F}from"./download-X9UbxJf_.js";import"./PlanningResources-CU8oHj75.js";import"./wrench-Bh4ym59U.js";import"./camera-lYjiyA-g.js";import"./book-open-DSGMQivd.js";const $=i=>({id:i,name:"",household:"",entryType:"individual",invitationSent:!1,rsvp:"awaiting",plusOneInvited:!1,plusOneName:"",plusOneAttending:!1,dietary:"",accessibility:"",meal:"",table:"",thankYouSent:!1,notes:""});function G(i){return i.reduce((n,s)=>(n.entries+=1,n.invited+=1+(s.plusOneInvited?1:0),s.rsvp==="attending"?n.attending+=1+(s.plusOneInvited&&s.plusOneAttending?1:0):s.rsvp==="declined"?n.declined+=1+(s.plusOneInvited?1:0):n.awaiting+=1+(s.plusOneInvited?1:0),s.dietary.trim()&&(n.dietary+=1),s.accessibility.trim()&&(n.accessibility+=1),n),{entries:0,invited:0,attending:0,declined:0,awaiting:0,dietary:0,accessibility:0})}const U=i=>{let n=String(i??"").replace(/\r?\n/g," ");return/^[=+\-@]/.test(n)&&(n=`'${n}`),`"${n.replace(/"/g,'""')}"`};function Y(i){const n=["Name","Household","Entry type","Invitation sent","RSVP","Plus-one invited","Plus-one name","Plus-one attending","Dietary requirements","Accessibility needs","Meal choice","Table","Thank-you sent","Notes"],s=i.map(l=>[l.name,l.household,l.entryType,l.invitationSent?"Yes":"No",l.rsvp,l.plusOneInvited?"Yes":"No",l.plusOneName,l.plusOneAttending?"Yes":"No",l.dietary,l.accessibility,l.meal,l.table,l.thankYouSent?"Yes":"No",l.notes]);return[n,...s].map(l=>l.map(U).join(",")).join(`\r 2`)}function V(i){if(!i)return[];try{const n=JSON.parse(i);return Array.isArray(n)?n.filter(s=>s&&typeof s.id=="string"&&typeof s.name=="string"&&["awaiting","attending","declined"].includes(s.rsvp)):[]}catch{return[]}}const b="bdp-wedding-guest-list-v1",c="w-full border border-neutral-300 bg-white px-3 py-2 text-sm text-neutral-900 focus:border-[var(--bdp-pink)] focus:outline-none",o="block text-[9px] font-bold uppercase tracking-[0.16em] text-neutral-500 mb-1";function M(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`}function te(){const[i,n]=p.useState(()=>{if(typeof window>"u")return[];try{return V(window.localStorage.getItem(b))}catch{return[]}}),[s,l]=p.useState("all"),[h,f]=p.useState(""),[j,u]=p.useState(!1),g=i.length>0,N="Add at least one guest before printing.",y=()=>window.print();p.useEffect(()=>{try{window.localStorage.setItem(b,JSON.stringify(i))}catch{}},[i]);const m=p.useMemo(()=>G(i),[i]),v=p.useMemo(()=>i.filter(t=>{const d=!h.trim()||`${t.name} ${t.household} ${t.table}`.toLowerCase().includes(h.trim().toLowerCase()),a=s==="all"||["awaiting","attending","declined"].includes(s)&&t.rsvp===s||s==="dietary"&&!!t.dietary.trim()||s==="accessibility"&&!!t.accessibility.trim();return d&&a}),[s,i,h]),r=(t,d)=>n(a=>a.map(x=>x.id===t?{...x,...d}:x)),w=()=>{const t=$(M());n(d=>[...d,t])},k=()=>{const t=new Blob(["\uFEFF",Y(i)],{type:"text/csv;charset=utf-8"}),d=URL.createObjectURL(t),a=document.createElement("a");a.href=d,a.download="wedding-guest-list.csv",a.click(),URL.revokeObjectURL(d)},C={"@context":"https://schema.org","@type":"WebApplication",name:"Wedding Guest List & RSVP Tracker",applicationCategory:"LifestyleApplication",operatingSystem:"Any",offers:{"@type":"Offer",price:"0",priceCurrency:"GBP"},description:"A free, browser-only wedding guest list and RSVP tracker."};return e.jsxs("div",{className:"min-h-screen bg-stone-50 text-neutral-950",children:[e.jsx(S,{title:"Free Wedding Guest List & RSVP Tracker UK | Big Day Productions",description:"Track wedding invitations, RSVPs, plus-ones, meals, dietary and accessibility needs, tables and thank-yous. Free and private on your device.",jsonLd:C}),e.jsx(P,{}),e.jsx(L,{onPrint:y,detail:"Print your current guest list or keep a PDF copy.",disabled:!g,disabledDetail:N,testId:"button-sticky-print-guest-list"}),e.jsxs("main",{children:[e.jsx("section",{className:"bg-neutral-950 text-white pt-32 pb-14 sm:pt-36 sm:pb-20 print:hidden",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-4 sm:px-6",children:[e.jsx("p",{className:"text-[10px] font-bold uppercase tracking-[0.25em] mb-5 text-[var(--bdp-pink)]",children:"Free private planning tool"}),e.jsxs("h1",{className:"text-4xl sm:text-6xl leading-[0.98] max-w-4xl mb-6",style:{fontFamily:"var(--font-display)"},children:["Wedding guest list & ",e.jsx("span",{className:"italic text-[var(--bdp-pink)]",children:"RSVP tracker."})]}),e.jsx("p",{className:"text-base sm:text-lg text-white/70 max-w-2xl leading-relaxed",children:"Keep invitations, replies, meals, requirements, tables and thank-yous together. No account, no upload, no guest data shared with us."})]})}),e.jsxs("section",{className:"max-w-6xl mx-auto px-4 sm:px-6 py-8 sm:py-12",children:[e.jsxs("div",{className:"bg-pink-50 border-l-4 border-[var(--bdp-pink)] p-4 sm:p-5 flex gap-3 mb-8 print:hidden","data-testid":"guest-privacy-notice",children:[e.jsx(T,{className:"w-5 h-5 text-[var(--bdp-pink)] shrink-0 mt-0.5"}),e.jsxs("div",{children:[e.jsx("h2",{className:"font-semibold mb-1",children:"Your guest details stay in this browser"}),e.jsx("p",{className:"text-sm text-neutral-700 leading-relaxed",children:"Entries are saved only in local storage on this device. They are not sent to BDP, used for marketing or included in analytics. Anyone using this browser profile may be able to see them, so exp
2ort and clear the list before using a shared device."})]})]}),e.jsxs("div",{className:"hidden print:block mb-6",children:[e.jsx("h1",{className:"text-3xl font-serif",children:"Wedding guest list"}),e.jsx("p",{className:"text-sm",children:"Printed from your private browser copy."})]}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-2 mb-8","data-testid":"guest-summary",children:[["Invited",m.invited],["Attending",m.attending],["Declined",m.declined],["Awaiting",m.awaiting],["Dietary",m.dietary],["Access needs",m.accessibility]].map(([t,d])=>e.jsxs("div",{className:"bg-white border border-neutral-200 p-4",children:[e.jsx("p",{className:"text-2xl text-[var(--bdp-pink)]",style:{fontFamily:"var(--font-display)"},children:d}),e.jsx("p",{className:"text-[9px] font-bold uppercase tracking-[0.16em] text-neutral-500",children:t})]},t))}),e.jsxs("div",{className:"flex flex-col lg:flex-row gap-3 justify-between mb-6 print:hidden",children:[e.jsx("div",{className:"flex flex-wrap gap-2",children:["all","attending","declined","awaiting","dietary","accessibility"].map(t=>e.jsx("button",{onClick:()=>l(t),className:`px-3 py-2 text-[10px] font-bold uppercase tracking-wider border ${s===t?"bg-neutral-950 text-white border-neutral-950":"bg-white border-neutral-300"}`,children:t},t))}),e.jsx("input",{"aria-label":"Search guests",value:h,onChange:t=>f(t.target.value),placeholder:"Search name, household or table",className:`${c} lg:max-w-xs`})]}),e.jsxs("div",{className:"space-y-3","aria-live":"polite",children:[v.map((t,d)=>e.jsxs("article",{className:"bg-white border border-neutral-200 p-4 sm:p-5 break-inside-avoid","data-testid":`guest-row-${d}`,children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3",children:[e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Guest name *"}),e.jsx("input",{value:t.name,maxLength:100,onChange:a=>r(t.id,{name:a.target.value}),className:`${c} ${t.name.trim()?"":"border-amber-400"}`,placeholder:"e.g. Alex Morgan"})]}),e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Household / group"}),e.jsx("input",{value:t.household,maxLength:100,onChange:a=>r(t.id,{household:a.target.value}),className:c,placeholder:"e.g. Morgan family"})]}),e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Entry"}),e.jsxs("select",{value:t.entryType,onChange:a=>r(t.id,{entryType:a.target.value}),className:c,children:[e.jsx("option",{value:"individual",children:"Individual"}),e.jsx("option",{value:"household",children:"Household contact"})]})]}),e.jsxs("label",{children:[e.jsx("span",{className:o,children:"RSVP"}),e.jsxs("select",{value:t.rsvp,onChange:a=>r(t.id,{rsvp:a.target.value}),className:c,children:[e.jsx("option",{value:"awaiting",children:"Awaiting reply"}),e.jsx("option",{value:"attending",children:"Attending"}),e.jsx("option",{value:"declined",children:"Declined"})]})]}),e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Plus-one"}),e.jsxs("select",{value:t.plusOneInvited?"yes":"no",onChange:a=>r(t.id,{plusOneInvited:a.target.value==="yes",plusOneAttending:a.target.value==="yes"?t.plusOneAttending:!1}),className:c,children:[e.jsx("option",{value:"no",children:"Not invited"}),e.jsx("option",{value:"yes",children:"Invited"})]})]}),t.plusOneInvited&&e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Plus-one name"}),e.jsx("input",{value:t.plusOneName,maxLength:100,onChange:a=>r(t.id,{plusOneName:a.target.value}),className:c,placeholder:"Name if known"})]}),t.plusOneInvited&&t.rsvp==="attending"&&e.jsxs("label",{className:"flex items-end gap-2 pb-2",children:[e.jsx("input",{type:"checkbox",checked:t.plusOneAttending,onChange:a=>r(t.id,{plusOneAttending:a.target.checked})})," ",e.jsx("span",{className:"text-sm",children:"Plus-one attending"})]}),e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Meal choice"}),e.jsx("input",{value:t.meal,maxLength:100,onChange:a=>r(t.id,{meal:a.target.value}),className:c,placeholder:"e.g. Vegetarian"})]}),e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Table"}),e.jsx("input",{value:t.table,maxLength:50,onChange:a=>r(t.id,{table:a.target.value}),className:c,placeholder:"e.g. Table 4"})]}),e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Dietary / allergies"}),e.jsx("input",{value:t.dietary,maxLength:250,onChange:a=>r(t.id,{dietary:a.target.value}),className:c,placeholder:"Confirm severe allergies with venue"})]}),e.jsxs("label",{children:[e.jsx("span",{className:o,children:"Accessibility needs"}),e.jsx("input",{value:t.accessibility,maxLength:250,onChange:a=>r(t.id,{accessibility:a.target.value}),className:c,placeholder:"e.g. Step-free route"})]}),e.jsxs("label",{className:"lg:col-span-2",children:[e.jsx("span",{className:o,children:"Notes"}),e.jsx("input",{value:t.notes,maxLength:500,onChange:a=>r(t.id,{notes:a.target.value}),className:c})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-5 mt-4 pt-3 border-t border-neutral-100",children:[e.jsxs("label",{className:"text-sm flex gap-2",children:[e.jsx("input",{type:"checkbox",checked:t.invitationSe
2nt,onChange:a=>r(t.id,{invitationSent:a.target.checked})})," Invitation sent"]}),e.jsxs("label",{className:"text-sm flex gap-2",children:[e.jsx("input",{type:"checkbox",checked:t.thankYouSent,onChange:a=>r(t.id,{thankYouSent:a.target.checked})})," Thank-you sent"]}),e.jsxs("button",{"aria-label":`Remove ${t.name||"guest"}`,onClick:()=>n(a=>a.filter(x=>x.id!==t.id)),className:"ml-auto text-red-700 text-xs inline-flex items-center gap-1 print:hidden",children:[e.jsx(R,{className:"w-3.5 h-3.5"})," Remove"]})]})]},t.id)),!v.length&&e.jsxs("div",{className:"text-center py-14 bg-white border border-dashed border-neutral-300",children:[e.jsx(O,{className:"w-8 h-8 mx-auto mb-3 text-neutral-400"}),e.jsx("p",{className:"text-neutral-600",children:i.length?"No guests match this filter.":"Add your first guest or household to begin."})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3 mt-6 print:hidden",children:[e.jsxs("button",{onClick:w,className:"px-5 py-3 bg-[var(--bdp-pink)] text-white text-xs font-bold uppercase tracking-wider inline-flex gap-2 items-center",children:[e.jsx(E,{className:"w-4 h-4"})," Add guest"]}),e.jsxs("button",{onClick:y,disabled:!g,className:"px-5 py-3 border border-neutral-950 text-xs font-bold uppercase tracking-wider inline-flex gap-2 items-center disabled:opacity-40",children:[e.jsx(D,{className:"w-4 h-4"})," Print"]}),e.jsxs("button",{onClick:k,disabled:!i.length,className:"px-5 py-3 border border-neutral-950 text-xs font-bold uppercase tracking-wider inline-flex gap-2 items-center disabled:opacity-40",children:[e.jsx(F,{className:"w-4 h-4"})," Export CSV"]}),e.jsx("button",{onClick:()=>u(!0),disabled:!i.length,className:"px-5 py-3 text-red-700 text-xs font-bold uppercase tracking-wider disabled:opacity-40",children:"Clear all data"})]}),e.jsx("p",{className:"mt-6 text-xs leading-relaxed text-neutral-500 print:hidden",children:"This tracker helps you organise information; always confirm allergies and accessibility arrangements directly with guests and your venue. Exported CSV files contain personal data, so store them securely."})]}),e.jsx(I,{pageType:"seo",slug:"wedding-rsvp-tracker"})]}),e.jsx(A,{}),j&&e.jsx("div",{className:"fixed inset-0 bg-black/60 z-[100] flex items-center justify-center p-4 print:hidden",role:"dialog","aria-modal":"true","aria-labelledby":"clear-title",children:e.jsxs("div",{className:"bg-white max-w-md w-full p-6",children:[e.jsx("h2",{id:"clear-title",className:"text-2xl mb-3",style:{fontFamily:"var(--font-display)"},children:"Clear every guest?"}),e.jsx("p",{className:"text-sm text-neutral-600 mb-6",children:"This permanently removes this list from this browser. Export a copy first if you need one."}),e.jsxs("div",{className:"flex gap-3 justify-end",children:[e.jsx("button",{onClick:()=>u(!1),className:"px-4 py-2 border border-neutral-300 text-sm",children:"Keep my list"}),e.jsx("button",{onClick:()=>{n([]);try{localStorage.removeItem(b)}catch{}u(!1)},className:"px-4 py-2 bg-red-700 text-white text-sm font-semibold",children:"Yes, clear it"})]})]})})]})}export{te as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.