The Multi-Program Calendar (Schedule Tab)

See every program a client has had — past, active, and future — in one calendar.

trainer guide/clients/[id]
What this is for: Visualize a client's entire program history at a glance and spot gaps or overlaps.

What this is for

Trainers asked: "Show me everything I've assigned this client across the year, not just what's active right now." The Schedule tab does exactly that.

  1. Click Clients in the sidebar to see your roster.
  2. Select a client from the list to open the client page.
  3. Open the Schedule tab. The toggle in the header switches between Calendar, Timeline and List.
  4. Choose Timeline to see every program as a bar, so overlaps and gaps stand out.
  5. Choose List for a simple week by week read-through.

It's the 8th tab on the Client 360 dashboard (/clients/[clientId]).

Three views, one toggle

In the tab header you have a Calendar / Timeline / List toggle.

Calendar view (default)

  • Month grid with prev / next / today buttons.
  • Each day cell shows the workout template (or "Rest") for whatever program is active that day.
  • Color-coded by program — legend below the grid maps colors to program names.
  • Click a day cell to open the day detail modal (template name, exercises, completion status if past).

Timeline view

  • Horizontal Gantt-strip — one row per program, time on the X axis.
  • Active programs render in saturated color; archived/past programs in muted color; future programs as dashed bars.
  • Best for spotting overlaps (two programs running concurrently) and gaps (no program assigned).

List view

  • Mobile-friendly. Vertical list of dates + workout name + program name.
  • Best for quick read-through of upcoming or past 30 days.

"Assign Program" is always visible

The Assign Program button appears in the header of all three views, plus in the empty-state CTA when the client has no programs yet. Clicking it opens the AssignProgramModal pre-scoped to this client.

Including past + archived programs

The API (GET /api/clients/[clientId]/schedule?includeInactive=true) returns every program ever assigned to this client. The UI honors the ?includeInactive flag so:

  • Default: shows only active and future programs.
  • Toggle: includes archived/past programs (muted styling).

Underneath the hood

The ScheduleTab calls expandCycleToCalendar() from lib/workout-scheduling/expand-cycle.ts. For each program assignment, it walks day-by-day from startDate to endDate, picks the cycle slot for each weekday, and emits a calendar entry. Legacy programs (isLegacy=true) walk Week 1→Week N instead.

Common pitfalls

Where to find this

  • Page: /clients/[clientId] → Schedule tab.
  • Components: ScheduleTab, ScheduleCalendar, ProgramTimeline, ScheduleListView, AssignProgramModal.
  • API: GET /api/clients/[clientId]/schedule (query params: from, to, includeInactive=true).
Was this article helpful?