8000
Skip to content

ivanmolto/pwrna

Repository files navigation

Algorand Repositories Explorer

A React Native mobile application assignment built with Expo that allows users to browse, search, and favorite GitHub repositories from Algorand-related organizations (Pera Wallet, Algorand Foundation, and Algorand).

πŸš€ Key Features

Core Functionality

  • Repository Browsing: View repositories from three Algorand organizations with details including stars, forks, language, and descriptions
  • Search & Filter: Real-time search across repository names and descriptions, with filter chips for organization-based filtering
  • Pull-to-Refresh: Sync repositories from GitHub by pulling down on the repositories list
  • Favorites System: Save favorite repositories that sync across devices (requires authentication)
  • Repository Details: View detailed information about each repository with an option to open it on GitHub
  • Offline Support: Full offline functionality with cached data persistence using React Query

User Experience

  • Authentication: Secure sign-in/sign-up using Clerk with email verification support
  • Dark/Light Mode: Automatic theme switching based on system preferences
  • Offline Indicators: Visual banners to inform users about network connectivity status
  • Optimized Performance: Uses FlashList for efficient rendering of large lists
  • Haptic Feedback: Enhanced user interactions with haptic feedback on tab navigation

πŸ“Έ Screenshots

The image files referenced below are only for documentation and are not used by the app bundle.

Flow

πŸ›  Tech Stack

Core Framework

  • React Native (0.81.5) with Expo (~54.0.29)
  • Expo Router for file-based routing
  • TypeScript for type safety

State Management & Data Fetching

  • TanStack Query (React Query) for server state management
  • AsyncStorage Persistence for offline data caching
  • Offline-First Architecture: Data is cached and available offline

Backend Services

  • Supabase: PostgreSQL database for repositories and favorites
  • Supabase Edge Functions: Serverless functions for syncing repositories from GitHub
  • Clerk: Authentication and user management
  • GitHub API: Repository data synchronization (via Edge Function or sync script)

UI & Navigation

  • React Navigation: Tab and stack navigation
  • FlashList: High-performance list rendering
  • Expo Image: Optimized image loading
  • Expo Web Browser: In-app browser for external links

Additional Libraries

  • React Native NetInfo: Network connectivity monitoring
  • Expo Haptics: Tactile feedback
  • Expo Secure Store: Secure token storage

πŸ“± Architecture Highlights

Offline-First Design

The app is designed to work seamlessly offline:

  • Repository data is cached using React Query with AsyncStorage persistence
  • Cache is valid for 5 minutes (staleTime) and kept for 24 hours (gcTime)
  • Network requests use networkMode: "offlineFirst" to prioritize cached data
  • Client-side filtering ensures search and filters work without network connectivity

Authentication Flow

  • Uses Clerk for authentication with secure token management
  • Supabase RLS (Row Level Security) ensures users can only access their own favorites
  • Token caching with Expo Secure Store for persistent sessions

Performance Optimizations

  • FlashList: Replaces FlatList for better performance with large datasets
  • Debounced Search: Search input is debounced (300ms) to reduce API calls
  • Memoized Filtering: Client-side filtering uses useMemo to prevent unnecessary recalculations
  • Image Optimization: Uses Expo Image for efficient image loading and caching

Component Architecture

  • Themed Components: Reusable components that adapt to light/dark themes
  • Custom Hooks: Encapsulated logic for repositories, favorites, network status, and more
  • Type Safety: Full TypeScript coverage with strict typing
  • Edge Functions: Serverless functions for GitHub synchronization
  • Unit Testing: Jest setup for testing utility functions

πŸ“‚ Project Structure

pwrna/
β”œβ”€β”€ app/                    # Expo Router file-based routing
β”‚   β”œβ”€β”€ (auth)/            # Authentication screens (sign-in, sign-up)
β”‚   β”œβ”€β”€ (tabs)/            # Main app screens (repositories, favorites)
β”‚   └── repository/[id].tsx # Repository detail screen
β”œβ”€β”€ components/            # Reusable UI components
β”‚   β”œβ”€β”€ themed/           # Theme-aware components
β”‚   β”œβ”€β”€ repo-card.tsx     # Repository card component
β”‚   β”œβ”€β”€ filter-chips.tsx  # Organization filter chips
β”‚   └── ...
β”œβ”€β”€ hooks/                 # Custom React hooks
β”‚   β”œβ”€β”€ use-repositories.ts
β”‚   β”œβ”€β”€ use-sync-repositories.ts  # Hook for syncing repos via Edge Function
β”‚   β”œβ”€β”€ use-favorites.ts
β”‚   β”œβ”€β”€ use-network-status.ts
β”‚   └── ...
β”œβ”€β”€ utils/                 # Utility functions
β”‚   β”œβ”€β”€ supabase.ts       # Supabase client setup
β”‚   β”œβ”€β”€ query-client.ts   # React Query configuration
β”‚   β”œβ”€β”€ storage.ts        # AsyncStorage adapter for caching
β”‚   β”œβ”€β”€ online-manager.ts # Network status management
β”‚   β”œβ”€β”€ transform-repository.ts # Repository transformation utility
β”‚   └── __tests__/         # Unit tests
β”‚       └── transform-repository.test.ts
β”œβ”€β”€ types/                 # TypeScript type definitions
β”œβ”€β”€ constants/             # App constants (themes)
β”œβ”€β”€ supabase/              # Supabase configuration
β”‚   β”œβ”€β”€ functions/         # Edge Functions
β”‚   β”‚   └── sync-repos/    # GitHub sync Edge Function
β”‚   └── migrations/        # Database migrations
└── scripts/               # Build and sync scripts
    └── sync-repos.ts     # GitHub to Supabase sync script (local)

