/* Bahá'ís of Dublin — page content. */

const Artwork = ({ ratio = "wide", tone = "rose", caption = "" }) => {
  const ratioCls = `bd-art--${ratio}`;
  const toneCls = `bd-art--${tone}`;
  return (
    <div className={`bd-art ${ratioCls} ${toneCls}`} role="img" aria-label={caption}>
      <div className="bd-art__inner">
        <div className="bd-art__mark">
          <NineStar size={56} stroke="currentColor" strokeWidth={0.7} />
        </div>
        <div className="bd-art__caption">
          {caption.split("\n").map((line, i) => <span key={i}>{line}</span>)}
        </div>
      </div>
    </div>
  );
};

const Home = ({ onNavigate, mobile }) => (
  <main className="bd-main">
    <section className="bd-hero-photo" aria-label="Welcome">
      <div className="bd-hero-photo__stack">
        <div className="bd-hero-photo__offset" aria-hidden="true"></div>
        <div className="bd-hero-photo__slot" role="img" aria-label="A photograph of a Dublin community gathering will live here">
        <div className="bd-hero-photo__mark">
          <NineStar size={mobile ? 56 : 72} stroke="currentColor" strokeWidth={0.7} />
        </div>
        <div className="bd-hero-photo__hint">
          <span className="bd-hero-photo__kind">Photograph or artwork</span>
          <span className="bd-hero-photo__cap">A Dublin community gathering — a study circle, a devotional, or a piece by the children's class — will live here.</span>
        </div>
      </div>
      </div>
      <div className="bd-hero-photo__copy">
        <p className="bd-eyebrow">A community in Dublin, California</p>
        <h1 className="bd-h1">Welcome.</h1>
        <p className="bd-lede">
          We are a small community of Bahá'ís living in Dublin, California. We
          gather to pray, to study, to serve our neighborhood, and to learn
          together how to build a more loving and unified society — one
          conversation, one friendship, one shared meal at a time.
        </p>
        <p className="bd-lede bd-lede--quiet">
          If you are curious about the Bahá'í Faith, or simply looking for a
          community where prayer and conversation feel at home, you are welcome
          here.
        </p>
      </div>
    </section>

    <blockquote className="bd-quote bd-quote--hero">
      <p>
        To be a Bahá'í simply means to love all the world; to love humanity and
        try to serve it; to work for universal peace and universal brotherhood.
      </p>
      <cite>— 'Abdu'l-Bahá</cite>
    </blockquote>

    <hr className="bd-rule" />

    <section className="bd-three">
      <article className="bd-three__col">
        <h3 className="bd-h3">What we do</h3>
        <p>
          We host devotional gatherings open to people of every faith and none. We
          study the writings of Bahá'u'lláh and explore how to apply them to daily
          life. We support classes for children and groups for junior youth that
          nurture both spiritual and intellectual growth. And we work alongside our
          neighbors on whatever in our community needs caring for.
        </p>
        <a href="#community" className="bd-link" onClick={(e) => { e.preventDefault(); onNavigate?.("community"); }}>
          Learn about community life →
        </a>
      </article>

      <article className="bd-three__col">
        <h3 className="bd-h3">What's coming up</h3>
        <ul className="bd-mini-events">
          <li>
            <span className="bd-mini-events__day">Sun</span>
            <span className="bd-mini-events__t">Devotional gathering · 10:30 am</span>
          </li>
          <li>
            <span className="bd-mini-events__day">Wed</span>
            <span className="bd-mini-events__t">Study circle · 7:30 pm</span>
          </li>
          <li>
            <span className="bd-mini-events__day">Fri</span>
            <span className="bd-mini-events__t">Feast of 'Ilm · 7:00 pm</span>
          </li>
        </ul>
        <a href="#events" className="bd-link" onClick={(e) => { e.preventDefault(); onNavigate?.("events"); }}>
          See all events →
        </a>
      </article>

      <article className="bd-three__col">
        <h3 className="bd-h3">Get in touch</h3>
        <p>
          If you'd like to come to a gathering, ask a question, or simply say hello,
          we'd love to hear from you. There's no pressure and no obligation.
        </p>
        <a href="#contact" className="bd-link" onClick={(e) => { e.preventDefault(); onNavigate?.("contact"); }}>
          Contact us →
        </a>
      </article>
    </section>

    <section className="bd-home-film">
      <div className="bd-home-film__copy">
        <p className="bd-eyebrow">A film worth watching</p>
        <h2 className="bd-h2">A glimpse of community life</h2>
        <p className="bd-home-film__lede">
          One segment of a four-part documentary film captures community-building
          in neighbourhoods like ours — children's classes, junior youth groups,
          devotional gatherings, and the patient work of friendship across
          difference.
        </p>
      </div>
      <figure className="bd-home-film__media">
        <div className="bd-video__frame">
          <iframe
            src="https://www.youtube-nocookie.com/embed/ENS5ePGQ7Bs"
            title="Frontiers of Learning"
            frameBorder="0"
            allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
            allowFullScreen
          ></iframe>
        </div>
        <figcaption className="bd-home-film__cap">
          <span>From the documentary <em>Frontiers of Learning</em></span>
          <a href="#community" className="bd-link bd-link--small" onClick={(e) => { e.preventDefault(); onNavigate?.("community"); }}>
            More films on Community Life →
          </a>
        </figcaption>
      </figure>
    </section>

    <section className="bd-invite-band">
      <div className="bd-invite-band__star">
        <NineStar size={300} stroke="currentColor" strokeWidth={0.6} />
      </div>
      <div className="bd-invite-band__inner">
        <span className="bd-invite-band__eyebrow">An open invitation</span>
        <p>
          Come once, come often, or simply read along. There is no cost, no list,
          and no expectation that you become a Bahá'í — only that you come with an
          open heart.
        </p>
        <a href="#events" onClick={(e) => { e.preventDefault(); onNavigate?.("events"); }}>
          See what's coming up →
        </a>
      </div>
    </section>
  </main>
);

