HomeScreen.tsx

Entry point screen for profile setup, work area configuration, and navigation to predictions

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:

  • age is present and in the range [10, 90]
  • heightCm is present and in the range [120, 230]
  • weightKg is 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:

FieldMinMax
age1090
heightCm120230
weightKg30200

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:

StateDescription
todayCircle setShows today’s saved radius and an “Edit Area” button
Only fallbackCircleShows the most recent prior day’s area with its date
Neither setShows 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

ParameterDescription
navigationReact Navigation prop used to navigate to Prediction