The Multi-Program Calendar (Schedule Tab)
See every program a client has had — past, active, and future — in one calendar.
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.
- Click Clients in the sidebar to see your roster.
- Select a client from the list to open the client page.
- Open the Schedule tab. The toggle in the header switches between Calendar, Timeline and List.
- Choose Timeline to see every program as a bar, so overlaps and gaps stand out.
- 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).