const Community = ({ mobile }) => (
  <main className="bd-main">
    <header className="bd-page-head">
      <p className="bd-eyebrow">Community Life</p>
      <h1 className="bd-h1 bd-h1--page">Our life together</h1>
      <OrnamentRule width={180} />
      <Artwork ratio="wide" tone="rose" caption={"junior youth artwork — drop in later"} />
    </header>

    <section className="bd-prose">
      <p>
        The Bahá'í community in Dublin is small and growing. Most weeks include a
        devotional gathering — a quiet hour of prayers, readings, and music drawn
        from many spiritual traditions, hosted in someone's home and open to anyone
        who'd like to come. Once every nineteen days we hold what Bahá'ís call a
        Feast: a time of prayer, consultation about community affairs, and fellowship.
      </p>
      <p>
        Children's classes meet to nurture moral and spiritual capacities through
        stories, songs, and conversation. Junior youth groups support young people
        aged eleven to fifteen as they develop the qualities and skills they'll
        carry into adulthood. Both are open to children and youth from any
        background, and many of the families who participate are not Bahá'ís themselves.
      </p>
      <p>
        We also gather to study — sometimes in small groups working through a
        sequence of courses called the Ruhi Institute, sometimes more informally
        around a particular passage or letter that we want to understand together.
        The point of the study is always practice: what does this mean for how we
        live, how we serve, how we treat one another?
      </p>
      <p>
        And we participate in the life of the wider city. Dublin is our home. The
        work of building a better society isn't something Bahá'ís do alone or for
        ourselves — it's something we hope to do alongside everyone who shares the
        longing for a more just and unified world.
      </p>

      <p>
        A few short films we keep returning to. Each one is the work of friends in
        the wider Bahá'í community, and each one says something we've found hard
        to say in our own words.
      </p>

      <figure className="bd-video">
        <div className="bd-video__frame">
          <iframe src="https://www.youtube-nocookie.com/embed/eVxgAuzFfvU" title="Light to the World" frameBorder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>
        </div>
        <figcaption>
          <span className="bd-video__kicker">A short film</span>
          <span className="bd-video__cap">A glimpse of Bahá'u'lláh's life and what his teachings have meant to those who follow them.</span>
        </figcaption>
      </figure>

      <p>
        We watch films like these together sometimes — over tea after a devotional,
        or as the start of a longer conversation. You're welcome to come watch
        with us, or just to follow the links from your own kitchen table.
      </p>

      <figure className="bd-video">
        <div className="bd-video__frame">
          <iframe src="https://www.youtube-nocookie.com/embed/g8tIovq74Lw" title="Frontiers of Learning" frameBorder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>
        </div>
        <figcaption>
          <span className="bd-video__kicker">From around the world</span>
          <span className="bd-video__cap">Communities in different parts of the world share what they're learning about service, study, and building unity in their neighbourhoods.</span>
        </figcaption>
      </figure>

      <p>
        And one closer to the everyday — what it actually looks like when a junior
        youth group meets, when children sing together, when neighbours pray.
      </p>

      <figure className="bd-video">
        <div className="bd-video__frame">
          <iframe src="https://www.youtube-nocookie.com/embed/d6E3F4iLDXk" title="Glimpses of community life" frameBorder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>
        </div>
        <figcaption>
          <span className="bd-video__kicker">Glimpses</span>
          <span className="bd-video__cap">Small, ordinary moments from Bahá'í community life — children's classes, devotionals, study circles, shared meals.</span>
        </figcaption>
      </figure>
    </section>

    <hr className="bd-rule" />

    <section className="bd-beliefs">
      <h2 className="bd-h2">A few things we believe</h2>
      <ul className="bd-beliefs__list">
        <li>
          <span className="bd-beliefs__num">i</span>
          <p>That humanity is one family, and that the time has come for us to live as if this were true.</p>
        </li>
        <li>
          <span className="bd-beliefs__num">ii</span>
          <p>That the great religions of the world come from a single Source, and each has prepared humanity for the next stage of its spiritual life.</p>
        </li>
        <li>
          <span className="bd-beliefs__num">iii</span>
          <p>That Bahá'u'lláh, who lived in the nineteenth century and suffered exile and imprisonment for forty years, is the latest in this line of divine Educators, and that his teachings carry the spiritual and social principles needed for the age we are entering.</p>
        </li>
        <li>
          <span className="bd-beliefs__num">iv</span>
          <p>That work done in a spirit of service is a form of worship.</p>
        </li>
        <li>
          <span className="bd-beliefs__num">v</span>
          <p>That prayer matters. That study matters. That the way we treat one another, day by day, matters most of all.</p>
        </li>
      </ul>
      <p className="bd-beliefs__more">
        For a fuller introduction, visit <a href="https://www.bahai.org" target="_blank" rel="noreferrer">bahai.org</a>.
      </p>
    </section>
  </main>
);

// Events live at Dublin/California times, so format timed events in Pacific
// regardless of the visitor's locale. Lowercase am/pm to match the rest of
// the design. All-day events come from ical.js as midnight UTC; format them
// in UTC so they don't shift back a day when read in Pacific.
const TZ = "America/Los_Angeles";
const fmtWeekday = new Intl.DateTimeFormat("en-US", { weekday: "long", timeZone: TZ });
const fmtDate = new Intl.DateTimeFormat("en-US", { month: "long", day: "numeric", timeZone: TZ });
const fmtTime = new Intl.DateTimeFormat("en-US", { hour: "numeric", minute: "2-digit", timeZone: TZ });
const fmtWeekdayUTC = new Intl.DateTimeFormat("en-US", { weekday: "long", timeZone: "UTC" });
const fmtDateUTC = new Intl.DateTimeFormat("en-US", { month: "long", day: "numeric", timeZone: "UTC" });
const lowerMeridiem = (s) => s.replace(/\s?AM\b/, " am").replace(/\s?PM\b/, " pm").trim();

const deriveType = (title) => {
  const t = (title || "").toLowerCase();
  if (t.includes("feast")) return "Feast";
  if (t.includes("devotional")) return "Devotional";
  if (t.includes("study")) return "Study";
  if (t.includes("fireside")) return "Fireside";
  if (t.includes("junior youth")) return "Junior Youth";
  if (t.includes("children")) return "Children";
  return "Gathering";
};

const formatEvent = (ev) => {
  const start = new Date(ev.start);
  const end = new Date(ev.end);
  const allDay = !!ev.allDay;
  return {
    key: `${ev.uid || ev.title}-${ev.start}`,
    weekday: allDay ? fmtWeekdayUTC.format(start) : fmtWeekday.format(start),
    date: allDay ? fmtDateUTC.format(start) : fmtDate.format(start),
    time: allDay ? "All day" : `${lowerMeridiem(fmtTime.format(start))} — ${lowerMeridiem(fmtTime.format(end))}`,
    title: ev.title,
    place: ev.location || "Address shared on request — please be in touch.",
    welcome: ev.welcome || "",
    type: deriveType(ev.title),
  };
};

const Events = ({ mobile, onNavigate }) => {
  const [state, setState] = React.useState({ status: "loading", events: [] });

  React.useEffect(() => {
    let cancelled = false;
    fetch("/api/events", { headers: { Accept: "application/json" } })
      .then((r) => (r.ok ? r.json() : []))
      .then((data) => {
        if (cancelled) return;
        const events = Array.isArray(data) ? data.map(formatEvent) : [];
        setState({ status: "ready", events });
      })
      .catch(() => {
        if (!cancelled) setState({ status: "ready", events: [] });
      });
    return () => { cancelled = true; };
  }, []);

  return (
    <main className="bd-main">
      <header className="bd-page-head">
        <p className="bd-eyebrow">Events</p>
        <h1 className="bd-h1 bd-h1--page">You are warmly invited</h1>
        <OrnamentRule width={180} />
        <p className="bd-lede bd-lede--center">
          Most of our gatherings take place in homes around Dublin. We ask that you
          reach out before coming so we know to expect you and can share the address.
          There is never any cost, and there is no expectation that you become a
          Bahá'í — only that you come with an open heart.
        </p>
      </header>

      {state.status === "loading" ? (
        <p className="bd-events__note" aria-live="polite">Checking the calendar…</p>
      ) : state.events.length === 0 ? (
        <p className="bd-events__note">
          Nothing on the calendar in the next couple of months — please{" "}
          <a
            href="#contact"
            className="bd-link bd-link--inline"
            onClick={(e) => { e.preventDefault(); onNavigate?.("contact"); }}
          >be in touch</a>{" "}
          and we'll let you know what's coming up.
        </p>
      ) : (
        <section className="bd-events">
          {state.events.map((ev) => (
            <article key={ev.key} className="bd-event">
              <div className="bd-event__when">
                <div className="bd-event__day">{ev.weekday}</div>
                <div className="bd-event__date">{ev.date}</div>
              </div>
              <div className="bd-event__body">
                <div className="bd-event__type">{ev.type}</div>
                <h3 className="bd-event__title">{ev.title}</h3>
                <div className="bd-event__meta">
                  <span>{ev.time}</span>
                  <span className="bd-event__sep" aria-hidden="true">·</span>
                  <span>{ev.place}</span>
                </div>
                {ev.welcome ? <p className="bd-event__welcome">{ev.welcome}</p> : null}
                <a
                  href="#contact"
                  className="bd-link bd-link--small"
                  onClick={(e) => { e.preventDefault(); onNavigate?.("contact"); }}
                >Let us know you'll come →</a>
              </div>
            </article>
          ))}
        </section>
      )}

      <p className="bd-events__note">
        Children's classes and junior youth groups also meet regularly. To join,
        please{" "}
        <a
          href="#contact"
          className="bd-link bd-link--inline"
          onClick={(e) => { e.preventDefault(); onNavigate?.("contact"); }}
        >be in touch</a>.
      </p>
    </main>
  );
};

