Fix(1187): misleading placement of height input#1191
Fix(1187): misleading placement of height input#1191CodeWithCJ merged 2 commits intoCodeWithCJ:mainfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request moves the height input from the check-in form to the profile settings page and refactors the settings accordion structure to support deep linking via URL parameters. It also updates the profile incomplete alert to link directly to the profile section. Feedback focuses on ensuring the height state is correctly synchronized with asynchronous data, preventing the saving of zero values for height, and using the specialized UnitInput component for better unit support.
| const [profileForm, setProfileForm] = useState<ProfileFormState>({ | ||
| full_name: profile.full_name || '', | ||
| phone: profile.phone_number || '', | ||
| date_of_birth: profile.date_of_birth || '', | ||
| bio: profile.bio || '', | ||
| gender: profile.gender || '', | ||
| height: heightData?.height || '', | ||
| }); |
There was a problem hiding this comment.
The profileForm state is initialized with heightData?.height on mount. However, since heightData is fetched asynchronously, it will likely be undefined during the initial render, leaving the height field empty even if a value exists in the database. You should use a useEffect to synchronize the height value once the query data becomes available.
const [profileForm, setProfileForm] = useState<ProfileFormState>({
full_name: profile.full_name || '',
phone: profile.phone_number || '',
date_of_birth: profile.date_of_birth || '',
bio: profile.bio || '',
gender: profile.gender || '',
height: heightData?.height || '',
});
useEffect(() => {
if (heightData?.height && !profileForm.height) {
setProfileForm((prev) => ({
...prev,
height: heightData.height,
}));
}
}, [heightData, profileForm.height]);
| const measurementData: UpdateCheckInMeasurementsRequest = { | ||
| entry_date: formatDateInUserTimezone(new Date(), 'yyyy-MM-dd'), | ||
| height: Number(profileForm.height), | ||
| }; |
There was a problem hiding this comment.
When profileForm.height is an empty string, Number(profileForm.height) evaluates to 0. Saving 0 as a height measurement is likely incorrect and could break BMR/TDEE calculations. It is better to send null or skip the measurement update if the field is empty.
if (profileForm.height) {
const measurementData: UpdateCheckInMeasurementsRequest = {
entry_date: formatDateInUserTimezone(new Date(), 'yyyy-MM-dd'),
height: Number(profileForm.height),
};
await saveCheckInMeasurements(measurementData);
}
| <div> | ||
| <Label htmlFor="height"> | ||
| {t('settings.profileInformation.height', 'Height')} | ||
| </Label> | ||
| <div className="relative"> | ||
| <Input | ||
| id="height" | ||
| type="number" | ||
| value={profileForm.height} | ||
| onChange={(e) => | ||
| setProfileForm((prev) => ({ | ||
| ...prev, | ||
| height: e.target.value, | ||
| })) | ||
| } | ||
| placeholder={t( | ||
| 'settings.profileInformation.enterHeight', | ||
| 'Enter your Height' | ||
| )} | ||
| /> | ||
| <span className="absolute right-3 top-1/2 -translate-y-1/2 text-sm text-gray-500 pointer-events-none"> | ||
| {defaultMeasurementUnit} | ||
| </span> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
Using a standard Input with type="number" for height loses support for non-metric units like 'Feet & Inches' (ft/in), which is a supported preference in this app. You should use the UnitInput component (with type="height") to ensure consistency with the rest of the application and proper unit handling. Note: You will need to import UnitInput from @/components/ui/UnitInput.
<div>
<Label htmlFor="height">
{t('settings.profileInformation.height', 'Height')}
</Label>
<UnitInput
id="height"
type="height"
unit={defaultMeasurementUnit}
value={profileForm.height.toString()}
onChange={(val) =>
setProfileForm((prev) => ({
...prev,
height: val.toString(),
}))
}
/>
</div>
Description
What problem does this PR solve?
Height input is required for tdee and the "update profile" link leads to profile information. But height was in the daily checkin tab. While height can change, nobody will track it daily.
How did you implement the solution?
I moved the height field to the profile information and removed it from daily check in. It's still saved the same way as before. I added the ability for a link to expand any sections in the settings and fixed a UI bug with the warning on small screens.
Linked Issue: Closes #1187
How to Test
PR Type
Checklist
All PRs:
New features only:
Frontend changes (
SparkyFitnessFrontend/orsrc/):pnpm run validateand it passes.en) translation file.Backend changes (
SparkyFitnessServer/):rls_policies.sqlfor any new user-specific tables.UI changes (components, screens, pages):