Skip to main content

KA26 Mobile App — Features & Architecture

Overview

React Native (Expo SDK 54) mobile application that mirrors the KA26 web app. Uses Expo Router for file-based navigation, consumes the same production API (https://ka26.shop), and shares JWT authentication with the web platform.


Architecture

LayerTechnology
FrameworkReact Native + Expo SDK 54
NavigationExpo Router (file-based)
AuthJWT stored in SecureStore (ka26_consumer_token)
API ClientCustom ApiClient class (src/lib/api.ts)
StateReact hooks + AsyncStorage for persistence
Translations6-language i18n system (src/contexts/LanguageContext.tsx)
TestingJest + React Native Testing Library (unit/integration), Vitest (code integrity)

Directory Structure

mobile/
├── app/ # Screens (Expo Router file-based routing)
│ ├── (tabs)/ # Bottom tab screens
│ │ ├── shop.tsx # Shop: stores + ads marketplace
│ │ ├── requests.tsx # Community requests feed
│ │ ├── reels.tsx # Video reels feed + upload
│ │ ├── eats.tsx # Restaurant ordering
│ │ └── profile.tsx # User profile + account
│ ├── restaurant/[id].tsx # Restaurant detail + checkout
│ ├── store/[id].tsx # Store detail page
│ ├── product/[id].tsx # Product detail page
│ ├── order/[id].tsx # Order tracking
│ ├── auth.tsx # Login / signup
│ ├── settings.tsx # App settings
│ ├── edit-profile.tsx # Edit profile + services
│ ├── language.tsx # Language selection
│ ├── feedback.tsx # Bug/feature feedback form
│ └── ... (15 more screens)
├── src/
│ ├── contexts/ # React contexts
│ │ ├── AuthContext.tsx # JWT auth + user state
│ │ └── LanguageContext.tsx # i18n translations
│ ├── lib/ # Utilities
│ │ ├── api.ts # API client with auth headers
│ │ ├── constants.ts # Colors, API URL
│ │ └── notifications.ts # Push notification setup
│ └── locales/ # Translation JSON files (6 languages)
├── __tests__/ # Jest tests (unit + integration)
└── tests/ # Vitest code integrity tests

Modules & Features

1. Shop (shop.tsx)

  • Stores Tab: Horizontal card layout with store image (110x110), name, category badge, open/closed status, address, product count, delivery info, smart signals
  • Ads Tab: 2-column clean card grid with shadow, tappable cards, image (4:3 aspect ratio), seller avatar, category badge, FOR RENT overlay, image count badge
  • Filters — Two rows matching web:
    • Row 1: "All Ads" / "My Ads" toggle (authenticated users only)
    • Row 2: Category chips (All, Electronics, Household, Books, Vehicles, Property Buy, Property Rent) — only shown in "All Ads" mode
  • My Ads: Fetches user's own listings from /api/ads
  • Search: Global search across products and stores
  • Branding: Logo — KA (red) 26 (black) + "Shop"

2. Eats — ARCHIVED 2026-04-17

Eats vertical removed from mobile launch scope. Source code preserved in src/_archived/eats-mobile/eats.tsx. To restore: copy back to mobile/app/(tabs)/eats.tsx, re-add the <Tabs.Screen name="eats"> entry in _layout.tsx, and bump tab count test from 4 to 5.

2-original. Eats (eats.tsx + restaurant/[id].tsx) — pre-archive description

  • Restaurant Listing: Cards with image, cuisine badge, open/closed status, delivery fee, ratings, hours, "orders today" count
  • Location Management: City picker (Gadag, Hubli, Dharwad, Belgaum, Bangalore) with AsyncStorage persistence, coordinates passed to intelligence feed API
  • Cuisine Filters: Chip-based filtering (All, South Indian, North Indian, Chinese, Fast Food, Biryani, Sweets, Bakery)
  • Restaurant Detail: Full menu with sections, popular items (deduplicated — shown only in "🔥 Popular" section, not repeated in category), category filter tabs below restaurant info that scroll to sections on tap
  • Checkout: Customer info, delivery address (with saved addresses from API), special instructions
  • Payment: Cash on Delivery + UPI payment (PhonePe, GPay, Paytm deep links, 5-minute timer, UTR confirmation)
  • Keyboard handling: All modals (checkout, UPI) wrapped with KeyboardAvoidingView + keyboardShouldPersistTaps so inputs aren't hidden by keyboard
  • Order Success: Order number display, 60-second edit window for address/instructions changes, cancel option
  • Location Coordinates: Passed with orders for delivery radius validation

3. Reels (reels.tsx + reels-profile.tsx)

  • Feed: Vertical swipe video feed with play/pause, likes, comments, share
  • Referral Gate: Upload requires 2+ referrals; shows progress bar and share button for referral code
  • Comments: Real-time comment feed with post/delete
  • Report System: Flag button with 5 predefined reasons + details field
  • Creator Profile: Grid of user's reels, follower stats
  • Reel Management: Long-press menu on own reels for hide/unhide and delete with confirmation

Post Reel Flow (Instagram-Style) — LOCKED UI ⚠️

DO NOT modify the post reel UI layout, step flow, or component structure. This design was user-approved on 2026-04-08 and is protected by 25+ code integrity tests.

Flow: select-videodetails ("New reel") → post (with optional edit-video via "Trim video" row)

Step 1 — Select Video (full-screen playback):

  • Video plays instantly full-screen after selection (expo-av <Video>, NOT VideoThumbnails)
  • Close (✕) button top-left, duration badge top-right
  • Drafts banner overlaid at top when drafts exist (Resume / Delete per draft)
  • Bottom bar: "Change" (re-pick) | "Next →" (pink CTA)

Step 2 — New Reel (Instagram-style details page):

  • Header: ← arrow + "New reel" title
  • Centered video thumbnail (55% screen width, 9:16 aspect ratio, rounded 16px) with "Edit cover" overlay
  • Borderless caption input (500 char limit, character counter appears after typing)
  • Horizontal chips row: # Hashtags toggle + emoji quick-picks (🔥 ❤️ 😍 🎉 👀 💯)
  • Hashtag suggestions panel (expandable): #KA26, #Gadag, #LocalBusiness, #FoodReview, etc.
  • Clean action rows (icon + label + chevron):
    • Tag products → navigates to tag-type step (store products or restaurant menu items, max 5 tags)
    • Add location → Alert picker with city list (Gadag, Hubli, Dharwad, Belgaum, Bangalore, Haveri) + quick-pick chips inline
    • Visibility → toggle Public (globe icon) / Followers only (people icon) with badge
    • Trim video → navigates to edit-video step (shows current duration)
  • Tagged items shown as horizontal scrollable chips with remove (✕) button
  • Earnings info banner (green): "Earn 1% on every order from your tagged products within 24h of viewing" (shown when items tagged)
  • Bottom bar: "Save Draft" (gray) | "Post Reel" (pink CTA) — upload progress shown inline

Draft System:

  • Saves to AsyncStorage key ka26_reel_drafts (max 5 drafts)
  • Draft includes: videoUri, caption, taggedItems, coverFrameUri, trimStartMs/EndMs, videoDurationMs, visibility, location, savedAt
  • Resume draft restores all state; delete draft with confirmation
  • Discard dialog offers "Save Draft" option

Trim Video (edit-video step):

  • Video info card: filename, duration, size estimate
  • Start/End time controls with ±1s increment/decrement buttons
  • Duration display, reset button, tip about server-side thumbnails
  • Back navigates to details (not select-video)

Crash Prevention Architecture:

  • VideoThumbnails.getThumbnailAsync() (native FFmpeg) is NEVER called in the post flow
  • Background feed thumbnail generation pauses when postStep !== null
  • Video playback uses expo-av <Video> component which is safe (different from VideoThumbnails)
  • All native decoder-intensive operations have 200ms+ delays between calls

Creator Economy (Redirect Tracking):

  • "Shop Now" floating pill on reels with tagged items (pulsing animation)
  • Tap tracks redirect via POST /api/reels/{id}/redirect with fingerprint + productId/menuItemId
  • Orders within 24hr attribution window earn creator 1% commission
  • Earnings: pending → confirmed (on delivery) → credited to wallet
  • Cancellations reverse earnings atomically
  • Self-purchase prevention built in

4. Requests (requests.tsx)

  • Feed: Community request cards with title, description, category, location
  • Filters: All / My Requests / I Helped tabs
  • Sorting: Newest / Nearest with location awareness
  • Support Flow: "I Can Help" compact pill button (not full-width), chat threads with message limits
  • Post Request: Title, details, category, location, phone (optional)
  • Provider Notifications: Auto-notifies matching service providers

5. Profile (profile.tsx)

  • Authenticated View: User photo, name, alias, stats (orders, stores, requests)
  • Account Activity: Quick links to Orders, My Requests, Subscribed Stores, Health Records
  • Guest View: Sign-in prompt with feature overview
  • Navigation: Settings, Edit Profile, My QR, Contributions, Invite, My Ads

6. Edit Profile (edit-profile.tsx)

  • Personal Info: Name, phone, bio with character limit
  • Photo Upload: Image picker with crop, upload to API
  • Service Categories: 32 categories organized in 6 groups (Transport, Home & Building, Appliance Repair, Agriculture, Personal Services, Health & General), multi-select picker modal
  • Service Area: Text input for service coverage
  • Email Verification: 6-digit code flow
  • Password Change: Current + new password form

7. Language System (language.tsx + LanguageContext.tsx)

  • 6 Languages: English, Kannada, Hindi, Telugu, Tamil, Sanskrit
  • Full Translation: 330+ keys covering all UI text
  • Real-time Switching: Language changes instantly update all screens
  • Persistent: Saved to AsyncStorage, restored on app launch
  • Template Parameters: Support for dynamic values (e.g., {km}, {count})
  • Fallback Chain: Selected language -> English -> key itself

8. Settings (settings.tsx)

  • Edit Profile, My QR Code, Language, Feedback, Notifications toggle
  • Seller dashboard link, logout

9. Authentication (auth.tsx + AuthContext.tsx)

  • Login / Signup with email + password
  • JWT token stored in SecureStore
  • Auto-refresh on app launch
  • Guest mode for browsing

10. Orders (orders.tsx + order/[id].tsx)

  • Order history list with status badges
  • Order detail with items, totals, status timeline
  • Real-time status tracking

11. Other Screens

  • My QR (my-qr.tsx): Personal QR code for doctor prescriptions
  • Feedback (feedback.tsx): Bug report / feature request / general feedback with screenshot attachment
  • Health Records (health-records.tsx): Prescription history linked via QR
  • Subscribed Stores (subscribed-stores.tsx): Managed store subscriptions
  • My Ads (my-ads.tsx): Consumer's resale/rental listings
  • Invite (invite.tsx): Referral code sharing
  • Contributions (contributions.tsx): Community contribution history

Testing — 544 tests across 15 suites

Jest + React Native Testing Library (103 tests, 8 suites)

  • Unit tests: API client, helper functions
  • Integration tests: Auth flow (login, register, token refresh), eats ordering (COD + UPI), store ordering (COD + UPI, subscriptions), reels (referral gate, likes, comments, report, management), post-reel flow (video upload, cover frame, tags, drafts, redirects), profile (contributions, health records, requests, feedback, QR)
  • Run: npx jest --forceExit --detectOpenHandles

Vitest — Code Integrity + API (441 tests, 7 suites)

  • screen-completeness.test.ts (84 tests): All 28 screens exist, default exports, tab nav, feature presence per screen
  • ui-consistency.test.ts (61 tests): CTA color uniformity (blue #2563EB), SafeAreaView, filter chip visibility, ad card layout
  • mobile-code-integrity.test.ts (164 tests): API endpoints, auth handling, routing, UPI flow, settings, features, Post Reel UI Lock (20 tests) — prevents any modification to the approved Instagram-style post reel layout
  • api-integration.test.ts (31 tests): Live API tests against production
  • api-response-shapes.test.ts (32 tests): Response shape validation for all endpoints
  • api-endpoints-auth.test.ts (35 tests): Auth-required endpoints return 401
  • post-deploy-smoke.test.ts (34 tests): Post-deployment health + data verification
  • Run: npx vitest run

CI/CD Integration

  • Mobile tests run in GitHub Actions before every deployment
  • Both web (1334 tests) and mobile (482 tests) must pass before build proceeds
  • Pipeline: test (web) + test-mobile → build → staging → smoke test → production

Build

Local APK (no EAS credits needed)

cd mobile
npx expo prebuild --platform android --clean
cd android && ./gradlew assembleRelease
# Output: android/app/build/outputs/apk/release/app-release.apk

Development

npx expo start # Start dev server
npx expo run:android # Run on connected device