πŸ”‘ Important React Native Patterns

1. File-Based Routing (Expo Router)

  • Uses Expo Router's file-based routing system
  • Route groups (auth) and (tabs) organize navigation structure
  • Dynamic routes like repository/[id].tsx for detail views

2. Custom Hooks Pattern

  • Business logic separated into reusable hooks
  • Examples: useRepositories(), useFavorites(), useDebounce()
  • Promotes code reusability and testability

3. Theme System

  • Centralized theme configuration in constants/theme.ts
  • Theme-aware components using useThemeColor hook
  • Automatic dark/light mode detection

4. Query Management

  • React Query for all server state
  • Query key factories for type-safe cache management
  • Optimistic updates and cache invalidation strategies

5. Safe Area Handling

  • Uses react-native-safe-area-context for proper screen insets
  • Handles notches, status bars, and navigation bars correctly

6. Performance Optimization

  • FlashList for efficient list rendering
  • Image optimization with Expo Image
  • Memoization for expensive computations

πŸš€ Getting Started

Prerequisites

  • Node.js (v18 or later)
  • npm or yarn
  • Expo CLI (npm install -g expo-cli)
  • iOS Simulator (for iOS) or Android Studio (for Android)

Installation

  1. Clone the repository

    git clone <repository-url>
    cd pwrna
  2. Install dependencies

    npm install
  3. Set up environment variables Create a .env file in the root directory:

    EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_key
    EXPO_PUBLIC_SUPABASE_URL=your_supabase_url
    EXPO_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
  4. Start the development server

    npx expo start
  5. Run on your device

    • Press i for iOS simulator
    • Press a for Android emulator
    • Scan QR code with Expo Go app (limited functionality)

Sync Repository Data

There are two ways to sync repository data:

Option 1: Pull-to-Refresh (Recommended)

Simply pull down on the repositories list in the app. This triggers the Supabase Edge Function to sync data from GitHub.

Option 2: Local Sync Script

To populate the Supabase database with GitHub repository data locally:

npm run sync-repos

This script fetches repositories from GitHub and syncs them to Supabase.

Option 3: Supabase Edge Function

Deploy and use the Edge Function directly:

# Deploy the function
supabase functions deploy sync-repos

# Set required secrets
supabase secrets set SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
supabase secrets set GITHUB_TOKEN=your_github_token

πŸ”§ Development Scripts

  • npm start - Start Expo development server
  • npm run android - Start on Android emulator
  • npm run ios - Start on iOS simulator
  • npm run web - Start web version
  • npm run sync-repos - Sync GitHub repositories to Supabase (local script)
  • npm test - Run unit tests with Jest
  • npm run test:watch - Run tests in watch mode
  • npm run lint - Run ESLint

πŸ“ Key Implementation Details

Offline Support

  • All repository data is cached locally using React Query with AsyncStorage
  • Network status is monitored and displayed to users
  • Favorites are stored in Supabase but cached locally for offline access

Authentication

  • Clerk handles authentication with secure token storage
  • Supabase RLS policies ensure data security
  • User-specific favorites are isolated per user account

Data Flow

  1. Repository data is synced from GitHub to Supabase via:
    • Supabase Edge Function (recommended, triggered by pull-to-refresh)
    • Local sync script (npm run sync-repos)
  2. App fetches from Supabase with React Query
  3. Data is cached locally for offline access
  4. Client-side filtering and search work on cached data
  5. Pull-to-refresh triggers sync and refreshes the cache

Testing

  • Unit Tests: Jest is configured for unit testing
    • Run tests: npm test
    • Watch mode: npm run test:watch
    • Tests are located in utils/__tests__/
    • Example: transform-repository.test.ts tests the repository transformation utility

πŸ“„ License

This project is an open-source project with MIT License.

0