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:
@@ -0,0 +1,187 @@
|
||||
{
|
||||
"$schema": "./campuses.schema.json",
|
||||
"_readme": "Single source of truth for campus data. Read by the Next.js frontend (src/config/campuses.ts) and by the PHP API (public/api/lib/campuses.php). Facts were verified against waterschurch.org on 2026-09-22 unless listed under `verify`. Edit this file, then rebuild (npm run build) and re-upload.",
|
||||
"campuses": [
|
||||
{
|
||||
"id": "north-attleboro",
|
||||
"name": "North Attleboro",
|
||||
"label": "North Attleboro, MA",
|
||||
"status": "open",
|
||||
"isCentral": true,
|
||||
"address": {
|
||||
"line1": "57 John L Dietsch Square",
|
||||
"city": "North Attleboro",
|
||||
"state": "MA",
|
||||
"postalCode": "02763"
|
||||
},
|
||||
"coordinates": { "lat": 41.97396, "lng": -71.29631 },
|
||||
"timezone": "America/New_York",
|
||||
"serviceTimes": [
|
||||
{ "day": "Sunday", "times": ["7:30 AM", "9:30 AM", "11:30 AM"] }
|
||||
],
|
||||
"phone": "+15086951300",
|
||||
"smsNumber": "+15086951300",
|
||||
"sinchAccountId": "WatersChurch_OLA_0007",
|
||||
"email": "info@waterschurch.org",
|
||||
"campusUrl": "https://waterschurch.org/locations/north-attleboro/",
|
||||
"directionsUrl": "https://www.google.com/maps/dir/?api=1&destination=Waters+Church%2C+57+John+L+Dietsch+Square%2C+North+Attleboro%2C+MA+02763",
|
||||
"leader": { "title": "Lead Pastor", "name": "Tim Hatch" },
|
||||
"arrivalNotes": null,
|
||||
"parkingNotes": null,
|
||||
"kidsNotes": "Waters Kids programs run at every service time.",
|
||||
"image": "north-attleboro",
|
||||
"verify": ["parkingNotes", "arrivalNotes", "coordinates"]
|
||||
},
|
||||
{
|
||||
"id": "norwood",
|
||||
"name": "Norwood",
|
||||
"label": "Norwood, MA",
|
||||
"status": "open",
|
||||
"isCentral": false,
|
||||
"address": {
|
||||
"line1": "668 Walpole Street",
|
||||
"city": "Norwood",
|
||||
"state": "MA",
|
||||
"postalCode": "02062"
|
||||
},
|
||||
"coordinates": { "lat": 42.17153, "lng": -71.22482 },
|
||||
"timezone": "America/New_York",
|
||||
"serviceTimes": [
|
||||
{ "day": "Sunday", "times": ["9:30 AM", "11:00 AM"] },
|
||||
{ "day": "First Wednesday of the month", "times": ["7:00 PM"] }
|
||||
],
|
||||
"phone": "+17817623357",
|
||||
"smsNumber": "+17817623357",
|
||||
"sinchAccountId": "WatersChurch_OLA_0002",
|
||||
"email": "info@waterschurchnorwood.org",
|
||||
"campusUrl": "https://waterschurch.org/locations/norwood/",
|
||||
"directionsUrl": "https://www.google.com/maps/dir/?api=1&destination=Waters+Church+Norwood%2C+668+Walpole+Street%2C+Norwood%2C+MA+02062",
|
||||
"leader": { "title": "Senior Pastor", "name": "Tommy Geyser" },
|
||||
"arrivalNotes": null,
|
||||
"parkingNotes": null,
|
||||
"kidsNotes": "Waters Kids programs run at every service time.",
|
||||
"image": "norwood",
|
||||
"verify": ["parkingNotes", "arrivalNotes", "coordinates"]
|
||||
},
|
||||
{
|
||||
"id": "woonsocket",
|
||||
"name": "Woonsocket",
|
||||
"label": "Woonsocket, RI",
|
||||
"status": "open",
|
||||
"isCentral": false,
|
||||
"address": {
|
||||
"line1": "1500 Diamond Hill Road",
|
||||
"city": "Woonsocket",
|
||||
"state": "RI",
|
||||
"postalCode": "02895"
|
||||
},
|
||||
"coordinates": { "lat": 42.01634, "lng": -71.47692 },
|
||||
"timezone": "America/New_York",
|
||||
"serviceTimes": [
|
||||
{ "day": "Sunday", "times": ["9:00 AM", "11:00 AM"] }
|
||||
],
|
||||
"phone": "+15086951300",
|
||||
"smsNumber": "+18332414837",
|
||||
"sinchAccountId": "WatersChurch_OLA_0005",
|
||||
"email": "info@waterschurch.org",
|
||||
"campusUrl": "https://waterschurch.org/locations/woonsocket/",
|
||||
"directionsUrl": "https://www.google.com/maps/dir/?api=1&destination=Waters+Church+Woonsocket%2C+1500+Diamond+Hill+Rd%2C+Woonsocket%2C+RI+02895",
|
||||
"leader": { "title": "Location Pastor", "name": "Jim Shekleton" },
|
||||
"arrivalNotes": null,
|
||||
"parkingNotes": null,
|
||||
"kidsNotes": "Waters Kids programs run at every service time.",
|
||||
"image": "woonsocket",
|
||||
"verify": ["parkingNotes", "arrivalNotes", "coordinates", "phone"]
|
||||
},
|
||||
{
|
||||
"id": "southcoast",
|
||||
"name": "Southcoast",
|
||||
"label": "Southcoast, RI/MA",
|
||||
"status": "open",
|
||||
"isCentral": false,
|
||||
"address": {
|
||||
"line1": "28 Fish Road",
|
||||
"city": "Tiverton",
|
||||
"state": "RI",
|
||||
"postalCode": "02878"
|
||||
},
|
||||
"coordinates": { "lat": 41.66752, "lng": -71.17603 },
|
||||
"timezone": "America/New_York",
|
||||
"serviceTimes": [
|
||||
{ "day": "Sunday", "times": ["10:30 AM"] }
|
||||
],
|
||||
"phone": "+15086951300",
|
||||
"smsNumber": "+15088093490",
|
||||
"sinchAccountId": "WatersChurch_OLA_0006",
|
||||
"email": "info@waterschurch.org",
|
||||
"campusUrl": "https://waterschurch.org/locations/southcoast/",
|
||||
"directionsUrl": "https://www.google.com/maps/dir/?api=1&destination=Waters+Church+Southcoast%2C+28+Fish+Road%2C+Tiverton%2C+RI+02878",
|
||||
"leader": { "title": "Location Pastor", "name": "Mehdi Chniouli" },
|
||||
"arrivalNotes": null,
|
||||
"parkingNotes": null,
|
||||
"kidsNotes": "Waters Kids programs run at every service time.",
|
||||
"image": "southcoast",
|
||||
"verify": ["parkingNotes", "arrivalNotes", "coordinates", "phone"]
|
||||
},
|
||||
{
|
||||
"id": "apollo-beach",
|
||||
"name": "Apollo Beach",
|
||||
"label": "Apollo Beach, FL",
|
||||
"status": "open",
|
||||
"isCentral": false,
|
||||
"address": {
|
||||
"line1": "5309 North US Hwy 41",
|
||||
"city": "Apollo Beach",
|
||||
"state": "FL",
|
||||
"postalCode": "33572"
|
||||
},
|
||||
"coordinates": { "lat": 27.74286, "lng": -82.41918 },
|
||||
"timezone": "America/New_York",
|
||||
"serviceTimes": [
|
||||
{ "day": "Sunday", "times": ["9:00 AM", "11:00 AM"] }
|
||||
],
|
||||
"phone": "+18136426979",
|
||||
"smsNumber": "+18136426979",
|
||||
"sinchAccountId": "WatersChurch_OLA_0003",
|
||||
"email": "info@waterschurch.org",
|
||||
"campusUrl": "https://waterschurch.org/locations/apollo-beach/",
|
||||
"directionsUrl": "https://www.google.com/maps/dir/?api=1&destination=Waters+Church+Apollo+Beach%2C+5309+N+US+Hwy+41%2C+Apollo+Beach%2C+FL+33572",
|
||||
"leader": { "title": "Location Pastor", "name": "Tom Duck" },
|
||||
"arrivalNotes": null,
|
||||
"parkingNotes": null,
|
||||
"kidsNotes": "Waters Kids programs run at every service time.",
|
||||
"image": "apollo-beach",
|
||||
"verify": ["parkingNotes", "arrivalNotes", "coordinates"]
|
||||
},
|
||||
{
|
||||
"id": "orlando",
|
||||
"name": "Orlando",
|
||||
"label": "Orlando, FL",
|
||||
"status": "launching",
|
||||
"isCentral": false,
|
||||
"address": {
|
||||
"line1": "Castle Door Studios, 1890 Kentucky Ave",
|
||||
"city": "Winter Park",
|
||||
"state": "FL",
|
||||
"postalCode": "32789"
|
||||
},
|
||||
"coordinates": { "lat": 28.59213, "lng": -81.37501 },
|
||||
"timezone": "America/New_York",
|
||||
"serviceTimes": [
|
||||
{ "day": "Sunday", "times": ["10:30 AM"], "note": "Doors open 10:00 AM. Currently gathering with the launch team only." }
|
||||
],
|
||||
"phone": "+15086951300",
|
||||
"smsNumber": null,
|
||||
"sinchAccountId": null,
|
||||
"email": "info@waterschurch.org",
|
||||
"campusUrl": "https://waterschurch.org/locations/orlando/",
|
||||
"directionsUrl": "https://www.google.com/maps/dir/?api=1&destination=1890+Kentucky+Ave%2C+Winter+Park%2C+FL+32789",
|
||||
"leader": { "title": "Pastor", "name": "Tim Hatch" },
|
||||
"arrivalNotes": null,
|
||||
"parkingNotes": null,
|
||||
"kidsNotes": null,
|
||||
"image": "orlando",
|
||||
"verify": ["status", "serviceTimes", "smsNumber", "kidsNotes", "coordinates"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Waters Church campuses",
|
||||
"type": "object",
|
||||
"required": ["campuses"],
|
||||
"properties": {
|
||||
"campuses": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "name", "label", "status", "address", "coordinates", "serviceTimes", "phone", "campusUrl", "directionsUrl"],
|
||||
"properties": {
|
||||
"id": { "type": "string", "pattern": "^[a-z0-9-]+$" },
|
||||
"name": { "type": "string" },
|
||||
"label": { "type": "string" },
|
||||
"status": { "enum": ["open", "launching", "hidden"] },
|
||||
"isCentral": { "type": "boolean" },
|
||||
"address": {
|
||||
"type": "object",
|
||||
"required": ["line1", "city", "state", "postalCode"],
|
||||
"properties": {
|
||||
"line1": { "type": "string" }, "city": { "type": "string" },
|
||||
"state": { "type": "string" }, "postalCode": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"coordinates": { "type": "object", "required": ["lat", "lng"], "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } } },
|
||||
"timezone": { "type": "string" },
|
||||
"serviceTimes": {
|
||||
"type": "array",
|
||||
"items": { "type": "object", "required": ["day", "times"], "properties": { "day": { "type": "string" }, "times": { "type": "array", "items": { "type": "string" } }, "note": { "type": ["string", "null"] } } }
|
||||
},
|
||||
"phone": { "type": "string", "pattern": "^\\+[1-9][0-9]{6,14}$" },
|
||||
"smsNumber": { "type": ["string", "null"], "pattern": "^\\+[1-9][0-9]{6,14}$" },
|
||||
"sinchAccountId": { "type": ["string", "null"] },
|
||||
"email": { "type": ["string", "null"] },
|
||||
"campusUrl": { "type": "string", "format": "uri" },
|
||||
"directionsUrl": { "type": "string", "format": "uri" },
|
||||
"leader": { "type": ["object", "null"], "properties": { "title": { "type": "string" }, "name": { "type": "string" } } },
|
||||
"arrivalNotes": { "type": ["string", "null"] },
|
||||
"parkingNotes": { "type": ["string", "null"] },
|
||||
"kidsNotes": { "type": ["string", "null"] },
|
||||
"image": { "type": ["string", "null"] },
|
||||
"verify": { "type": "array", "items": { "type": "string" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user