The BCGW Dashboard is a fullstack web application. The frontend is a React/TypeScript single-page app served via Firebase Hosting. The backend runs as Firebase Cloud Functions using Express.js. All data is stored in Firestore, and authentication is handled by Firebase Auth with multi-factor authentication (MFA) and role-based access control.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/hack4impact-umd/breastfeeding-center-gw/llms.txt
Use this file to discover all available pages before exploring further.
Tech stack
Frontend
React 18 + TypeScript, built with Vite. UI components from ShadCN and Tailwind CSS. Charts powered by Reaviz. Data fetching via TanStack Query. Routing with React Router v7.
Backend
Firebase Cloud Functions running Express.js. All external API calls are made server-side — the frontend never contacts external services directly.
Database
Firebase Firestore stores all synced client data, Jane import records, user profiles, and role assignments.
Authentication
Firebase Authentication with email/password sign-in and mandatory MFA (SMS or TOTP). Roles are stored as custom claims on JWT tokens.
Data flow
External data enters the system through Cloud Functions and is persisted to Firestore before the frontend reads it. Jane data is the exception — it enters via a manual upload rather than an API call. The React frontend reads exclusively from Firestore (via TanStack Query) and from Firebase Auth. It does not call Acuity, Booqable, or Squarespace directly.Authentication flow
All users must complete MFA setup before they can access the dashboard. MFA can be configured with either SMS or a TOTP authenticator app.
- The user enters their email and password at the login screen.
- Firebase Auth validates the credentials and challenges the user for their second factor (SMS code or TOTP).
- On successful MFA verification, Firebase issues a JWT with the user’s role embedded as a custom claim (
VOLUNTEER,ADMIN, orDIRECTOR). - The React app reads the role claim from the JWT to conditionally render UI elements and gate protected routes.
- Cloud Functions verify the JWT on every request and enforce role-based access server-side.
External integrations
| Service | Integration method | Data synced |
|---|---|---|
| Jane | Manual CSV/Excel upload | Appointments, client demographics |
| Acuity | REST API (server-side) | Class registrations, instructor data |
| Booqable | Stripe API (server-side) | Equipment rental orders |
| Squarespace | Commerce API (server-side) | Product purchases, order history |
Jane does not offer a public API. Staff export data directly from the Jane platform as Excel or CSV files and upload them through the dashboard’s data upload interface. The Cloud Function parses and normalizes the file before writing records to Firestore.
Client data model
Clients are unified across all four services using email address as the common key. When a sync runs for Acuity, Booqable, or Squarespace, the Cloud Function looks for an existing Firestore document with a matching email. If one exists, the new activity is appended to that client’s record. If not, a new client document is created. Jane data follows the same matching logic when uploaded. This means a client who booked an appointment through Jane, attended a class through Acuity, and rented equipment through Booqable will appear as a single unified record in the dashboard — with all three interactions visible in the client journey view.Clients without an email address in a given service cannot be matched and are stored as unlinked records. These appear separately in the client list and cannot be merged automatically.
Deployment
The application is deployed to Firebase Hosting via GitHub Actions. Two workflow files handle CI/CD:firebase-hosting-merge.yml— Runs on every merge tomain. Builds the React app and deploys to the production Firebase Hosting channel.firebase-hosting-pull-request.yml— Runs on every pull request. Deploys to a temporary preview channel and posts the preview URL as a PR comment.
