Plan Your Visit landing page for visit.waterschurch.org

Next.js 16 static export + PHP 8 API for cPanel/Apache hosting.

- Location-aware campus finder (IP estimate, optional precise location, ZIP search)
- Three-step Plan Your Visit form with separate email/SMS consent
- PHP API: validation, anti-spam, rate limiting, SQLite lead store,
  Mailchimp and Sinch Engage adapters, idempotent retries via cron
- Attribution capture (utm_*, gclid/gbraid/wbraid, fbclid, ttclid, twclid) and
  consent-aware analytics hooks
- Vitest and PHP test suites, cPanel deployment script and docs

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Waters Church
2026-09-22 13:22:26 -04:00
co-authored by Claude Fable 5.1
commit 78cd0cc550
109 changed files with 16861 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
import { beforeEach, describe, expect, it } from "vitest";
import { _resetAnalyticsQueue, track } from "@/lib/analytics";
describe("analytics layer", () => {
beforeEach(() => {
window.dataLayer = [];
window.sessionStorage.clear();
window.localStorage.clear();
window.history.replaceState({}, "", "/?utm_source=google&utm_campaign=brand&gclid=G");
_resetAnalyticsQueue();
});
it("pushes named events with attribution and device props, without PII", () => {
track("campus_selected", { campus: "norwood", selection_source: "manual" });
const evt = (window.dataLayer as Record<string, unknown>[]).at(-1)!;
expect(evt.event).toBe("campus_selected");
expect(evt.campus).toBe("norwood");
expect(evt.source).toBe("google");
expect(evt.campaign).toBe("brand");
expect(evt.platform).toBe("google");
expect(evt.variant).toBe("a");
expect(["mobile", "tablet", "desktop"]).toContain(evt.device_category);
expect(JSON.stringify(evt)).not.toMatch(/@|phone/);
});
it("dispatches a DOM event for custom listeners", () => {
const seen: string[] = [];
window.addEventListener("wc:analytics", (e) => seen.push((e as CustomEvent).detail.event));
track("text_us_clicked", { location: "header" });
expect(seen).toEqual(["text_us_clicked"]);
});
});