LandingScreen.tsx

First-run onboarding flow for language selection and initial profile setup

Purpose

This module renders the first-run onboarding experience presented to users before they access the main application. It walks the user through two sequential steps: selecting a display language and entering their physical profile.

Its responsibilities include:

  • Displaying a two-step sequential onboarding flow controlled by local step state
  • Persisting the selected language immediately on selection (before the user proceeds)
  • Collecting and validating physical profile fields (gender, unit system, age, height, weight)
  • Converting imperial inputs to metric before persisting
  • Clamping all physical values to valid physiological ranges before saving
  • Blocking completion until all required profile fields are filled with valid values
  • Calling the onComplete callback to signal the host that onboarding is finished

Invariants

Step Ordering

Steps always progress in a fixed order: "language""profile".

There is no back navigation between steps. Once the user advances to the profile step, the language step is unmounted.


Immediate Language Persistence

Language is written to storage (saveLanguage) as soon as the user taps a language card, before they tap “Continue”.

This ensures the language is available for translation even if the app is closed mid-onboarding.


Required Profile Gate

Profile completion is required at this step.

The “Get Started” action remains disabled until the user selects a gender and enters valid age, height, and weight values. The UI shows the first missing or invalid requirement so the blocked field is visible. In imperial mode, the visible feet, inches, and pounds inputs are validated against rounded imperial bounds and then clamped to canonical metric bounds on save.


Value Clamping on Save

Parsed profile values are clamped to physiological bounds before persisting:

FieldMinMax
age1090
heightCm120230
weightKg30200

Canonical Metric Storage

As in HomeScreen, all values are stored in metric units.

Imperial inputs are converted to metric at save time. Height in imperial mode is computed from feet and inches fields together.


daysActive14 Preserved from Default

The daysActive14 field is always taken from defaultProfile at this step.

It is not collected during onboarding and must be set later via the Prediction screen.


Variants

Language Step

Presents two language cards (English, Spanish) rendered as pressable radio-style selectors.

The previously saved language (if any) is pre-selected on mount via loadSavedLanguage.


Profile Step

Presents a scrollable KeyboardAvoidingView form with:

  • Unit system toggle (metric / imperial)
  • Gender selector (male / female)
  • Age, height, and weight inputs
  • Height in imperial mode uses two fields (feet + inches) with live metric sync identical to HomeScreen
  • Weight in imperial mode converts lbs → kg live as the user types

Sub-components

ComponentPurpose
LangCardPressable radio-style language selector card
SegRowLabeled row wrapping a horizontal segmented control
SegOptionIndividual option button within a SegRow
FieldRowLabeled row wrapping one or more text inputs
DividerSingle-pixel horizontal rule

Exports

LandingScreen (default)

export default function LandingScreen({ onComplete }: Props): JSX.Element

Renders the two-step onboarding flow.

Parameters

ParameterDescription
onCompleteCallback invoked after the profile is saved; signals the host to unmount the landing flow