FarmerEats is a full-featured mobile application built as part of a practical assignment for sowlab.com . It creates a direct bridge between local farmers and consumers, enabling farmers to register their business, set operating hours, upload verification documents, and manage their farm profile.
The app is built using React Native with Expo SDK 54 , integrating REST APIs, multi-step registration flows, JWT authentication, and secure local storage β all with a premium, polished design.
π― Assignment Objectives Covered
β
Splash Screen with animated intro
β
3-slide Onboarding carousel with animated dot indicators
β
Login with email/password + JWT token storage
β
5-step Farmer Registration flow with data accumulation
β
Forgot Password β OTP Verification β Reset Password
β
Home Dashboard with user stats
β
Full API integration with sowlab.com/assignment
β
Custom reusable component library
Feature
Description
Status
π JWT Authentication
Secure login with token persistence via AsyncStorage
β
Done
π 5-Step Registration
Multi-screen form with shared state via module-level object
β
Done
π± Onboarding Carousel
Horizontal FlatList with animated expanding dots
β
Done
π Forgot Password Flow
Mobile OTP β 6-digit verify β reset with strength meter
β
Done
π Document Upload
Business registration proof via expo-document-picker
β
Done
π Business Hours
Day-by-day time slot selector with schedule summary
β
Done
πΊοΈ State Dropdown
All 50 US states with custom dropdown (no external lib)
β
Done
πͺ Password Strength
Real-time visual strength indicator (weak/medium/strong)
β
Done
π¨ Custom Components
Reusable CustomInput, CustomButton, StepIndicator
β
Done
πΏ Brand Design System
Consistent colors, fonts (BeVietnamPro), spacing tokens
β
Done
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β index.js β
β registerRootComponent(App) β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββΌββββββββββββββββββββββββββββββββ
β App.js β
β ββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β Fonts Loader β β GestureHandlerRootView β β
β β (BeVietnamPro) β β βββββββββββββββββββββββ β β
β ββββββββββββββββββ β β AuthProvider β β β
β β β ββββββββββββββββββ β β β
β β β β AppNavigator β β β β
β β β ββββββββββββββββββ β β β
β β βββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββΌββββββββββββββββββββββββββββββββ
β Stack Navigator (12 screens) β
β β
β Splash β Onboarding β Login β Register(1β5) β
β ForgotPassword β OTP β ResetPassword β Home β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββΌββββββββββββββββββββββββββββββββ
β Data Layer β
β βββββββββββββββ βββββββββββββ ββββββββββββββββ β
β β AuthContext β β authApi β β registerData β β
β β (JWT token) β β (axios) β β (shared obj) β β
β βββββββββββββββ βββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββ 2.8s βββββββββββββββ swipe/skip
β SPLASH β ββββββββββββ βΆβ ONBOARDING β βββββββββββββββΆ
β πΏ β β 3 slides β
ββββββββββββ βββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LOGIN β
β email + password β POST /user/login β JWT β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
REGISTER FORGOT PASSWORD
β β
ββββββββββΌβββββββββββ ββββββββββΌβββββββββββ
β Register Step 1 β β Forgot Password β
β Personal Info β β Mobile Number β
ββββββββββ¬βββββββββββ ββββββββββ¬βββββββββββ
β β
ββββββββββΌβββββββββββ ββββββββββΌβββββββββββ
β Register Step 2 β β OTP Screen β
β Farm/Business β β 6-digit verify β
ββββββββββ¬βββββββββββ ββββββββββ¬βββββββββββ
β β
ββββββββββΌβββββββββββ ββββββββββΌβββββββββββ
β Register Step 3 β β Reset Password β
β Document Upload β β Strength meter β
ββββββββββ¬βββββββββββ βββββββββββββββββββββ
β
ββββββββββΌβββββββββββ
β Register Step 4 β
β Business Hours β
ββββββββββ¬βββββββββββ
β
ββββββββββΌβββββββββββ βββββββββββββββ
β Register Step 5 β βββββββΆβ HOME β
β Review+Submit β β Dashboard β
βββββββββββββββββββββ βββββββββββββββ
FarmerEatsApp/
β
βββ π index.js # Entry point (registerRootComponent)
βββ π App.js # Root: fonts + providers + navigator
βββ π app.json # Expo config (name, icons, splash)
βββ π babel.config.js # Babel transpiler config
βββ π package.json # Dependencies
β
βββ π assets/ # App icons, splash, adaptive icons
β
βββ π src/
β
βββ π api/
β βββ authApi.js # All REST API calls (axios)
β βββ loginUser()
β βββ registerUser()
β βββ forgotPassword()
β βββ verifyOTP()
β βββ resetPassword()
β
βββ π context/
β βββ AuthContext.js # JWT token state, login/logout
β
βββ π navigation/
β βββ AppNavigator.js # Stack navigator, screen definitions
β
βββ π theme/
β βββ colors.js # Design token: primary, secondary, etc.
β
βββ π components/ # Reusable UI components
β βββ CustomButton.js # Primary/outline/secondary variants
β βββ CustomInput.js # Input with icon, error, eye toggle
β βββ StepIndicator.js # Progress dots for registration
β
βββ π screens/ # 12 screens
βββ SplashScreen.js # Animated logo entry (2.8s)
βββ OnboardingScreen.js # 3-slide horizontal onboarding
βββ LoginScreen.js # Email/password login
βββ RegisterStep1Screen.js # Personal info + shared registerData{}
βββ RegisterStep2Screen.js # Farm/business info + US state picker
βββ RegisterStep3Screen.js # Document upload (expo-document-picker)
βββ RegisterStep4Screen.js # Business hours (day Γ time slot grid)
βββ RegisterStep5Screen.js # Review + FormData multipart submit
βββ ForgotPasswordScreen.js# Mobile number input
βββ OTPScreen.js # 6-box OTP input with auto-focus
βββ ResetPasswordScreen.js # New password + strength indicator
βββ HomeScreen.js # Dashboard with stats and quick actions
node > = 18.x
npm > = 9.x
Expo Go app on your Android/iOS device
# 1. Clone the repo (or navigate to project folder)
cd " FarmerEatsApp"
# 2. Install dependencies
npm install --legacy-peer-deps
# 3. Start Metro bundler with cleared cache
npx expo start --clear
# 4. Scan the QR code with Expo Go app
# OR press 'a' for Android, 'w' for web
Problem
Solution
White screen on Expo Go
Ensure newArchEnabled: false in app.json
babel-preset-expo not found
Run npm install babel-preset-expo --save-dev
Terminal hangs on press a
Old Expo process still running β open new terminal
Cannot find module 'worklets'
Don't use react-native-reanimated@^4.x with Expo Go
Fonts not loading
Clear cache: npx expo start --clear
Base URL: https://sowlab.com/assignment
Endpoint
Method
Description
Auth
/user/login
POST
Login with email + password
β
/user/register
POST
Register new farmer (multipart)
β
/user/forgot-password
POST
Send OTP to mobile
β
/user/verify-otp
POST
Verify 6-digit OTP
β
/user/reset-password
POST
Set new password with token
β
{
"email" : " farmer@example.com" ,
"password" : " password123" ,
"role" : " farmer" ,
"device_token" : " expo_device_token" ,
"type" : " email"
}
Register (FormData fields)
full_name, email, phone, password, role,
business_name, informal_name, address, city,
state, zip_code, business_hours (JSON string),
device_token, type, registration_proof (file)
Token
Hex
Usage
primary
#D5715B
Buttons, active states, brand
secondary
#F2C94C
Highlights, accents
tertiary
#5EA25F
Success, green badges
dark
#261C12
Body text, headings
white
#FFFFFF
Backgrounds
inputBg
rgba(38,28,18,0.08)
Input field backgrounds
error
#E53935
Error states, validation
All text uses BeVietnamPro (Google Fonts) with 4 weights:
Weight
Font Name
Usage
400
BeVietnamPro_400Regular
Body text, subtitles
500
BeVietnamPro_500Medium
Labels, secondary text
600
BeVietnamPro_600SemiBold
Links, emphasized text
700
BeVietnamPro_700Bold
Headings, buttons, brand