// sections.jsx — Offerings, Services, Journey, Team, Testimonials, Location, Footer function Offerings({ lang }) { const t = COPY[lang].offerings; return ( {t.eyebrow} {t.title} {t.subtitle} {t.areas.map((a, i) => ( {a.n} {a.head} {a.lead} {a.items.map((it, j) => {it})} ))} ); } function Services({ lang }) { const t = COPY[lang].services; const [open, setOpen] = React.useState(null); return ( {t.eyebrow} {t.title} {t.subtitle} {t.rows.map((r, i) => ( setOpen(open === i ? null : i)}> {r.n} {r.name} {r.desc} {r.img && ( )} {r.meta.map(([dt, dd], j) => ( {dt} {Array.isArray(dd) ? ( {dd.map((item, k) => {item})} ) : ( {dd} )} ))} e.stopPropagation()}> {t.readMore} → ))} ); } function Journey({ lang }) { const t = COPY[lang].journey; const ref = React.useRef(null); const [active, setActive] = React.useState(0); React.useEffect(() => { const onScroll = () => { if (!ref.current) return; const r = ref.current.getBoundingClientRect(); const vh = window.innerHeight; // active = progress through the journey section const total = r.height - vh * 0.3; const p = Math.max(0, Math.min(1, (vh * 0.5 - r.top) / total)); setActive(Math.min(4, Math.floor(p * 5))); }; window.addEventListener("scroll", onScroll, { passive: true }); onScroll(); return () => window.removeEventListener("scroll", onScroll); }, []); return ( {t.eyebrow} {t.title} {t.steps.map((s, i) => ( {s.n} {s.t} {s.d} ))} ); } function About({ lang }) { const t = COPY[lang].about; return ( {t.eyebrow} Yehia Hassan {lang === "de" ? "Dipl. Physiotherapeut" : "Physiotherapist"} · Winterthur {t.title} {t.subtitle} {t.intro} {t.p2} {t.p3} {t.langsLabel} {t.langs.map((l, i) => {l})} {t.cvLabel} {t.cv.map((row, i) => ( {row.y} {row.t} {row.p} ))} ); } Object.assign(window, { About }); function Testimonials({ lang }) { const t = COPY[lang].testim; return ( {t.eyebrow} {t.title} {t.items.map((item, i) => ( {item.q} {item.who}{item.ctx} {[0,1,2,3,4].map((s) => )} ))} ); } function Location({ lang }) { const t = COPY[lang].location; const ct = COPY[lang].contact || {}; const _day = (new Date().getDay() + 6) % 7; // Mon=0…Sun=6 // condensed rows: 0=Mo–Do, 1=Fr, 2=Sa/So const todayIdx = _day <= 3 ? 0 : _day === 4 ? 1 : 2; const [form, setForm] = React.useState({ firstname: "", lastname: "", email: "", message: "" }); const [sent, setSent] = React.useState(false); const [sending, setSending] = React.useState(false); const [imgModal, setImgModal] = React.useState(null); const handleSubmit = (e) => { e.preventDefault(); setSending(true); fetch("https://formspree.io/f/xkolgdwa", { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ firstname: form.firstname, lastname: form.lastname, email: form.email, message: form.message, }), }) .then(r => r.json()) .then(data => { setSending(false); if (data.ok) { setSent(true); setForm({ firstname: "", lastname: "", email: "", message: "" }); } else { alert("Fehler beim Senden. Bitte versuchen Sie es erneut."); } }) .catch(() => { setSending(false); alert("Fehler beim Senden. Bitte versuchen Sie es erneut."); }); }; return ( {t.eyebrow} {t.title} {t.subtitle} {/* Map + Info grid */} {t.addressLabel} {t.addressLines.map((l, i) => ( {l} ))} {t.contactLabel} {t.contact.map((c, i) => ( {c} ))} {t.hoursLabel} {t.hours.map(([d, h], i) => ( {d} {h} ))} {/* Photos + Access instructions */} {t.accessLabel} {t.transitInfo} {(t.accessSteps || []).map((s, i) => ( {s.icon} {s.text} {s.img && ( setImgModal(s.img)} aria-label="Vergrössern"> )} ))} {/* Contact form */} {ct.eyebrow} {ct.title} {ct.subtitle} {sent ? ( ✓ {ct.success} {ct.successSub} ) : ( {ct.firstname} setForm({ ...form, firstname: e.target.value })} /> {ct.lastname} setForm({ ...form, lastname: e.target.value })} /> {ct.email} setForm({ ...form, email: e.target.value })} /> {ct.message} setForm({ ...form, message: e.target.value })} /> {sending ? "…" : ct.send} )} {imgModal && ( setImgModal(null)}> e.stopPropagation()} /> )} ); } function Footer({ lang }) { const t = COPY[lang].foot; return ( ); } Object.assign(window, { Offerings, Services, Journey, Testimonials, Location, Footer });
{t.subtitle}
{a.lead}
{s.d}
{t.intro}
{t.p2}
{t.p3}
{t.transitInfo}
{ct.subtitle}
{ct.successSub}