Skip to content

6ixline/react-native-product-catalogue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“¦ Spare Parts Catalogue - React Native App

A production-grade mobile app for browsing, searching and enquiring about spare parts

React Native Expo TypeScript NativeWind Zustand TanStack Query

A fully-featured, type-safe React Native app built with Expo SDK 54 and Expo Router. Designed for field teams and dealers to browse a live spare parts catalogue, raise enquiries, and manage their account - with enterprise-grade security features baked in.


πŸ“‹ Table of Contents


✨ Features

πŸ“± Core App

  • 3-slide onboarding carousel with pagination dots and smooth snap scrolling
  • Email + password login with show/hide toggle and client-side validation
  • Forgot password flow with reset via email
  • Dashboard - 4-card grid for quick access to all key features
  • Product search - keyword-based spare parts search with results
  • Product detail - full part info with image viewer
  • Favorites - save and manage preferred parts
  • Enquiry system - raise product enquiries and track history
  • User profile - view and manage account details

πŸ”„ Smart Data Layer

  • Silent token refresh - Axios interceptor silently renews expired JWTs without logging the user out
  • Zustand auth store - persisted to AsyncStorage, rehydrated on app launch
  • TanStack Query - caching, background refetch and stale-time configuration per query
  • Offline detection - NoInternet screen shown instantly on connection loss, TanStack Query onlineManager synced with NetInfo

πŸ”’ Security Features (see full section below)

  • Screenshot and screen recording blocked on Android
  • Screen recording blocked on iOS (Apple policy prevents blocking screenshots)
  • Custom native Expo plugins for Android FLAG_SECURE and iOS secure layer
  • Portrait orientation locked to prevent layout exploits

πŸš€ OTA Updates

  • UpdateManager component checks for Expo OTA updates every hour
  • Animated modal with progress bar when an update is available
  • One-tap download and apply - app reloads automatically
  • Skipped safely in development mode

πŸ› οΈ Tech Stack

Category Technology Purpose
Framework React Native 0.81 + Expo SDK 54 Cross-platform mobile
Language TypeScript 5 Full type safety
Routing Expo Router v6 File-based navigation
Styling NativeWind v4 (Tailwind CSS) Utility-first styling
State Zustand v5 Global auth state with persistence
Data Fetching TanStack Query v5 Server state, caching, background sync
HTTP Axios API calls + JWT interceptor
Storage AsyncStorage Token + auth state persistence
Updates expo-updates OTA update delivery
Security expo-screen-capture Screenshot/recording prevention
Network @react-native-community/netinfo Online/offline detection
Images expo-image + react-native-image-viewing Optimised image rendering + viewer

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    App Entry (_layout.tsx)                    β”‚
β”‚                                                              β”‚
β”‚  SecureScreen β†’ QueryClientProvider β†’ AuthProvider β†’ Stack  β”‚
β”‚  (screen protection)  (TanStack Q)    (auth state)  (nav)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β–Ό                  β–Ό                  β–Ό
   Public Screens      ProtectedRoute      UpdateManager
   /index (onboarding) checks Zustand      checks for OTA
   /login             store on mount       every 1 hour
   /forgot-password   β†’ redirects if
                        not authenticated
                             β”‚
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β–Ό                         β–Ό
         Screen Component          Custom Hook
         (UI only)                 (TanStack Query)
                                         β”‚
                                         β–Ό
                                  Service Function
                                  (Axios typed call)
                                         β”‚
                                         β–Ό
                                  axiosInstance
                              (base URL + JWT header
                               + silent refresh on 401)
                                         β”‚
                                         β–Ό
                               REST API Backend

Key patterns:

  • File-based routing via Expo Router - screens are just files in /app
  • Zustand store initialized from AsyncStorage on first load (onRehydrateStorage)
  • Service layer - typed Axios functions, never called directly from components
  • Silent refresh - 401 response triggers token refresh, original request retried automatically

πŸ“ Project Structure

