# Setup Guide — St. John's Christian Church Website

This walks you through the two accounts the site needs: **Firebase** (members, milestones,
church calendar, and staff login) and **Google Apps Script** (Connect Card and Contact form
submissions, sent to a Google Sheet). Both are free for a church this size. Budget about 30
minutes total, and do them in order.

---

## Part 1: Firebase (members, calendar, and staff login)

### Step 1 — Create the project
1. Go to [console.firebase.google.com](https://console.firebase.google.com) and sign in with a
   Google account the church controls (not a personal one, if you can help it).
2. Click **Add project**. Name it something like `st-johns-groton`. You can decline Google
   Analytics — it isn't needed here.
3. Click **Create project** and wait for it to finish.

### Step 2 — Register a Web App
1. On the project's home screen, click the **`</>`** (web) icon to add a web app.
2. Give it a nickname like "SJCC Website" and click **Register app**. You don't need Firebase
   Hosting for this step.
3. Firebase will show a code block with a `firebaseConfig` object — something like:
   ```js
   const firebaseConfig = {
     apiKey: "AIza...",
     authDomain: "st-johns-groton.firebaseapp.com",
     projectId: "st-johns-groton",
     storageBucket: "st-johns-groton.appspot.com",
     messagingSenderId: "123456789",
     appId: "1:123456789:web:abc123"
   };
   ```
4. Copy those six values into **the config section at the top of `app.js`** in this project, replacing every
   `"REPLACE_ME"`. Save the file.

### Step 3 — Turn on Firestore (the database)
1. In the left sidebar, click **Build ▸ Firestore Database**.
2. Click **Create database**. Choose **Start in production mode**, pick a location close to
   Connecticut (e.g. `us-east4` or `nam5`), and click **Enable**.
3. Once it's created, click the **Rules** tab and replace the contents with:
   ```
   rules_version = '2';
   service cloud.firestore {
     match /databases/{database}/documents {
       function isStaff() {
         return request.auth != null &&
           exists(/databases/$(database)/documents/staff/$(request.auth.uid));
       }
       function staffDoc() {
         return get(/databases/$(database)/documents/staff/$(request.auth.uid)).data;
       }
       function isSuperAdmin() {
         return isStaff() && staffDoc().role == 'superadmin';
       }
       function canEditMembers() {
         return isStaff() && (staffDoc().role == 'superadmin' || staffDoc().canEditMembers == true);
       }

       match /calendarEvents/{doc} {
         allow read: if true;
         allow write: if isStaff();
       }
       match /milestones/{doc} {
         allow read, write: if isStaff();
       }
       match /members/{doc} {
         allow read, write: if canEditMembers();
       }
       match /galleryPhotos/{doc} {
         allow read: if true;
         allow write: if isStaff();
       }
       match /inquiries/{doc} {
         allow create: if true;
         allow read, update, delete: if isStaff();
       }
       match /staff/{doc} {
         allow read: if isStaff();
         allow write: if isSuperAdmin();
       }
     }
   }
   ```
4. Click **Publish**. This makes the public calendar visible to any visitor. Everything else now
   depends on a **staff document** existing for the signed-in user (Step 5 below) — a Firebase
   Auth login by itself no longer grants access to anything.

### Step 4 — Turn on staff login (Authentication)
1. In the left sidebar, click **Build ▸ Authentication**, then **Get started**.
2. Under **Sign-in method**, enable **Email/Password** (the first option in the list).
3. Go to the **Users** tab and click **Add user**. Enter your own email and a password — this
   becomes the site's first Super Admin. (Everyone after this first one can be invited straight
   from the dashboard itself — see below — you won't need to come back to this Users tab again.)
4. **Copy this user's UID** — click on the row you just created and copy the "User UID" value.
   You'll need it in the next step.

### Step 5 — Make yourself the first Super Admin
Every staff member needs two things: a Firebase Authentication login (Step 4), and a matching
**staff document** in Firestore that says what they're allowed to do. Normally the Super Admin
creates both at once from the dashboard's "Invite Admin" button — but the very first Super Admin
has to be created manually, once, here:

1. In the left sidebar, click **Firestore Database ▸ Data** tab.
2. Click **Start collection**. For the Collection ID, type exactly `staff`.
3. For the **Document ID**, paste the UID you copied in Step 4 (not an auto-ID — it must be that
   exact UID, since that's how the rules above match a login to its permissions).
4. Add these fields:
   - `email` (string) — your email, exactly as you used in Step 4
   - `role` (string) — `superadmin`
   - `canEditMembers` (boolean) — `true`
5. Click **Save**.

Firebase is now fully connected. Open `admin.html`, sign in with the email/password from Step 4,
and you should land on the dashboard with a **Staff Access** tab visible in the sidebar (only
Super Admins see this tab). From there, use **+ Invite Admin** to create logins for everyone
else — no more trips to the Firebase console needed.

**How inviting and removing staff actually works:** when you invite someone, the dashboard
creates their Firebase login and their staff record in one step — just share the email and
temporary password with them directly (text, call, in person). They can set their own password
under Settings once they've signed in. When you remove someone, their staff record is deleted,
which immediately blocks them from every part of the dashboard — but their underlying login
technically still exists (deleting logins outright needs a small backend server, which this
site doesn't have). In practice this doesn't matter: without a staff record they can't get past
the sign-in screen at all.

---

## Part 2: Google Apps Script (Connect Card + Contact form → Google Sheet)

### Step 1 — Create the Sheet
1. Go to [sheets.google.com](https://sheets.google.com) and create a new blank spreadsheet.
   Name it something like "SJCC Website Submissions".

### Step 2 — Add the script
1. In the Sheet, click **Extensions ▸ Apps Script**.
2. Delete any starter code in `Code.gs`.
3. Open **`AppsScript-Code.gs.txt`** from this project, copy its entire contents, and paste
   them into `Code.gs`.
4. Click the **Save** icon (or `Ctrl+S` / `Cmd+S`).

### Step 3 — Deploy it as a web app
1. Click **Deploy ▸ New deployment**.
2. Click the gear icon next to "Select type" and choose **Web app**.
3. Set:
   - **Execute as:** Me
   - **Who has access:** Anyone
4. Click **Deploy**. The first time, Google will ask you to authorize the script — click
   through the consent screens (you'll see an "unverified app" warning since this is your own
   private script; click **Advanced ▸ Go to (project name)** to proceed).
5. Copy the **Web app URL** it gives you.

### Step 4 — Connect it to the site
1. Open **the config section at the top of `app.js`** in this project.
2. Paste the Web app URL as the value of `APPS_SCRIPT_URL`.
3. Optionally, paste the Sheet's own URL (from your browser's address bar while viewing it) as
   `CHURCH_SHEET_URL` — this adds a quick link to the Sheet from the admin dashboard.
4. Save the file.

Submissions from the Connect Card (I'm New page) and the Contact form (Home page) will now
appear as new rows in two tabs of your Sheet: **Connect Cards** and **Contact Messages**. Both
tabs are created automatically the first time each form is submitted.

---

## Part 2.5: Cloudinary (photo galleries)

Photos for the Ministries page (Men's, Women's, Children's, Community Events) are hosted on
Cloudinary — free, no credit card required, and the admin dashboard uploads directly to it.

1. Go to **[cloudinary.com](https://cloudinary.com)** and sign up for a free account (email,
   Google, or GitHub — no card needed).
2. Once you're in, your **Cloud Name** is shown right on the dashboard home page (top of the
   screen, or under Settings). Copy it.
3. Click **Settings** (gear icon) ▸ **Upload** tab ▸ scroll to **Upload presets** ▸ **Add upload
   preset**.
4. Set **Signing Mode** to **Unsigned** — this is what lets the dashboard upload photos directly
   from the browser without needing a backend server. Give the preset any name you like (or keep
   the auto-generated one), and click **Save**.
5. Copy that preset's name.
6. Open `app.js`, find the Cloudinary section near the top, and paste in your two values:
   ```js
   const CLOUDINARY_CLOUD_NAME = "your-cloud-name";
   const CLOUDINARY_UPLOAD_PRESET = "your-preset-name";
   ```

That's it — no further Cloudinary configuration needed. Photos uploaded from the dashboard's
**Photos** tab go straight to your Cloudinary account, and only their web links are stored in
Firestore — never the actual image files. Firestore isn't built to hold binary files like photos,
and Cloudinary's free tier (no card required) is generous enough that a normal-sized church photo
gallery should never come close to its limits, especially since every photo is automatically
resized and compressed before upload.

---

## Part 3: Payments (already set up separately)

The Giving page uses a PayPal donate button. To make it live, open **`giving.html`**, find the
`YOUR-PAYPAL-BUSINESS-EMAIL@example.com` placeholder, and replace it with your church's real
PayPal business email (create one free at [paypal.com/business](https://www.paypal.com/business)
if you don't have one yet).

---

## Part 3.5: The Verse of the Day

The homepage now fetches its daily verse text live from [bible-api.com](https://bible-api.com) —
a free, no-key API. Nothing to set up here; it works out of the box. A few things worth knowing:

- Each day of the year is pre-mapped to a reference (e.g. "John 3:16") in the `VERSES` list near
  the top of `app.js`. The site asks bible-api.com for that day's reference and displays whatever
  text comes back.
- **If bible-api.com is ever unreachable** (down, blocked, no internet), the site automatically
  falls back to the KJV text already stored alongside that reference in `app.js` — visitors will
  never see a broken or blank verse.
- **Caching:** once a verse is fetched, it's saved in the visitor's browser for the rest of that
  day, so repeat page loads don't re-fetch it.
- **Changing translation:** find `const VOTD_TRANSLATION = "kjv";` near the top of `app.js` and
  change it to another code bible-api.com supports (e.g. `"web"` for the World English Bible) —
  see bible-api.com's site for the full list of available translations.
- **Changing which verses appear:** edit the `VERSES` list in `app.js` — add, remove, or reorder
  entries (each just needs a `ref`; the `text` field only matters as the offline fallback).

---

## Part 3.6: The homepage hero video

The homepage is built for a full-bleed video of an aerial/drone view of Groton — harbor, coastline,
or the church itself all work well. To add it:

1. Get footage. A few realistic options:
   - Hire a local drone operator for an afternoon (search "drone videographer Groton CT" or
     "drone videographer New London County") — often $150–$400 for a short flight.
   - Check if the Town of Groton or the CT Office of Tourism has existing aerial footage they'll
     license for community/nonprofit use.
   - License a generic New England coastline aerial clip from a stock site like
     [Pexels Videos](https://www.pexels.com/videos/) or [Coverr](https://coverr.co) if you'd
     rather not wait on original footage — just double-check the license allows commercial/church
     website use (most free-tier clips do, but always read the specific terms).
2. Export or trim it to a short (10–25 second), silent, looping clip — no audio is needed since
   the video plays muted.
3. Save it as `hero-video.mp4` inside the `assets` folder, replacing nothing (there's no
   placeholder file — you're adding a new one).
4. Optional: grab one still frame from the video, save it as `hero-poster.jpg` in `assets` — it
   shows briefly while the video loads.

Until you add the video, the hero displays its purple gradient background on its own, so the
site never looks broken in the meantime.

---

## Part 4: Publishing the site

This is a static site (plain HTML/CSS/JS) — it doesn't need a special server. Two easy, free
options:

- **[Netlify Drop](https://app.netlify.com/drop)** — drag this whole folder onto the page and
  it's live in seconds, with a free `.netlify.app` address you can later point your own domain
  (e.g. `stjohnsgroton.org`) at.
- **GitHub Pages** — push this folder to a GitHub repository and enable Pages in the repo
  settings.

Either way, once Firebase and Apps Script are configured as above, everything will work exactly
the same on the live site as it does on your computer.

---

## A note on security

- Firestore rules above mean member and milestone data can only be read or written by a signed-in
  staff account — not by the public.
- Only add staff members you trust with this data as Firebase Authentication users.
- The Google Sheet is only as private as your Google Drive sharing settings — don't share it
  publicly, and consider restricting it to specific church staff.
