type page = Dream_html.node
val login :
Dream.request -> ?error:string -> ?registration_open:bool -> unit -> page
(** [registration_open] shows the "Register" link. Defaults to [false]. *)
val register : Dream.request -> ?error:string -> unit -> page
val choose_routine :
Dream.request ->
workout_started:int option ->
viewer:View_model.Viewer.t ->
routines:View_model.Routine_choice.t list ->
page
val home :
Dream.request -> viewer:View_model.Viewer.t -> home:View_model.Home.t -> page
val workout_in_progress :
Dream.request ->
viewer:View_model.Viewer.t ->
workout_started:int ->
workout_name:string ->
page
(** The Home card shown while a workout is in progress. Links to the current
workout so it stays one tap away. [workout_started] drives the nav timer. *)
val routine :
Dream.request ->
?workout_started:int ->
viewer:View_model.Viewer.t ->
View_model.Routine.t ->
page
val workout :
Dream.request ->
viewer:View_model.Viewer.t ->
?workout_started:int ->
record_id:string option ->
active_slot:int ->
View_model.Workout.t ->
page
(** Renders every prescribed slot as an accordion — one native [details] per
slot, sharing a [name] so the browser keeps exactly one open — with the
active slot open. Authenticated pages carry generic progressive-enhancement
markers. Current workouts additionally mark slot links and forms, while
saved-record edits use the generic authenticated form path. [active_slot] is
the slot that opens. A handler clamps a requested slot and falls back to the
first outstanding slot. [record_id] is [None] for the workout in progress
and [Some id] for a saved history record. [workout_started] drives the nav
timer: a live workout uses its own start, so it is ignored there; a
saved-record view passes the epoch of a separate workout in progress, if
any. A refused record or correction is reported through the flash message on
the post-redirect-get reload, not inline. *)
val feedback_factors : (string * string) list
(** Ordered factor codes and labels. Each is a radio group in the feedback form
and a series in the feedback graph. *)
val logbook :
Dream.request ->
?workout_started:int ->
viewer:View_model.Viewer.t ->
?calendar:View_model.Calendar.t ->
?selected_date:View_model.Selected_date.t ->
?suggest_feedback:bool ->
?feedback_open:bool ->
?delete_record:View_model.Recorded_workout.t ->
?tab:string ->
?progress_charts:View_model.Progress_page.chart list ->
unit ->
page
(** The logbook: the Calendar and Progress views under one endpoint. The [tab]
parameter selects the active view. The [progress_charts] parameter supplies
chart data for the Progress view. *)
val profile :
Dream.request ->
?workout_started:int ->
viewer:View_model.Viewer.t ->
import_open:bool ->
?username_error:string ->
?password_error:string ->
?notice:string ->
unit ->
page
(** The account profile page: rename the account and change the password, each
an independent form. [username_error] and [password_error] report a refused
change inline. [notice] confirms a successful one. *)
val settings :
Dream.request ->
?workout_started:int ->
viewer:View_model.Viewer.t ->
theme:string ->
unit ->
page
(** The session-scoped theme settings page. *)
val import_review :
Dream.request ->
viewer:View_model.Viewer.t ->
View_model.Import_review.t ->
page
(** The review of a provisional Hevy import batch. Lists the rows dropped on
parse, then each workout with its sets, blockers, and acknowledgement state.
Renders a mapping form per distinct source name, a normal-set confirmation
form, a per-workout promote form, and a batch promote form. Basic accessible
HTML: it names no core entity, only the view model. *)
val problem : title:string -> detail:string -> page
val error_page :
?viewer:View_model.Viewer.t ->
?request:Dream.request ->
status:int ->
unit ->
page
(** A branded page for an HTTP failure. It names only the class of failure, so
no server-supplied string leaks, and keeps the navigation affordances: top
on desktop, bottom on mobile. *)
val app_feedback :
Dream.request ->
?workout_started:int ->
viewer:View_model.Viewer.t ->
?tab:[ `Write | `Submitted ] ->
?error:string ->
View_model.App_feedback.t list ->
page
(** The authenticated application feedback page. One tab accepts a freeform
message. The other lists the trainee's submitted messages. *)