app/                          # Expo Router screens (file = route)
β”œβ”€β”€ _layout.tsx               # Root layout - providers, security wrappers, nav stack
β”œβ”€β”€ index.tsx                 # Onboarding (3-slide carousel)
β”œβ”€β”€ login.tsx                 # Email + password login
β”œβ”€β”€ forgot-password.tsx       # Password reset flow
β”œβ”€β”€ dashboard.tsx             # Home - 4-card grid (protected)
β”œβ”€β”€ search.tsx                # Keyword product search (protected)
β”œβ”€β”€ seach-limited.tsx         # Limited/guest search view
β”œβ”€β”€ product.tsx               # Product detail + image viewer (protected)
β”œβ”€β”€ favorites.tsx             # Saved parts list (protected)
β”œβ”€β”€ enquiries.tsx             # Enquiry history (protected)
β”œβ”€β”€ enquiry-detail.tsx        # Single enquiry detail (protected)
β”œβ”€β”€ profile.tsx               # User profile (protected)
└── help.tsx                  # Help & support (protected)

src/
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ AuthProvider.tsx       # Auth state initializer on app start
β”‚   β”œβ”€β”€ ProtectedRoute.tsx     # Route guard - redirects to /login if not authed
β”‚   β”œβ”€β”€ Button.tsx             # Reusable button with variants
β”‚   β”œβ”€β”€ EnquiryBottomSheet.tsx # Bottom sheet for raising enquiries
β”‚   β”œβ”€β”€ NoInternet.tsx         # Full-screen offline indicator
β”‚   β”œβ”€β”€ UpdateManager.tsx      # OTA update checker + animated modal
β”‚   β”œβ”€β”€ SecureScreen.tsx       # Blocks screenshots via expo-screen-capture
β”‚   β”œβ”€β”€ SecureScreenPass.tsx   # Secondary screen protection layer
β”‚   β”œβ”€β”€ IOSScreenProtection.tsx
β”‚   β”œβ”€β”€ CompleteIOSProtection.tsx
β”‚   └── icons/                 # SVG icon components (Search, Save, Profile, etc.)
β”‚
β”œβ”€β”€ hooks/                     # TanStack Query custom hooks
β”‚   β”œβ”€β”€ useAuth.ts             # Login, logout, profile fetch mutations
β”‚   β”œβ”€β”€ useProducts.ts         # Product listing + search
β”‚   β”œβ”€β”€ useFavorites.ts        # Add/remove/list favorites
β”‚   β”œβ”€β”€ useEnquiries.ts        # Enquiry list + raise new
β”‚   └── useForgotPassword.ts   # Password reset flow
β”‚
β”œβ”€β”€ services/                  # Typed Axios API call functions
β”‚   β”œβ”€β”€ api.ts                 # Axios instance + JWT interceptor + silent refresh
β”‚   β”œβ”€β”€ userService.ts         # Login, logout, profile
β”‚   β”œβ”€β”€ productService.ts      # Product search + detail
β”‚   β”œβ”€β”€ favoriteService.ts     # Favorites CRUD
β”‚   β”œβ”€β”€ enquiryService.ts      # Enquiry list + create
β”‚   └── passwordResetService.ts
β”‚
β”œβ”€β”€ store/
β”‚   └── authStore.ts           # Zustand store - user, token, refreshToken (persisted)
β”‚
β”œβ”€β”€ types/                     # TypeScript interfaces
β”‚   β”œβ”€β”€ auth.ts
β”‚   β”œβ”€β”€ product.ts
β”‚   β”œβ”€β”€ enquiry.ts
β”‚   β”œβ”€β”€ favorite.ts
β”‚   └── index.ts
β”‚
β”œβ”€β”€ constants/
β”‚   β”œβ”€β”€ config.ts              # API base URL
β”‚   β”œβ”€β”€ onboarding.ts          # Onboarding slide data
β”‚   β”œβ”€β”€ color.ts               # Brand color tokens
β”‚   └── version.ts             # App version constant
β”‚
└── plugins/
    β”œβ”€β”€ withSecureFlag.js      # Custom Expo plugin - Android FLAG_SECURE
    └── withSecureFlagiOS.js   # Custom Expo plugin - iOS secure layer