const PRAYERS = [
  { group: "Prayers for unity", items: [{ text: "O my God! O my God! Unite the hearts of Thy servants, and reveal to them Thy great purpose. May they follow Thy commandments and abide in Thy law. Help them, O God, in their endeavor, and grant them strength to serve Thee. O God! Leave them not to themselves, but guide their steps by the light of Thy knowledge, and cheer their hearts by Thy love. Verily, Thou art their Helper and their Lord.", author: "'Abdu'l-Bahá" }] },
  { group: "Prayers for healing", items: [{ text: "Thy name is my healing, O my God, and remembrance of Thee is my remedy. Nearness to Thee is my hope, and love for Thee is my companion. Thy mercy to me is my healing and my succour in both this world and the world to come. Thou, verily, art the All-Bountiful, the All-Knowing, the All-Wise.", author: "Bahá'u'lláh" }] },
  { group: "On service", items: [{ text: "O Thou kind Lord! Thou hast created all humanity from the same stock. Thou hast decreed that all shall belong to the same household. In Thy Holy Presence they are all Thy servants, and all mankind are sheltered beneath Thy Tabernacle.", author: "'Abdu'l-Bahá" }] },
];

const QUOTES = [
  { text: "The earth is but one country, and mankind its citizens.", author: "Bahá'u'lláh" },
  { text: "So powerful is the light of unity that it can illuminate the whole earth.", author: "Bahá'u'lláh" },
  { text: "Let your vision be world-embracing, rather than confined to your own self.", author: "Bahá'u'lláh" },
  { text: "The betterment of the world can be accomplished through pure and goodly deeds, through commendable and seemly conduct.", author: "Bahá'u'lláh" },
];

const Prayers = ({ mobile }) => (
  <main className="bd-main">
    <header className="bd-page-head">
      <p className="bd-eyebrow">Prayers & Quotes</p>
      <h1 className="bd-h1 bd-h1--page">A small selection</h1>
      <OrnamentRule width={180} />
      <p className="bd-lede bd-lede--center">
        A few prayers and passages we return to. Refreshed when we feel moved to.
      </p>
    </header>

    <section className="bd-prayers">
      {PRAYERS.map((g, i) => (
        <div key={i} className="bd-prayers__group">
          <h2 className="bd-h2 bd-h2--soft">{g.group}</h2>
          {g.items.map((it, j) => (
            <blockquote key={j} className="bd-prayer">
              <p>{it.text}</p>
              <cite>— {it.author}</cite>
            </blockquote>
          ))}
        </div>
      ))}
    </section>

    <hr className="bd-rule" />

    <section className="bd-quotes">
      <h2 className="bd-h2 bd-h2--soft">A few short passages</h2>
      <div className="bd-quotes__grid">
        {QUOTES.map((q, i) => (
          <figure key={i} className="bd-quotecard">
            <blockquote><p>{q.text}</p></blockquote>
            <figcaption>— {q.author}</figcaption>
          </figure>
        ))}
      </div>
    </section>

    <p className="bd-prayers__more">
      For more, visit the{" "}
      <a href="https://www.bahai.org/library/" target="_blank" rel="noreferrer">
        Bahá'í Reference Library
      </a>.
    </p>
  </main>
);

const TURNSTILE_SCRIPT_SRC = "https://challenges.cloudflare.com/turnstile/v0/api.js";

