Skip to content

beatlecz/etnetera-performance-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sports Performance Tracker

A modular React Native application for tracking sports performances, built with Expo and TypeScript.

Overview

This project demonstrates a reusable, configuration-driven module for recording and managing sports performances. The module can be easily integrated into other React Native applications.

Key Features

  • Performance Tracking: Record sports performances with title, date, and optional metrics (distance, duration, heart rate, notes)
  • Configuration-Driven: UI and form fields controlled by validated configuration
  • Type-Safe: Full TypeScript with Zod schema validation
  • Modular Architecture: Separated module that can be reused in other apps
  • Settings UI: Dedicated configuration screen for customizing fields and display
  • Animated: Smooth transitions using React Native Reanimated
  • Internationalized: Support for multiple languages (EN, CS)
  • Tested: Unit tests for core logic with 70%+ coverage goal

Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js: v18 or later
  • npm: v9 or later (or yarn)
  • Expo CLI: Install globally with npm install -g expo-cli
  • iOS Simulator (Mac only) or Android Emulator or Expo Go app on your device

Installation

1. Clone the repository (if applicable)

git clone <repository-url>
cd etnetera-performance-app

2. Install dependencies

npm install

This will install all required dependencies including:

  • React Native and Expo packages
  • Zod for validation
  • React Hook Form for form management
  • i18next for internationalization
  • Testing libraries (Jest, React Native Testing Library)

Running the Application

Start the Expo Development Server

npm start

This will start the Expo development server and display a QR code in your terminal.

Run on Different Platforms

iOS (Mac only)

npm run ios

This will open the app in the iOS Simulator.

Android

npm run android

This will open the app in the Android Emulator.

Web

npm run web

This will open the app in your default web browser.

Physical Device

  1. Install the Expo Go app from the App Store (iOS) or Play Store (Android)
  2. Scan the QR code displayed in your terminal
  3. The app will load on your device

Project Structure

etnetera-performance-app/
├── app/                        # Expo Router app directory
│   ├── index.tsx              # Main screen - Performances list with FAB
│   ├── performance/
│   │   └── [id].tsx           # Add/edit form modal
│   ├── settings.tsx           # Settings modal
│   └── _layout.tsx            # Root layout with providers and modal routes
├── modules/                    # Reusable modules
│   └── performance-tracker/   # Performance tracking module
│       ├── components/        # UI components
│       ├── context/           # React Context providers
│       ├── hooks/             # Custom hooks
│       ├── schemas/           # Zod validation schemas
│       ├── types/             # TypeScript type definitions
│       ├── utils/             # Utility functions
│       ├── locales/           # i18n translation files
│       ├── __tests__/         # Unit tests
│       └── index.ts           # Public API exports
├── docs/                       # Documentation
│   ├── app_spec.pdf           # Original specification
│   ├── PRD.md                 # Product Requirements Document
│   └── ARCHITECTURE.md        # Architecture documentation
├── CLAUDE.md                   # Claude Code guidance
├── package.json
├── tsconfig.json
└── jest.config.js

Available Scripts

Development

  • npm start - Start the Expo development server
  • npm run ios - Run on iOS Simulator
  • npm run android - Run on Android Emulator
  • npm run web - Run in web browser

Code Quality

  • npm run lint - Run ESLint to check code quality
  • npm test - Run unit tests
  • npm run test:watch - Run tests in watch mode
  • npm run test:coverage - Run tests with coverage report

Other

  • npm run reset-project - Reset the project to a clean state

Usage

1. Viewing Performances

  • Launch the app
  • The main screen shows all recorded performances
  • Tap any performance to edit it

2. Adding a Performance

  • Tap the floating + button at the bottom center of the screen
  • A modal will open with the form
  • Fill in the required fields (Title, Date)
  • Fill in optional fields if enabled (Distance, Duration, Heart Rate, Notes)
  • Tap Save to create the performance

3. Editing a Performance

  • Tap an existing performance from the list
  • The edit modal will open
  • Update any fields
  • Tap Save to update

4. Configuring Fields

  • Tap the gear icon in the top right corner
  • Settings modal will open
  • For each field (Distance, Duration, Heart Rate, Notes), you have two settings:
    • Enable in Form - Allow entering/editing this field in add/edit form
    • Show in List - Display this field in the performance list
  • Important: "Show in List" requires "Enable in Form" to be enabled
    • If you disable "Enable in Form", "Show in List" is automatically disabled
    • You can enable a field in the form without showing it in the list
  • Select sort order and direction in "Sort Order" section
  • Changes take effect immediately
  • Tap the X or swipe down to close settings

