Docs📱 App🛠️ Technical📱 Screens & Navigation

Screens & Navigation

CalorieBeat uses Expo Router for file-based routing, providing type-safe navigation and automatic deep linking.

Bottom Tab Navigation

The main app interface uses bottom tabs for primary navigation:

1. Home Tab

Icon: Home Route: /(tabs)/index Purpose: Activity feed and dashboard

2. Analytics Tab

Icon: Bar Chart Route: /(tabs)/analytics Purpose: Progress charts and insights

3. Add Post (Center, Elevated)

Icon: Plus (Large, Elevated) Route: /(tabs)/add-post Purpose: Quick capture via camera

4. Profile Tab

Icon: User Route: /(tabs)/profile Purpose: User profile and settings

Authentication Stack

Before entering the main app, users go through authentication:

Landing Screen

Route: /

  • App introduction
  • Key features showcase
  • Sign Up / Login buttons

Login Screen

Route: /(auth)/login

  • Google Sign-In
  • Apple Sign-In
  • Email / Magic Link
  • Create Account link

Onboarding Flow

Routes: /(onboarding)/step-[1-11]

11-step personalized onboarding:

  1. Gender Selection
  2. Date of Birth
  3. Workout Frequency
  4. Referral Source
  5. Height & Weight
  6. Weight Goal
  7. Weight Loss Speed
  8. Timeframe
  9. Calorie Tracking Preference
  10. Dietary Preference
  11. Desired Weight Confirmation

Modals appear over the main interface for focused tasks:

Food Entry Modal

Route: /(tabs)/add-post/food

  • AI photo analysis or manual entry
  • Food selection and portions
  • Save to log

Workout Entry Modal

Route: /(tabs)/add-post/workout

  • AI photo analysis or manual entry
  • Exercise selection
  • Duration and intensity
  • Save to log

Settings Modal

Route: /settings

  • Theme preferences
  • Notifications
  • Privacy settings
  • Account management

Subscription Modal

Route: /subscription

  • Plan comparison
  • Payment processing
  • Subscription management

File-Based Routing

Routes are automatically generated from the app/ directory structure:

app/
├── index.tsx                      # Landing page
├── _layout.tsx                    # Root layout

├── (auth)/                        # Auth stack
│   ├── _layout.tsx               # Auth layout
│   ├── login.tsx                 # Login screen
│   └── signup.tsx                # Signup screen

├── (onboarding)/                  # Onboarding stack
│   ├── _layout.tsx               # Onboarding layout
│   ├── step-1.tsx                # Gender
│   ├── step-2.tsx                # DOB
│   ├── step-3.tsx                # Workout frequency
│   ├── step-4.tsx                # Referral
│   ├── step-5.tsx                # Height & Weight
│   ├── step-6.tsx                # Goal weight
│   ├── step-7.tsx                # Speed
│   ├── step-8.tsx                # Timeframe
│   ├── step-9.tsx                # Calorie tracking
│   ├── step-10.tsx               # Dietary preference
│   └── step-11.tsx               # Confirmation

└── (tabs)/                        # Main app tabs
    ├── _layout.tsx               # Tab layout
    ├── index.tsx                 # Home feed
    ├── analytics.tsx             # Analytics
    ├── profile.tsx               # Profile

    └── add-post/                 # Add post screens
        ├── _layout.tsx           # Add post layout
        ├── index.tsx             # Method selection
        ├── food.tsx              # Food entry
        └── workout.tsx           # Workout entry

Push Navigation

Navigate to a new screen:

import { router } from 'expo-router';
 
router.push('/analytics');

Replace Navigation

Replace current screen:

router.replace('/(tabs)');

Go Back

Return to previous screen:

router.back();

Present as modal:

router.push({
  pathname: '/settings',
  params: { presentation: 'modal' }
});

Deep Linking

Expo Router automatically handles deep links:

caloriebeat://analytics
caloriebeat://profile/edit
caloriebeat://add-post/food

Universal Links (iOS):

https://caloriebeat.com/analytics

App Links (Android):

https://caloriebeat.com/profile

Screen Transitions

Default Transitions

  • iOS: Slide from right
  • Android: Slide from bottom

Custom Animations

<Stack.Screen
  name="modal"
  options={{
    presentation: 'modal',
    animation: 'slide_from_bottom'
  }}
/>

Authentication Guard

Protects routes requiring authentication:

if (!user) {
  router.replace('/login');
  return null;
}

Onboarding Guard

Redirects incomplete onboarding:

if (!profile.onboarding_complete) {
  router.replace('/(onboarding)/step-1');
  return null;
}

Subscription Guard

Checks premium features:

if (!isPremium && requiresPremium) {
  router.push('/subscription');
  return null;
}

Tab Bar Customization

<Tabs
  screenOptions={{
    tabBarActiveTintColor: colors.primary,
    tabBarInactiveTintColor: colors.textSecondary,
    tabBarStyle: {
      backgroundColor: colors.surface,
      borderTopColor: colors.border
    }
  }}
>
  <Tabs.Screen
    name="index"
    options={{
      title: 'Home',
      tabBarIcon: ({ color }) => <Home color={color} />
    }}
  />
  {/* ... other tabs */}
</Tabs>

Header Configuration

<Stack.Screen
  name="analytics"
  options={{
    title: 'Analytics',
    headerShown: true,
    headerStyle: {
      backgroundColor: colors.surface
    },
    headerTitleStyle: {
      color: colors.text
    }
  }}
/>