// Load the Turnstile script once, idempotently. Returns a promise resolving when
// `window.turnstile` is available. Polls rather than relying solely on the load
// event so we don't hang if the script tag was already loaded by an earlier mount
// (the load event won't re-fire on existing nodes).
const loadTurnstileScript = () => {
  if (typeof window === "undefined") return Promise.reject(new Error("no window"));
  if (window.turnstile) return Promise.resolve();
  let promise = window.__turnstileLoading;
  if (promise) return promise;
  promise = new Promise((resolve, reject) => {
    const existing = document.querySelector(`script[src="${TURNSTILE_SCRIPT_SRC}"]`);
    if (!existing) {
      const s = document.createElement("script");
      s.src = TURNSTILE_SCRIPT_SRC;
      s.async = true;
      s.defer = true;
      s.onerror = () => reject(new Error("turnstile script error"));
      document.head.appendChild(s);
    }
    const start = Date.now();
    const tick = () => {
      if (window.turnstile) return resolve();
      if (Date.now() - start > 5000) return reject(new Error("turnstile not ready"));
      setTimeout(tick, 50);
    };
    tick();
  });
  window.__turnstileLoading = promise;
  return promise;
};

const Contact = ({ mobile }) => {
  const [form, setForm] = React.useState({ name: "", email: "", phone: "", message: "", source: "" });
  const [touched, setTouched] = React.useState({});
  const [submitState, setSubmitState] = React.useState({ status: "idle", error: "" });
  const [siteKey, setSiteKey] = React.useState(null); // null = loading, "" = unconfigured
  const [token, setToken] = React.useState("");
  const widgetRef = React.useRef(null);
  const widgetIdRef = React.useRef(null);

  // Pull the public Turnstile site key from /api/config.
  React.useEffect(() => {
    let cancelled = false;
    fetch("/api/config", { headers: { Accept: "application/json" } })
      .then((r) => (r.ok ? r.json() : {}))
      .then((data) => { if (!cancelled) setSiteKey(data.turnstileSiteKey || ""); })
      .catch(() => { if (!cancelled) setSiteKey(""); });
    return () => { cancelled = true; };
  }, []);

  // Render the Turnstile widget once we have a site key + a mount node.
  React.useEffect(() => {
    if (!siteKey || !widgetRef.current) return undefined;
    let cancelled = false;
    loadTurnstileScript()
      .then(() => {
        if (cancelled || !widgetRef.current || !window.turnstile) return;
        widgetIdRef.current = window.turnstile.render(widgetRef.current, {
          sitekey: siteKey,
          callback: (t) => setToken(t),
          "error-callback": () => setToken(""),
          "expired-callback": () => setToken(""),
          "timeout-callback": () => setToken(""),
          theme: "light",
        });
      })
      .catch(() => { /* widget will simply not appear; submit will show a clear error */ });
    return () => {
      cancelled = true;
      if (widgetIdRef.current && window.turnstile) {
        try { window.turnstile.remove(widgetIdRef.current); } catch (_) {}
        widgetIdRef.current = null;
      }
    };
  }, [siteKey]);

  const errs = {
    name: !form.name.trim() ? "Please share your name" : "",
    email: !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(form.email) ? "A valid email, please" : "",
    message: form.message.trim().length < 5 ? "A short message helps us reply well" : "",
  };
  const valid = !errs.name && !errs.email && !errs.message;

  const resetTurnstile = () => {
    setToken("");
    if (widgetIdRef.current && window.turnstile) {
      try { window.turnstile.reset(widgetIdRef.current); } catch (_) {}
    }
  };

  const submit = async (e) => {
    e.preventDefault();
    setTouched({ name: true, email: true, message: true });
    if (!valid) return;
    if (!token) {
      setSubmitState({ status: "error", error: "Please complete the verification check above before sending." });
      return;
    }
    setSubmitState({ status: "sending", error: "" });
    try {
      const r = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json", Accept: "application/json" },
        body: JSON.stringify({ ...form, turnstileToken: token }),
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok || data.ok === false) {
        resetTurnstile();
        setSubmitState({
          status: "error",
          error: data.error || "Something went wrong — please try again, or email us directly.",
        });
        return;
      }
      setSubmitState({ status: "sent", error: "" });
    } catch (_) {
      resetTurnstile();
      setSubmitState({
        status: "error",
        error: "Network problem — please check your connection and try again.",
      });
    }
  };

  const sending = submitState.status === "sending";

  return (
    <main className="bd-main">
      <header className="bd-page-head">
        <p className="bd-eyebrow">Contact</p>
        <h1 className="bd-h1 bd-h1--page">Get in touch</h1>
        <OrnamentRule width={180} />
        <p className="bd-lede bd-lede--center">
          Whether you'd like to come to a gathering, ask a question about the Bahá'í
          Faith, or simply say hello, we'd be glad to hear from you. We read every
          message, and someone from the community will be in touch.
        </p>
      </header>

      {submitState.status === "sent" ? (
        <section className="bd-thanks">
          <NineStar size={42} stroke="var(--bd-gold)" strokeWidth={0.9} />
          <h2 className="bd-h2">Thank you, {form.name.split(" ")[0]}.</h2>
          <p>Your message is with us. Someone from the community will write back soon.</p>
          <button
            className="bd-btn bd-btn--ghost"
            onClick={() => {
              setForm({ name: "", email: "", phone: "", message: "", source: "" });
              setTouched({});
              setSubmitState({ status: "idle", error: "" });
              resetTurnstile();
            }}
          >
            Send another
          </button>
        </section>
      ) : (
        <form className="bd-form" onSubmit={submit} noValidate>
          <Field label="Name" id="name" value={form.name} err={touched.name && errs.name} onChange={(v) => setForm({ ...form, name: v })} onBlur={() => setTouched({ ...touched, name: true })} />
          <Field label="Email" id="email" type="email" value={form.email} err={touched.email && errs.email} onChange={(v) => setForm({ ...form, email: v })} onBlur={() => setTouched({ ...touched, email: true })} />
          <Field label="Phone" hint="Optional" id="phone" type="tel" value={form.phone} err="" onChange={(v) => setForm({ ...form, phone: v })} />
          <Field label="Message" id="message" textarea value={form.message} err={touched.message && errs.message} onChange={(v) => setForm({ ...form, message: v })} onBlur={() => setTouched({ ...touched, message: true })} />
          <Field label="How did you hear about us?" hint="Optional" id="source" value={form.source} err="" onChange={(v) => setForm({ ...form, source: v })} />

          <div className="bd-field">
            <div ref={widgetRef} className="bd-turnstile" />
            {siteKey === "" ? (
              <span className="bd-field__err">
                The verification widget isn't configured yet — please email us directly at{" "}
                <a href="mailto:hello@dublincabahais.org">hello@dublincabahais.org</a>.
              </span>
            ) : null}
          </div>

          {submitState.error ? (
            <p className="bd-form__err" role="alert">{submitState.error}</p>
          ) : null}

          <button
            type="submit"
            className={`bd-btn bd-btn--primary ${(!valid && Object.keys(touched).length) || sending ? "is-disabled" : ""}`}
            disabled={sending}
          >
            {sending ? "Sending…" : "Send message"}
          </button>
        </form>
      )}

      <p className="bd-direct">
        You can also email us directly at{" "}
        <a href="mailto:hello@dublincabahais.org">hello@dublincabahais.org</a>{" "}
        or call <span className="bd-direct__name">Sara</span> at{" "}
        <a href="tel:+19255550133">(925) 555-0133</a>.
      </p>
    </main>
  );
};

const Field = ({ label, id, type = "text", textarea, value, onChange, onBlur, err, hint }) => (
  <label className={`bd-field ${err ? "is-err" : ""}`} htmlFor={id}>
    <span className="bd-field__row">
      <span className="bd-field__label">{label}</span>
      {hint ? <span className="bd-field__hint">{hint}</span> : null}
    </span>
    {textarea ? (
      <textarea id={id} value={value} onChange={(e) => onChange(e.target.value)} onBlur={onBlur} rows={5} />
    ) : (
      <input id={id} type={type} value={value} onChange={(e) => onChange(e.target.value)} onBlur={onBlur} />
    )}
    {err ? <span className="bd-field__err">{err}</span> : null}
  </label>
);

Object.assign(window, { Home, Community, Events, Prayers, Contact, Artwork });