5. Changing Language

  • Tap the gear icon to open Settings
  • Scroll to the "Language" section
  • Select your preferred language:
    • English
    • Čeština (Czech)
  • The app language will change immediately

Module Integration

The performance tracker is designed as a reusable module. To integrate it into another app:

1. Copy the Module

Copy the entire modules/performance-tracker directory to your project.

2. Install Dependencies

Ensure your project has these dependencies:

{
  "dependencies": {
    "zod": "^3.x",
    "react-hook-form": "^7.x",
    "@hookform/resolvers": "^3.x",
    "react-native-reanimated": "~4.x",
    "i18next": "^25.x",
    "react-i18next": "^16.x"
  }
}

3. Wrap Your App with Providers

import {
  ConfigurationProvider,
  PerformanceProvider,
} from './modules/performance-tracker';

function App() {
  return (
    <ConfigurationProvider>
      <PerformanceProvider>
        {/* Your app content */}
      </PerformanceProvider>
    </ConfigurationProvider>
  );
}

4. Use the Components

import { PerformanceList, PerformanceForm } from './modules/performance-tracker';

// In your screen
<PerformanceList onItemPress={(id) => navigateToEdit(id)} />

5. Customize Configuration

import { ConfigurationProvider, defaultConfiguration } from './modules/performance-tracker';

const customConfig = {
  ...defaultConfiguration,
  fields: {
    distance: { enabledInForm: true, showInList: true },
    duration: { enabledInForm: false, showInList: false },
    heartRate: { enabledInForm: true, showInList: false },
    notes: { enabledInForm: true, showInList: false },
  },
};

<ConfigurationProvider initialConfig={customConfig}>
  {/* ... */}
</ConfigurationProvider>

Testing

Running Tests

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

Test Coverage

The project includes unit tests for:

  • Zod schema validation
  • Configuration validation
  • Sorting utilities
  • Formatting utilities

Coverage Target: 70%+ for core logic (schemas, utils)


Configuration

Environment Variables

No environment variables are required for this demo app.

TypeScript

The project uses TypeScript in strict mode. Configuration can be found in tsconfig.json.

ESLint

Linting is configured via Expo's default ESLint config. Run npm run lint to check code quality.


Technical Stack

  • Framework: React Native with Expo SDK ~54
  • Language: TypeScript (strict mode)
  • Routing: Expo Router (file-based)
  • Form Management: React Hook Form + Zod
  • Validation: Zod
  • Animation: React Native Reanimated ~4.1
  • Internationalization: i18next + react-i18next
  • Testing: Jest + React Native Testing Library
  • State Management: React Context API

Architecture

For detailed architecture documentation, see ARCHITECTURE.md.

Key architectural decisions:

  • Modular Design: Complete separation between reusable module and demo app
  • Configuration-Driven: All behavior controlled by validated schemas
  • Type-Safe: Full TypeScript with Zod runtime validation
  • Context-Based State: Simple, dependency-free state management

Internationalization

The app supports multiple languages:

  • English (en)
  • Czech (cs)

Language is auto-detected from device settings. Translation files are located in modules/performance-tracker/locales/.

To add a new language:

  1. Create a new JSON file (e.g., de.json)
  2. Add translations following the structure of en.json
  3. Import in locales/i18n.ts

Known Limitations

Current Limitations

  1. In-Memory Storage: Data is lost when the app restarts. No persistence implemented.
  2. No Delete Function: Cannot delete performances from the UI (Context method exists).
  3. Date Picker: Date input is not interactive (would require platform-specific implementation).
  4. Configuration Restart: Some configuration changes may require app restart.

Future Improvements

  • Add AsyncStorage for data persistence
  • Implement delete functionality with swipe gestures
  • Add cross-platform date picker
  • Real-time configuration updates
  • Search and filter functionality
  • Performance analytics and charts
  • Export to CSV/PDF

See ARCHITECTURE.md for detailed discussion of trade-offs and future improvements.


Troubleshooting

Common Issues

Metro Bundler Issues

# Clear Metro cache
npx expo start --clear

TypeScript Errors

# Check for errors
npx tsc --noEmit

Dependency Issues

# Clean install
rm -rf node_modules package-lock.json
npm install

iOS Simulator Not Opening

# Ensure Xcode is installed and simulators are available
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

Android Emulator Not Opening

  • Ensure Android Studio is installed
  • Create an AVD (Android Virtual Device) in AVD Manager
  • Start the emulator manually from Android Studio

License

This project is private and intended for demonstration purposes.


Support

For questions or issues related to this implementation, refer to:


Acknowledgments

Built as a test assignment for Etnetera Flow demonstrating:

  • Modular React Native architecture
  • TypeScript and type safety
  • Configuration-driven development
  • Clean code principles

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published