153 lines
5.3 KiB
Markdown
153 lines
5.3 KiB
Markdown
---
|
||
phase: 01-input-ux
|
||
plan: 02
|
||
type: execute
|
||
wave: 2
|
||
depends_on: ["01-01"]
|
||
files_modified:
|
||
- frontend/src/pages/WorkoutPage.jsx
|
||
autonomous: true
|
||
|
||
must_haves:
|
||
truths:
|
||
- "Each set row in WorkoutPage shows a WeightInput (- button, value, kg, + button) instead of a bare input"
|
||
- "Each set row shows a RepsInput (- button, value, + button) instead of a bare input"
|
||
- "Tapping + on weight increments by 2.5; tapping - decrements by 2.5"
|
||
- "Tapping + on reps increments by 1; tapping - decrements by 1"
|
||
- "Typing a negative weight or reps value is blocked — value stays at 0"
|
||
- "The kg suffix is visible next to the weight value inside the stepper"
|
||
artifacts:
|
||
- path: "frontend/src/pages/WorkoutPage.jsx"
|
||
provides: "Updated ExerciseCard using stepper inputs"
|
||
contains: "WeightInput"
|
||
key_links:
|
||
- from: "frontend/src/pages/WorkoutPage.jsx"
|
||
to: "frontend/src/components/WeightInput.jsx"
|
||
via: "import WeightInput"
|
||
pattern: "import WeightInput"
|
||
- from: "frontend/src/pages/WorkoutPage.jsx"
|
||
to: "frontend/src/components/RepsInput.jsx"
|
||
via: "import RepsInput"
|
||
pattern: "import RepsInput"
|
||
---
|
||
|
||
<objective>
|
||
Replace the two bare `<input type="number">` elements inside ExerciseCard's set-row with WeightInput and RepsInput components. Remove the now-unused .weight-input and .reps-input CSS rules.
|
||
|
||
Purpose: Users logging weight and reps now see +/- steppers with validation and the kg suffix — satisfying INP-01 through INP-03 and INP-06/INP-07.
|
||
Output: Updated WorkoutPage.jsx. The bare inputs are gone; stepper components are in.
|
||
</objective>
|
||
|
||
<execution_context>
|
||
@/home/intense/.claude/get-shit-done/workflows/execute-plan.md
|
||
@/home/intense/.claude/get-shit-done/templates/summary.md
|
||
</execution_context>
|
||
|
||
<context>
|
||
@.planning/PROJECT.md
|
||
@.planning/ROADMAP.md
|
||
@frontend/src/pages/WorkoutPage.jsx
|
||
@frontend/src/App.css
|
||
@.planning/phases/01-input-ux/01-01-SUMMARY.md
|
||
</context>
|
||
|
||
<tasks>
|
||
|
||
<task type="auto">
|
||
<name>Task 1: Integrate WeightInput and RepsInput into ExerciseCard</name>
|
||
<files>frontend/src/pages/WorkoutPage.jsx</files>
|
||
<action>
|
||
In frontend/src/pages/WorkoutPage.jsx, make these targeted changes:
|
||
|
||
1. Add two import statements at the top of the file (after the existing Icon import):
|
||
```
|
||
import WeightInput from '../components/WeightInput'
|
||
import RepsInput from '../components/RepsInput'
|
||
```
|
||
|
||
2. Inside the ExerciseCard component, find the set-row rendering block (around lines 321-343). Replace the two bare `<input>` elements and the separator span with:
|
||
```jsx
|
||
<WeightInput
|
||
value={input.weight}
|
||
onChange={(val) => handleInputChange(setNum, 'weight', val)}
|
||
/>
|
||
<span className="input-separator">×</span>
|
||
<RepsInput
|
||
value={input.reps}
|
||
onChange={(val) => handleInputChange(setNum, 'reps', val)}
|
||
/>
|
||
```
|
||
|
||
The handleInputChange function signature already accepts a plain string value (second arg is field name, third is value string) — the new components pass the string directly via onChange, which matches.
|
||
|
||
3. Update the .set-inputs CSS in App.css. Find the `.set-inputs` rule and change `align-items: center` to `align-items: flex-start` so the taller stepper containers align correctly at the top of the row. Also ensure `.set-row` uses `align-items: flex-start` rather than `center` (the complete-btn can stay aligned via its own styling).
|
||
|
||
In App.css, update:
|
||
```css
|
||
.set-inputs {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 0.75rem;
|
||
}
|
||
|
||
.set-row {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 0.75rem;
|
||
padding: 0.75rem;
|
||
background: var(--bg-secondary);
|
||
border-radius: 8px;
|
||
transition: all 0.2s;
|
||
}
|
||
```
|
||
|
||
4. Remove the now-redundant `.weight-input` and `.reps-input` rules from App.css. Search for:
|
||
```
|
||
.weight-input,
|
||
.reps-input {
|
||
```
|
||
and delete that entire rule block (approximately 8 lines). Also delete the mobile override block:
|
||
```
|
||
.weight-input,
|
||
.reps-input {
|
||
width: 60px;
|
||
padding: 0.5rem;
|
||
}
|
||
```
|
||
inside the `@media (max-width: 480px)` section.
|
||
|
||
Do NOT change any other part of WorkoutPage.jsx (warmup logic, progression hints, complete-btn, finish-workout-btn, etc.).
|
||
</action>
|
||
<verify>
|
||
1. grep -n "WeightInput\|RepsInput" frontend/src/pages/WorkoutPage.jsx
|
||
2. grep -n "weight-input\|reps-input" frontend/src/App.css (should return nothing — rules deleted)
|
||
3. cd /workspace/gravl/frontend && npm run build 2>&1 | tail -20
|
||
</verify>
|
||
<done>
|
||
- WorkoutPage.jsx imports and uses WeightInput and RepsInput in set rows
|
||
- .weight-input and .reps-input CSS rules are removed
|
||
- Build passes with no new errors
|
||
</done>
|
||
</task>
|
||
|
||
</tasks>
|
||
|
||
<verification>
|
||
Manual check: open the app in a browser, navigate to a workout, expand an exercise. Each set row should show:
|
||
[ - ] [ value ] [ kg ] [ × ] [ - ] [ value ] [ + ] [ complete ]
|
||
Tap + on weight: increments by 2.5. Tap - on reps: decrements by 1. Try typing -5 in weight: stays at 0.
|
||
</verification>
|
||
|
||
<success_criteria>
|
||
- Set rows use WeightInput and RepsInput, not bare inputs
|
||
- Weight increments by 2.5 per tap; reps increments by 1 per tap
|
||
- Negative values are blocked
|
||
- "kg" suffix is visible inside the weight stepper
|
||
- Build passes
|
||
</success_criteria>
|
||
|
||
<output>
|
||
After completion, create `.planning/phases/01-input-ux/01-02-SUMMARY.md` using the summary template.
|
||
</output>
|