LandingScreen.tsx
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
onCompletecallback 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:
| Field | Min | Max |
|---|---|---|
age | 10 | 90 |
heightCm | 120 | 230 |
weightKg | 30 | 200 |
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
| Component | Purpose |
|---|---|
LangCard | Pressable radio-style language selector card |
SegRow | Labeled row wrapping a horizontal segmented control |
SegOption | Individual option button within a SegRow |
FieldRow | Labeled row wrapping one or more text inputs |
Divider | Single-pixel horizontal rule |
Exports
LandingScreen (default)
export default function LandingScreen({ onComplete }: Props): JSX.Element
Renders the two-step onboarding flow.
Parameters
| Parameter | Description |
|---|---|
onComplete | Callback invoked after the profile is saved; signals the host to unmount the landing flow |