πŸ“² Screens & Navigation

Screen Route Auth Description
Onboarding / ❌ 3-slide intro carousel with CTA
Login /login ❌ Email + password, forgot password link
Forgot Password /forgot-password ❌ Password reset via email
Dashboard /dashboard πŸ”’ 4-card home grid
Search /search πŸ”’ Keyword spare parts search
Product Detail /product πŸ”’ Full part info + image viewer
Favorites /favorites πŸ”’ Saved parts list
Enquiries /enquiries πŸ”’ Enquiry history
Enquiry Detail /enquiry-detail πŸ”’ Single enquiry view
Profile /profile πŸ”’ User account details
Help & Support /help πŸ”’ Support information

πŸ”’ = Protected by ProtectedRoute component - unauthenticated users are redirected to /login


πŸ”’ Security Features

This app implements multiple layers of screen protection to prevent data leaks through screenshots or screen recording:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Security Stack                          β”‚
β”‚                                                          β”‚
β”‚  1. SecureScreen          expo-screen-capture            β”‚
β”‚     └─ preventScreenCaptureAsync() on mount              β”‚
β”‚                                                          β”‚
β”‚  2. SecureScreenPass      Secondary protection layer     β”‚
β”‚                                                          β”‚
β”‚  3. CompleteIOSProtection iOS-specific secure view       β”‚
β”‚                                                          β”‚
β”‚  4. IOSScreenProtection   Additional iOS layer           β”‚
β”‚                                                          β”‚
β”‚  5. withSecureFlag.js     Native plugin β†’ Android        β”‚
β”‚     └─ Sets FLAG_SECURE   WindowManager flag             β”‚
β”‚                                                          β”‚
β”‚  6. withSecureFlagiOS.js  Native plugin β†’ iOS            β”‚
β”‚     └─ Secure UITextField layer                          β”‚
β”‚                                                          β”‚
β”‚  7. Portrait lock         ScreenOrientation.lockAsync()  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Platform Screenshots Screen Recording
Android βœ… Blocked βœ… Blocked
iOS ⚠️ Not blockable (Apple policy) βœ… Blocked

πŸš€ Getting Started

Prerequisites

  • Node.js v18+
  • Expo CLI - npm install -g expo-cli
  • Expo Go app on device or Android/iOS emulator

Installation

# 1. Clone the repository
git clone https://github.com/6ixline/react-native-product-catalogue.git
cd react-native-parts-catalogue

# 2. Install dependencies
npm install

# 3. Start the Expo development server
npx expo start

Then press a for Android emulator or i for iOS simulator, or scan the QR code with Expo Go.


πŸ”§ Environment Variables

Update src/constants/config.ts with your API URL:

export const BASE_URL = "https://your-api-domain.com";
export const API_BASE_URL = 'https://your-api-domain.com/api';

πŸ“¦ Build & Deploy

# Build for Android (APK preview)
eas build --platform android --profile preview

# Build for iOS
eas build --platform ios --profile preview

# OTA update (no store submission needed)
eas update --branch production --message "your update message"

πŸ”— Related Project

This app connects to the Product Catalog REST API for all data:

πŸ”§ nodejs-express-rest-api - Node.js + Express 5 + MySQL backend with multi-role JWT auth, product catalog, enquiry system and bulk Excel import.


πŸ“„ License

This project is open source and available under the MIT License.


Built with ❀️ using React Native & Expo

⬆ Back to top

About

Production-ready React Native app built with Expo SDK 54, TypeScript & NativeWind - spare parts catalogue with JWT auth, silent token refresh, OTA updates and enterprise screen security

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors