{{ monthLabel }}

{{ recordCount }} clients · {{ rangeLabel }}
NCOs purchased
{{ kpi.n }}
{{ kpi.nDelta }}
Converted
{{ kpi.yes }}
{{ kpi.yesDelta }}
Conversion rate
{{ kpi.conv }}
{{ kpi.convDelta }}
Still open
{{ kpi.open }}
{{ kpi.openNote }}
Revenue from wins
{{ kpi.rev }}
{{ kpi.revNote }}
By location · {{ monthLabel }}
LocationManagerNCOsWonLostOpenConv.Revenue
{{ l.name }} {{ l.manager }} {{ l.n }} {{ l.yes }} {{ l.lost }} {{ l.open }} {{ l.conv }} {{ l.rev }}
Why we lost · {{ ytdLabel }}{{ lossScope }}

{{ lossTotal }} losses (No + Abandoned). Uses the Loss reason field when set, otherwise inferred from Notes. Click a reason to see the clients.

{{ lossList.tag }}{{ lossList.count }} clients
ClientTrainerLocationBoughtNote
{{ c.name }}{{ c.trainerOrDash }}{{ c.locName }}{{ c.boughtFull }}{{ c.noteOrDash }}
Trend · bar height = NCOs purchased, filled = converted · click a bar to jump to that month
{{ tl.name }} {{ tl.ytdNote }}
{{ b.label }}
Review notes · from the imported workbook
  1. SLU has turned around. 2025 (Jul–Dec) converted 44% of 108 NCOs; 2026 year to date is 57% of 210, at 26 a month versus 18. Belltown is the steadiest location, between 47% and 64% every month of 2026.
  2. Madison Park's August is the open problem. 13 of 20 August NCOs are still pending and most notes say "waitlist" or "switching trainers" after the Nika reassignment. Only 1 conversion logged so far, against a 55% norm.
  3. June was SLU's weak month. 14 losses out of 25 (32% conversion). Notes cluster around form checks, travel and "too expensive"; several were follow-ups that went unanswered.
  4. A third of losses carry no reason in Notes. Among tagged losses, "no response" and "form check only" lead, with "too expensive" close behind. The Oct 1 price rise ($65 → $85, $99 → $129) makes that last tag the one to watch; the new Loss reason field replaces guessing.
  5. Scheduled-but-not-purchased is where wins leak. The Follow-up tab now reads the three session dates, so a client whose third session has passed without a result rises to the top.
What wins turned into · {{ ytdLabel }}{{ lossScope }}
Plan or packageSoldRevenue
{{ p.pkg }}{{ p.n }}{{ p.rev }}

{{ pkgNote }}

At least {{ minN }} NCOs in the period · {{ hiddenTrainers }} below the line
#TrainerLocationNCOsWonLostOpenConv.
{{ t.rank }} {{ t.trainer }} {{ t.locName }} {{ t.n }} {{ t.yes }} {{ t.lost }} {{ t.open }} {{ t.conv }}
{{ queueCount }} open clients{{ queueQNote }}

{{ g.title }}

{{ g.count }} {{ g.hint }}
Next stepClientLocationTrainerBoughtLast contactNoteResolve
{{ r.next }} {{ r.name }} {{ r.locName }} {{ r.trainerOrDash }} {{ r.boughtFull }} {{ r.lastContact }} {{ r.notes }}

{{ monthLabel }} · {{ entryScope }}

{{ entryHint }}

{{ entryQNote }}

BoughtClientLocTrainerResultLoss reason / planNotes
{{ r.bought }} {{ r.name }} {{ r.loc }} {{ r.pkgShort }}

{{ detail.name }}

{{ detailMeta }}
Suggested from the note "{{ detail.notes }}". Save to confirm, or change it above.
{{ detailRevLabel }}{{ detailRev }}

Add a new client

{{ savedMsg }}
{{ syncText }} {{ syncMsg }}
Active clients
{{ rk.active }}
{{ rk.activeNote }}
Monthly recurring
{{ rk.mrr }}
{{ rk.mrrNote }}
Per active client
{{ rk.avg }}
average monthly
Pack clients
{{ rk.packs }}
{{ rk.packNote }}

No clients on the roster yet

{{ rosterEmptyMsg }}

Load from Mindbody reports:

Handoffs in progress

clients being moved off a departing trainer · monthly value retained vs. lost
DepartingClientsContactedComp bookedComp doneTransferredLostRetained /moLost /moOpen /mo
{{ h.from }}
{{ h.locName }} · since {{ h.since }}
{{ h.n }} {{ h.contacted }} {{ h.booked }} {{ h.done }} {{ h.transferred }} {{ h.lost }} {{ h.retained }} {{ h.lostMrr }} {{ h.openMrr }}

{{ g.trainer }}

{{ g.locName }} {{ g.count }} clients {{ g.mrr }} /mo at risk if all left
ClientTrainingMembershipMonthlyLast seenVisitsStatus
{{ c.name }}NCO
{{ c.handoffLabel }}
{{ c.planLabel }}
{{ c.notes }}
{{ c.gymLabel }} {{ c.monthly }} {{ c.lastSeenLabel }} {{ c.visitsLabel }}

{{ rc.name }}

{{ rcMeta }}

Add a client

Regular-rate clients who didn't come through an NCO, or anyone missing. NCO wins are added automatically when you pick their plan.
Handoff
{{ rfHandoffNote }}
Monthly value{{ rfValue }}
{{ rcMsg }}
Performance summary · {{ rv.period }}

{{ rv.trainer }}

{{ rv.locName }} · manager {{ rv.manager }} · {{ rv.span }}
NCOs assigned
{{ rv.n }}
{{ rv.nNote }}
Conversion
{{ rv.conv }}
{{ rv.convNote }}
Won · Lost · Open
{{ rv.wlo }}
{{ rv.rankNote }}
Revenue from wins
{{ rv.rev }}
{{ rv.revNote }}
Current roster
{{ rv.rosterN }}
active clients · {{ rv.rosterNco }} came via NCO
Monthly recurring
{{ rv.rosterMrr }}
what leaves if the book walks
Largest client
{{ rv.rosterTop }}
{{ rv.rosterTopNote }}
Month by month
MonthNCOsWonConv.Location
{{ m.label }}{{ m.n }}{{ m.yes }}{{ m.conv }}{{ m.locConv }}
What clients bought
{{ p.pkg }}{{ p.n }}
No priced wins in this period.
Why clients didn't continue
{{ t.tag }}
{{ t.count }}
No losses in this period.
Talking points
  • {{ p.text }}
Every client · {{ rv.period }}
BoughtClientResultPlan / note
{{ c.bought }}{{ c.name }}{{ c.result }}{{ c.detail }}

Connect to Supabase

Paste the two values from your Supabase project (Settings → API). The anon key is safe to share; access is controlled by sign-in.

Sign in

Connected

Signed in as{{ conn.email }}
Project{{ conn.host }}
Rows{{ recordCount }}
Live updates{{ conn.rt }}
{{ dupCount }} duplicate rows found. The workbook was imported more than once. Removing duplicates keeps one copy of each client and brings the stats back to the real numbers.
{{ inferredCount }} wins priced from their notes. Older wins have free-text packages like "8-pack + membership". The tracker reads those and applies the price sheet in force on the purchase date. Saving writes the matched plan onto each record so managers can correct any of them.
The database is empty. Load the 775 clients from the workbook (Jul 2025 – Sep 2026) so everyone starts from the same history.
No clients loaded yet. Ask Charith to import the workbook.
{{ connMsg }}
One-time setup (about 15 minutes)
  1. Create a free project at supabase.com. Pick the US West region.
  2. SQL Editor → paste supabase/schema.sql → Run. This creates the table, edit rules and live updates.
  3. Sign in below, then click Import workbook to load the 775 rows from the spreadsheet. (Or run supabase/seed.sql in the SQL Editor.)
  4. SQL Editor → paste supabase/roster.sql → Run. Adds the client-roster table for the Clients tab.
  5. SQL Editor → paste supabase/handoff.sql → Run. Adds handoff tracking for trainer departures (then redeploy the mindbody-sync function).
  6. Mindbody sync: Edge Functions → Deploy new function named mindbody-sync, paste index.ts. Add secrets MB_API_KEY, MB_SITE_ID, MB_STAFF_USER, MB_STAFF_PASS. Then SQL Editor → run supabase/sync.sql for the nightly schedule.
  7. Authentication → Providers → Email: turn off "Allow new users to sign up".
  8. Authentication → Users → Add user → Create new user: email, a password, tick "Auto Confirm User". Do this for you, Mo, Christopher and Chellsey, and share each password privately. No email is sent.
  9. Optional, later: Authentication → Emails → Set up SMTP (Gmail app password or Resend). That unlocks the "Email me a code" option and password-reset emails.
  10. The project URL and anon key are already built in, so managers only need to open this page and sign in with their email.

"Use a different project" → "Disconnect project" switches to a demo on the imported workbook, with edits kept on this device only.

How this works
  • Everything you enter saves as you type and shows up for everyone right away.
  • Entry is your weekly update: set each client's Result, and pick what they bought when it's a Yes.
  • Follow-up lists clients still open, sorted by their next session date.
  • Stay signed in on your own computer; sign out only on a shared one.
{{ loadingMsg }}