Workout logger

A React block (a whole screen) in Beamline's Salon & fitness app.

A live training session: every exercise's sets as target-table rows with a done column; marking a set done fills its shape and starts the rest by itself (a timer bar dragged for more or less, or skipped); a timed set's own inline timer marks it done; the elapsed time, the counts and the set up next beside them. Finish opens the review (name, date and start time, duration, how it went, a photo, who sees it, where it goes); Save says saved and each destination's result apart; a session that changed its routine then asks to update it, and a routine changed meanwhile is said.

Use it for

  • Logging a training session as it happens: sets marked done, a rest between them, a timed set, then saving it with where it goes.
  • Any session of repeated rounds done live, with a rest between rounds and a review at the end (rehab, drills, intervals).

Not for

Anatomy

  • head: the session's title (on a phone the elapsed time beside it)
  • exercises: each a card with its name ('Added this session' when it isn't in the routine) and its sets as target-table rows with done; the set up next ringed; a timed exercise's next set with its inline timer
  • side (wide; a docked foot on a phone): the elapsed time large with its start, sets done of all and volume, the rest while it runs (the timer's large form with Skip rest), the rest's end said once, the set up next in words and drawn as its shape (stays in view through the rest) with Last time and Go to the set, the session outline (a tick per set), Finish after it
  • review: name, date, start time, duration (minutes, scrubbed or typed), how it went, a photo; beside it the duration, sets and volume large, sets not done said, who sees it, where it goes, Save
  • after the save: Saved to your history and one line per destination (sent, or not sent with the reason and Try again); then, if the session changed its routine, the changes in words with Update the routine or Keep the original

States

  • nothing done yet; some done; every set done
  • rest running (bar drag or ←/→ give more or less; Skip rest), rest ended ('Rest's over: Bench press, set 3 is next.' once), no rest (after the last set, before a drop set, rest off)
  • a done set undone (its rest stops)
  • a timed set running its own timer, which marks it done at the end
  • an exercise added this session
  • review: sets not done said; saving; save refused (the reason with Try again, nothing lost); saved with a destination that failed (its own line, Try again), a destination sending
  • routine decision: asking, updating, changed elsewhere (said; Update becomes Replace with this session), updated, kept
  • narrow room: one column, the rest and Finish docked at the foot, the elapsed time in the head

Keyboard

  • every set's fields, bar and done mark as target-table's (Tab, arrows on the bar, Enter or Space on done)
  • the rest's bar: ←/→ five seconds (Shift: thirty), as the timer's
  • Go to the set moves focus to the next set's done mark
  • the review's fields in order; Save; Try again on a failed destination

Motion

Done fills the set's segments one after another from the row's start (a short ink sweep, once); the rest's bar drains with the clock. Nothing else moves; reduced motion fills at once.

Props

PropTypeDefaultDescription
title / startedAt (required)string / number—title: The session's name ("Push"); editable in the review. startedAt: When the session started (ms since the epoch, your clock).
exercises (required)Exercise[]—The exercise library (names and measures).
items / defaultItems / onItemsChangePlanItem[]—The session's exercises and sets (what Start handed you), edited live.
done / defaultDone / onDoneChangestring[]—Ids of the sets marked done.
routineRoutine | null—The routine the session started from: after a save, a changed session offers to update it.
destinations{ id, name }[]—Where a saved workout can also go; all are chosen by default.
onSave (required)(workout: FinishedWorkout) => Promise<DestinationResult[]>—Saves the workout. Resolve with each destination's result (a failed destination is not a failed save); reject when the workout itself wasn't saved (its message is shown with Try again).
onRetryDestination(id: string) => Promise<DestinationResult>—Sends a saved workout to one destination again.
onUpdateRoutine(items, { replace }) => Promise<"updated" | "conflict">—Writes the session's exercises and sets into the routine. Resolve "conflict" when the routine changed since the session started (its revision moved); `replace` then asks to overwrite it anyway.
onDone() => void—After the save (and the routine decision, when there is one): your app leaves the session.
view / defaultView / onViewChange"log" | "review"—The session or its review.
clock() => number—Your clock (ms since the epoch). Default Date.now. Elapsed time and rest are read from it.
title (required)string—The session's name ("Push"); editable in the review.
startedAt (required)number—When the session started (ms since the epoch, your clock).
itemsPlanItem[]—The session's exercises and sets: what Start handed you (workout-planner's PlanStart.items), edited live.
defaultItemsPlanItem[]—
onItemsChange((items: PlanItem[]) => void)—
donestring[]—Ids of the sets marked done. Store them with the items to survive a reload.
defaultDonestring[]—
onDoneChange((done: string[]) => void)—
viewLoggerView—
defaultViewLoggerView—
onViewChange((view: LoggerView) => void)—
labelsPartial<{ elapsed: Message; startedAt: Message; setsDone: Message; setsDoneLabel: Messa…—
classNamestring—Classes on the documented visual root; no override by default.
refRef<HTMLDivElement>—Receives the documented native target or imperative handle; omitted by default.
defaultPhoto{ src: string; alt: string; } | null—A photo the session already has (taken on the phone during it): the review opens with it as the post's picture.

Built from

Dependencies

lucide-react

Import

import { WorkoutLogger } from "@beamline/workout-logger";

Get it

Workout logger is part of Beamline UI. Install the parts you need in your React app as compiled packages or editable source. Get Beamline · Connect your agent

More in Salon & fitness

  • Workout planner: A training plan a person lives in: the program's next session with its estimate and Start, an exercise replaced for this session only or for every later…
  • Training progress: A person's training history: the headline counts (weeks in a row, days since the last workout, workouts this month), a month calendar that names each…
  • Program setup: A training program's setup and living settings: the intake (one question per step, the week drawn as you answer, a failed generation keeping every…
  • Protocol builder: A practitioner's reusable protocol and the client copies made from it. Foods and habits each carry a written intent (Include, Reduce, Exclude) in its…
  • Nutrition library: A nutrition practice's library. Recipes: ingredients with grams and servings, nutrients per serving summed (energy, protein, carbohydrate, fat, fibre), a…
  • Packages & memberships: Prepaid packages and series, built: the packages down the side (version and how many sold, or not on sale yet), the open one beside them. Its price is a…
  • Client forms: A salon's or spa's client forms and who they ask: the forms down the side with where each stands (on, set up and off, not set up yet), the open one…
  • Instructor finder: Finding a flight instructor. Search by name or airfield, filter by what you want to learn (each subject with how many teach it nearby), by distance, and…
  • Flight logbook: A pilot's logbook. Total time (with hours brought forward from earlier logbooks), PIC, night, the last 90 days and how many entries are still incomplete…

Part of Beamline UI: polished, editable React components and complete screens for custom applications. Build your own style from any look; tokens, fonts, radii, motion; not only colours.