From e49b44f99179bbd8fb336f81979b8c17de5ad22f Mon Sep 17 00:00:00 2001 From: Dave Liu <7david12liu@gmail.com> Date: Sun, 18 Oct 2026 17:44:52 -0700 Subject: [PATCH 1/7] Embed Zeffy membership form on Join Us for staging review (#750) --- .github/lint-baseline.json | 17 ++--- OFFICER_START_HERE.md | 2 + SYSTEM_DESIGN.md | 2 + docs/officers/README.md | 2 + docs/officers/ZEFFY_MEMBERSHIP.md | 56 +++++++++++++++++ src/App.test.jsx | 6 +- src/components/ZeffyMembershipForm.jsx | 63 +++++++++++++++++++ src/components/ZeffyMembershipForm.test.jsx | 70 +++++++++++++++++++++ src/components/zeffyMembershipForm.css | 30 +++++++++ src/pages/joinUs/JoinUs.jsx | 29 +-------- src/pages/joinUs/JoinUs.test.jsx | 18 ++++++ 11 files changed, 258 insertions(+), 37 deletions(-) create mode 100644 docs/officers/ZEFFY_MEMBERSHIP.md create mode 100644 src/components/ZeffyMembershipForm.jsx create mode 100644 src/components/ZeffyMembershipForm.test.jsx create mode 100644 src/components/zeffyMembershipForm.css create mode 100644 src/pages/joinUs/JoinUs.test.jsx diff --git a/.github/lint-baseline.json b/.github/lint-baseline.json index 61c4e119..b55f7095 100644 --- a/.github/lint-baseline.json +++ b/.github/lint-baseline.json @@ -10,10 +10,10 @@ "targets": [ "src" ], - "scannedFileCount": 137, + "scannedFileCount": 140, "scannedFilesByExtension": { ".js": 12, - ".jsx": 35, + ".jsx": 38, ".ts": 52, ".tsx": 38 }, @@ -31,7 +31,7 @@ ".ts": 0, ".tsx": 6 }, - "fingerprint": "sha256:b4fdd4e8efba6c011d293d96f8453a4e2dccccddf7907e2ff9b67cf2b74ba81f", + "fingerprint": "sha256:b35a20454e66177c3055a06768686a0f310d15cca2f45d633a4b74f497cafd21", "scannedFiles": [ "src/App.jsx", "src/App.test.jsx", @@ -56,6 +56,8 @@ "src/components/Subheader.jsx", "src/components/UpcomingEventsPreview.tsx", "src/components/VideoCarousel.jsx", + "src/components/ZeffyMembershipForm.jsx", + "src/components/ZeffyMembershipForm.test.jsx", "src/components/index.ts", "src/data.jsx", "src/headerClearance.test.js", @@ -97,6 +99,7 @@ "src/pages/events/raceCheckoutRequest.ts", "src/pages/home/Home.jsx", "src/pages/joinUs/JoinUs.jsx", + "src/pages/joinUs/JoinUs.test.jsx", "src/pages/joinUs/JoinUsConditionalRoute.jsx", "src/pages/joinUs/Route.jsx", "src/pages/joinUs/Waiver.jsx", @@ -1318,9 +1321,9 @@ }, { "file": "src/pages/joinUs/JoinUs.jsx", - "line": 130, + "line": 105, "column": 1, - "endLine": 130, + "endLine": 105, "endColumn": 104, "severity": 2, "ruleId": "max-len", @@ -1331,9 +1334,9 @@ }, { "file": "src/pages/joinUs/JoinUs.jsx", - "line": 134, + "line": 109, "column": 17, - "endLine": 134, + "endLine": 109, "endColumn": 36, "severity": 2, "ruleId": "react/no-array-index-key", diff --git a/OFFICER_START_HERE.md b/OFFICER_START_HERE.md index 8072d529..d308cafc 100644 --- a/OFFICER_START_HERE.md +++ b/OFFICER_START_HERE.md @@ -1,5 +1,7 @@ # MPRC Website: Officer Start Here +**Zeffy membership preview — October 18, 2026:** the Join Us source embeds the club's supplied Zeffy form with an iframe fallback and a direct link. The [view-only review guide](./docs/officers/ZEFFY_MEMBERSHIP.md) records staging evidence separately. This is the real provider form; do not submit details or pay during the demo. No Firebase membership activation or production release is included. + **Saved test Checkout — October 18, 2026, native clarification verified:** Hosting `30d5f27` now explains when Resume cannot reopen the same open, inactive purchase. A fresh sandbox decline/expiry retained the original order and term; no replacement payment or membership was created. Both owned test accounts were retired, seven financial-record hashes stayed unchanged and two expiry receipts were retained. Dues Functions remain v1/source `71f59e2`. [Dated evidence](./docs/TEST_DUES_RECOVERY_MESSAGE.md) and [officer steps](./docs/officers/TEST_DUES.md). Real payments, production, family invitations and final club policies remain separate. Earlier checkpoints below are historical. **Member-screen staging checkpoint — #739, October 16, 2026:** Function v7 and Hosting source `799565e` are verified, including the downloaded archive, all 62 website files, genuine Auth/App Check and ten member/retry/expiry/cancellation checks with fresh fictional fixtures and verified cleanup. Full-site screenshots exposed a fixed-header style collision on the member navigation. The navigation correction is now published at `d08a6a3`; all 62 final assets, four deep routes, genuine sign-in, desktop/390px navigation/focus and fresh cleanup passed in [closed #739](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/739). Function v7 remains unchanged. Online dues and real membership/payments remain unavailable. [Officer review](./docs/officers/MEMBER_SCREEN.md). diff --git a/SYSTEM_DESIGN.md b/SYSTEM_DESIGN.md index 09339218..1f34b1e9 100644 --- a/SYSTEM_DESIGN.md +++ b/SYSTEM_DESIGN.md @@ -1,5 +1,7 @@ # MPRC Platform System Design +**Zeffy membership embed — October 18, 2026, source prepared:** Join Us replaces its Google membership application link with the owner-supplied fixed Zeffy form, route-scoped loader, iframe-on-loader-error fallback and persistent direct link. The staging page labels this as a view-only display of a real provider form. No form value, payment result or provider message is read into Firebase; no account, role, dues, webhook, schema or membership synchronization is added. Prices and renewal terms remain provider content and require reconciliation before production. See the [officer procedure and data-flow map](./docs/officers/ZEFFY_MEMBERSHIP.md) for exact staging evidence. This source note does not claim a merge, deployment, submission or production release. + **Saved test Checkout — October 18, 2026, native clarification verified:** Hosting `30d5f27` now explains when Resume cannot reopen the same open, inactive purchase. A fresh sandbox decline/expiry retained the original order and term; no replacement payment or membership was created. Both owned test accounts were retired, seven financial-record hashes stayed unchanged and two expiry receipts were retained. Dues Functions remain v1/source `71f59e2`. [Dated evidence](./docs/TEST_DUES_RECOVERY_MESSAGE.md) and [officer steps](./docs/officers/TEST_DUES.md). Real payments, production, family invitations and final club policies remain separate. Earlier checkpoints below are historical. **Member-screen staging checkpoint — #739, October 16, 2026:** Function v7 and Hosting source `799565e` are verified, including the downloaded archive, all 62 website files, genuine Auth/App Check and ten member/retry/expiry/cancellation checks with fresh fictional fixtures and verified cleanup. Full-site screenshots exposed a fixed-header style collision on the member navigation. The navigation correction is now published at `d08a6a3`; all 62 final assets, four deep routes, genuine sign-in, desktop/390px navigation/focus and fresh cleanup passed in [closed #739](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/739). Function v7 remains unchanged. Online dues and real membership/payments remain unavailable. [Officer review](./docs/officers/MEMBER_SCREEN.md). diff --git a/docs/officers/README.md b/docs/officers/README.md index 596e678c..6d3fcd37 100644 --- a/docs/officers/README.md +++ b/docs/officers/README.md @@ -1,5 +1,7 @@ # Officer Website Handbook +[Review the Zeffy membership preview](./ZEFFY_MEMBERSHIP.md) on Join Us. The supplied form is real: view only during staging review. Provider submissions, payments, Firebase activation and production release remain separate. + **October 18:** [Test annual dues](./TEST_DUES.md) now has a verified stop message when a saved Checkout cannot reopen. Keep the purchase and ask Dave for reconciliation. Read the [native evidence and exact test-account cleanup](../TEST_DUES_RECOVERY_MESSAGE.md); real payments and production remain separate. [Test annual dues](./TEST_DUES.md) has a connected staging screen and verified core hosted flow and [bounded native recovery checks](../TEST_DUES_NATIVE_RECOVERY.md) as of October 17. Fresh specialist-provided fictional accounts are required; the completed run's accounts were removed. Read the [dated evidence and remaining qualification](../TEST_DUES_HOSTED_EVIDENCE.md). Real payments and production remain separate. diff --git a/docs/officers/ZEFFY_MEMBERSHIP.md b/docs/officers/ZEFFY_MEMBERSHIP.md new file mode 100644 index 00000000..86041130 --- /dev/null +++ b/docs/officers/ZEFFY_MEMBERSHIP.md @@ -0,0 +1,56 @@ +# Review the Zeffy membership form + +**Status:** [issue #750](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/750), source prepared October 18, 2026. Staging deployment and screen evidence will be recorded below. Production is **NOT AVAILABLE YET** for this change. + +**Purpose:** review the embedded membership form on the Join Us page without creating a membership or payment. + +**Approver:** Dave for this staging demonstration. The membership lead, treasurer and platform owner must approve a later production release. + +**Prerequisites:** the specialist supplies the exact staging preview link and source revision. Stay signed out. The displayed Zeffy form is the club's real form, not a payment sandbox. Do not enter information, accept a waiver, submit or pay. + +```mermaid +flowchart LR + A["Staging Join Us page"] --> B["Zeffy embed loader"] + B --> C["Club membership form on Zeffy"] + A --> D["Direct link if the embed is unavailable"] + D --> C + B -- "Loader fails" --> E["Embedded iframe fallback"] + E --> C + C -. "No account activation or sync added" .-> F["Existing Firebase member system"] +``` + +In words: the Join Us page displays the club's form from Zeffy and retains a separate direct link; a failed loader uses an iframe, and this change adds no Firebase membership synchronization. + +## Review without a terminal + +1. Open the specialist's staging link while signed out. +2. Find **Become an MPRC Member** on Join Us. +3. Confirm the notice identifies a staging preview of the real Zeffy form. +4. Confirm the club's membership options or opening message appear inside the page. +5. Open **Open the membership form in a new tab**. +6. Confirm it points to the club's membership on `www.zeffy.com`. +7. Close the new tab without entering information. +8. Return to Home and then Join Us. +9. Confirm only one visible membership form appears. +10. Repeat at phone and computer widths. +11. Leave the separate **Sign Waiver Form** unchanged and unused. + +**Expected result:** the form is readable within Join Us. A direct link remains usable if the embed fails. There is no duplicate Google membership signup link. Prices and renewal terms are supplied by Zeffy; this change does not settle the conflicting provider description and options noted October 18. + +**Stop conditions:** wrong club/form, missing real-form notice, clipped controls, duplicate forms, missing direct link, unexpected account activation, or any request to test a payment or submit real details. + +**Success proof:** exact source revision, staging URL and deployment ID, dated phone/computer screenshots, one-form navigation check, loader/fallback tests and served artifact hashes. Viewing a form proves display only. It does not prove payment, membership activation, provider configuration or production readiness. + +**Undo:** ask the platform maintainer to expire the task's preview channel. For a later published change, use a reviewed revert and the normal protected release path. Do not edit Zeffy records, delete members or refund a payment to undo a website preview. + +**Escalation:** platform owner for display or deployment; membership lead and treasurer for provider options/prices; privacy owner for collected data or policy. A specialist is still required for deployment. + +## Deployment evidence + +- Source: local implementation; not merged. +- Tests: 28 frontend suites / 1,531 tests pass under Node 20. The new files have no lint findings. The exact lint baseline retains the same 113 legacy errors and six legacy warnings; only two old Join Us findings move with the removed Google-link lines. +- Staging website: pending. +- `runmprc.com`: unchanged; no production release authorized. +- Firebase Functions, Rules, Auth, IAM and data: unchanged. +- Zeffy account/form configuration: unchanged; public form display only. +- Payments and membership submissions: not performed. diff --git a/src/App.test.jsx b/src/App.test.jsx index efcff535..e4810fea 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -921,9 +921,9 @@ test('keeps the real Join route structured data free of an unapproved membership expect(JSON.stringify(joinSchema)).not.toMatch( /"@type":"Offer"|"price":|"priceCurrency":|Annual membership fee for individuals \(2026\)/, ); - expect(screen.getByText( - 'Affordable membership fees: $25/individual or $30/household per calendar year', - )).toBeInTheDocument(); + expect(screen.getByRole('link', { name: /open the membership form in a new tab/i })) + .toHaveAttribute('href', 'https://www.zeffy.com/en-US/ticketing/mid-peninsula-running-clubs-membership'); + expect(screen.queryByText(/Affordable membership fees:/)).not.toBeInTheDocument(); }); test('keeps the shared Join schema helper price-neutral while retaining organization and run data', () => { diff --git a/src/components/ZeffyMembershipForm.jsx b/src/components/ZeffyMembershipForm.jsx new file mode 100644 index 00000000..5bd2eb1b --- /dev/null +++ b/src/components/ZeffyMembershipForm.jsx @@ -0,0 +1,63 @@ +import React, { useEffect, useRef, useState } from 'react'; +import './zeffyMembershipForm.css'; + +const FORM_PATH = '/embed/ticketing/mid-peninsula-running-clubs-membership'; +const FORM_URL = `https://www.zeffy.com${FORM_PATH}`; +const MEMBERSHIP_URL = 'https://www.zeffy.com/en-US/ticketing/mid-peninsula-running-clubs-membership'; + +function ZeffyMembershipForm() { + const embedRef = useRef(null); + const scriptRef = useRef(null); + const [useFallback, setUseFallback] = useState(false); + + useEffect(() => { + const embed = embedRef.current; + const script = document.createElement('script'); + script.src = 'https://www.zeffy.com/embed/v2/zeffy-embed.js'; + script.async = true; + script.onerror = () => setUseFallback(true); + scriptRef.current.appendChild(script); + + return () => { + script.onerror = null; + script.remove(); + // Zeffy owns the children it adds here. A route remount starts fresh. + embed.replaceChildren(); + }; + }, []); + + return ( +
+ {process.env.REACT_APP_FIREBASE_ENVIRONMENT === 'staging' && ( +

+ Staging preview: + {' '} + This is the club's real Zeffy form. View only; do not submit details or pay. +

+ )} +

+ Join or renew through Zeffy. Membership options, prices and opening dates + are shown in the form. +

+

+ + Open the membership form in a new tab + +

+