Skip to content

Phase 5: Workout Execution Screen + Rest Timer#5

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/implement-fast-execution-flow
Draft

Phase 5: Workout Execution Screen + Rest Timer#5
Copilot wants to merge 2 commits intomainfrom
copilot/implement-fast-execution-flow

Conversation

Copy link
Contributor

Copilot AI commented Feb 28, 2026

Delivers the core "fast execution" flow: Start Workout → log sets per exercise → rest timer → finish and mark day complete. Targets ≤3 steps from planning to execution with no tab navigation.

New: Execution Screen (app/(app)/workout/[id].tsx)

Replaces the Phase 5 placeholder. Route param id is an ISO date string (YYYY-MM-DD); invalid dates render an error card.

  • Header: back arrow + workout title + ⏱ button
  • Compact hero card: category badge, duration, muscle groups
  • Exercise list: one card per exercise, one row per prescribed set
    • Checkbox toggles completion; reps/weight inputs pre-filled from structured_json
    • Saves to workout_logs on blur via upsert keyed on (planned_workout_id, exercise_name, set_number)
    • Optimistic UI; inline red error on save failure
  • Rest timer modal: 60/90/120s chips, start/pause/reset, large countdown. Graceful fallback (Alert) on finish — no expo-av/expo-haptics dependency
  • Finish Workout: confirms if zero sets logged; sets is_completed=true + completed_at=now(), navigates back

API (lib/api.ts)

Four new helpers:

fetchPlannedWorkoutByDate(date: string): Promise<PlannedWorkout | null>
fetchWorkoutLogs(plannedWorkoutId: string): Promise<WorkoutLog[]>
upsertWorkoutLog(plannedWorkoutId, exerciseName, setNumber, repsCompleted, weight): Promise<WorkoutLog>
finishPlannedWorkout(plannedWorkoutId: string): Promise<void>

Store (store/useWorkoutStore.ts)

Added activePlannedWorkout, activeWorkoutLogs, and upsertActiveWorkoutLog (uses findIndex to avoid double-iteration).

Types (types/index.ts)

WorkoutLog.reps_completed and weight are now number | null to match upsert semantics.

Entry Points

  • Today screen (index.tsx): Start Workout navigates to /workout/<selectedDate> (was workout UUID)
  • Planner screen (planner.tsx): shows Start Workout CTA for today/past unlocked days; shows Completed badge for finished days
Original prompt

Phase 5 — Workout Execution + Rest Timer (Judy)

Build Phase 5 in pcdev333/judy-ui now that Phase 3/4 and config fixes are merged into main.

Goal

Deliver the core “fast execution” flow: the user taps Start Workout → executes sets with minimal friction → logs sets quickly → uses a built-in rest timer → finishes workout and marks the day completed.

UX constraints (must follow)

  • Maintain existing theme/style from the mockups.
  • Reduce friction from planning to execution.
  • Each workflow max 3 steps.
  • No bottom tab navigation; use back arrows.
  • Background always #F2F2F7.
  • Cards white, radius 16, subtle shadow.
  • Primary CTA: black background #1A1A1A, white bold text, orange accent.
  • FAB: orange #E8470A, 56px, bottom-right.

Data model assumptions

Use existing tables in Supabase:

  • planned_workouts (includes is_completed, completed_at)
  • workout_logs (per-set logs)
  • workouts.structured_json contains exercises and prescribed sets/reps/weight.

Screens / routes

1) Create app/(app)/workout/[plannedDate].tsx

A dedicated execution screen for a specific date (ISO date string passed as route param plannedDate).

Entry points

  • From Today screen (Start Workout) for today’s planned date.
  • From Planner screen when selecting a day that has a workout (add Start button if needed).

Screen layout

  • Header: back arrow + title (workout title) + small timer icon button to open rest timer.
  • Top card: workout hero summary (reuse WorkoutHeroCard but in compact mode if necessary).
  • Main content: list of exercises (accordion or stacked cards). Each exercise card shows:
    • Exercise name
    • Prescribed sets x reps (and weight if provided)
    • A quick “Log set” row repeated for each prescribed set number:
      • Checkbox / toggle for completed
      • Inputs for reps completed and weight (prefill from prescription)
      • “Save” action should be implicit: saving on blur/change with debounce or a single tap per set.
  • Bottom area: primary CTA Finish Workout.

Rest timer

  • Rest timer is a modal/bottom sheet.
  • Defaults: 60s, 90s, 120s quick chips.
  • Start/pause/reset.
  • While running, show remaining time prominently.
  • When finished: play a sound (use Expo AV if available) and haptic feedback (Expo Haptics) if installed; otherwise graceful fallback.

Logging behavior

  • On first visit, fetch planned workout + linked workout + existing logs.
  • When user marks a set completed or edits reps/weight, upsert into workout_logs keyed by:
    • planned_workout_id, exercise_name, set_number.
  • Use optimistic UI and show minimal inline error (small red text) if save fails.

Finish Workout

  • When tapped:
    • Ensure at least 1 set is logged; otherwise confirm “Finish anyway?”
    • Update planned_workouts row: is_completed=true, completed_at=now()
    • Navigate back to Today screen.

2) Update Today screen app/(app)/index.tsx

  • Wire Start Workout CTA to navigate to /workout/<todayISODate>.
  • If no planned workout today, CTA should be disabled or replaced with “Plan Workout”.
  • If today is locked but not planned, show a friendly nudge.

3) Update Planner screen app/(app)/planner.tsx

  • If selected day has a planned workout, show Start Workout primary CTA (black) if it’s today or past, otherwise keep as preview.
  • If day is completed, show “Completed” state.

API updates

Update lib/api.ts with helpers:

  • fetchPlannedWorkoutByDate(date: string) returning planned_workout joined with workout.
  • fetchWorkoutLogs(plannedWorkoutId: string)
  • upsertWorkoutLog(plannedWorkoutId: string, exerciseName: string, setNumber: number, repsCompleted: number | null, weight: number | null)
  • finishPlannedWorkout(plannedWorkoutId: string)

Store updates

Update Zustand store (store/useWorkoutStore.ts) to include:

  • activePlannedWorkout and activeWorkoutLogs
  • Actions to set/update logs locally.

Implementation notes

  • Keep type safety: add/update types for PlannedWorkout join shape and WorkoutLog.
  • Ensure the route param plannedDate is validated (ISO date), and show an error card if invalid.
  • Loading skeletons for workout + logs.
  • Avoid complex multi-step flows; keep execution fast.

Acceptance criteria

  • User can start a planned workout from Today.
  • Execution screen loads workout definition and shows per-set rows.
  • Logs persist to Supabase and reload correctly.
  • Rest timer works (modal) and does not crash if AV/Haptics unavailable.
  • Finish workout marks day completed and updates planner/today UI accordingly.

This pull request was created from Copilot chat.


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

- Add full execution screen (app/(app)/workout/[id].tsx):
  per-exercise/per-set logging rows, rest timer modal (60/90/120s),
  optimistic saves, finish workout with completion marking
- Add API helpers: fetchPlannedWorkoutByDate, fetchWorkoutLogs,
  upsertWorkoutLog, finishPlannedWorkout (lib/api.ts)
- Add store state: activePlannedWorkout, activeWorkoutLogs with
  upsertActiveWorkoutLog action (store/useWorkoutStore.ts)
- Make WorkoutLog.reps_completed and weight nullable (types/index.ts)
- Wire Start Workout to navigate by planned date (app/(app)/index.tsx)
- Add Start Workout + Completed CTAs in Planner (app/(app)/planner.tsx)

Co-authored-by: pcdev333 <124543139+pcdev333@users.noreply.github.com>
Copilot AI changed the title [WIP] Build Phase 5 for workout execution and rest timer Phase 5: Workout Execution Screen + Rest Timer Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants