HomeScreen.tsx
Purpose
This module renders the Home tab, which serves a dual purpose: presenting the primary call-to-action for starting a new prediction and hosting the user profile and language settings forms.
Its responsibilities include:
- Displaying the current date and a localized welcome header
- Gating the “New Prediction” button behind profile completeness validation
- Surfacing and editing the user’s daily work area via
DailyWorkAreaContext - Providing inline editing of all profile fields (gender, unit system, age, height, weight)
- Keeping imperial display fields live-synced to canonical metric storage values
- Computing and displaying BMI from the current draft values
- Persisting profile changes and language preference atomically on save
- Allowing individual fields to be reset to defaults without affecting gender or unit system
- Localizing all labels and status messages via
react-i18next
Invariants
Canonical Metric Storage
Profile data is always stored in metric units (heightCm, weightKg).
Imperial display fields (heightFeet, heightInches, weightLbs) are derived values only. On save, only the canonical metric fields are read from the draft. This means imperial inputs are always converted to metric in real time as the user types.
Profile Validation Notice
Profile edits are not saved until the profile draft is valid. When the draft is invalid, a red validation notice is rendered directly below the profile card.
The notice reuses the same validation message keys as first-run setup:
ageis present and in the range[10, 90]heightCmis present and in the range[120, 230]weightKgis present and in the range[30, 200]- In imperial mode: visible height and weight are validated against rounded imperial bounds, then clamped to canonical metric bounds on save
Validation is computed from the draft state on every render via useMemo.
Settings Card Order
Settings cards render in this fixed order:
- Activity
- Today’s work area
- Profile
- Language
- Research upload
The profile validation notice is not a card; when present, it appears directly below the Profile card.
Save Button Gating
The “Save Changes” button is disabled when:
- a save is already in progress, or
- no changes have been made relative to the last saved state (draft fields and language are compared field-by-field)
Input Clamping on Save
Raw text input values are clamped to valid physiological ranges at save time, not during editing:
| Field | Min | Max |
|---|---|---|
age | 10 | 90 |
heightCm | 120 | 230 |
weightKg | 30 | 200 |
Invalid or empty inputs fall back to the last saved profile value.
Atomic Save
Profile and language are written in parallel via Promise.all([saveProfile(...), saveLanguage(...)]).
Both are committed together or neither updates the “last saved” snapshot used for change detection.
Unit System Switch Side Effects
Switching from metric to imperial populates the imperial display fields from the current canonical metric values.
Switching back to metric clears the imperial fields but retains the metric values unchanged. The unit system preference is immediately persisted to the profile store on switch, independently of the main save flow.
Variants
Work Area States
The work area card renders one of three states depending on DailyWorkAreaContext:
| State | Description |
|---|---|
todayCircle set | Shows today’s saved radius and an “Edit Area” button |
Only fallbackCircle | Shows the most recent prior day’s area with its date |
| Neither set | Shows a “not set” prompt and a “Set Area” button |
Height Input — Imperial Mode
In imperial mode, height uses two separate inputs (feet and inches) that both contribute to the live-synced heightCm canonical value.
Both fields must be non-empty for the metric equivalent to be computed.
Exports
HomeScreen (default)
export default function HomeScreen({ navigation }: any): JSX.Element
Renders the settings tab with activity, work area, profile, language, and research upload sections.
Parameters
| Parameter | Description |
|---|---|
navigation | React Navigation prop used to navigate to Prediction |