Skip to main content

React Native Mobile App Build Prompt

Use this prompt when building the FishingLog React Native mobile application.

Project Overview

FishingLog Mobile App is a comprehensive fishing log and social platform mobile app built with React Native. Users can track fishing trips, catches, gear, participate in tournaments, connect with other anglers, and access fishing regulations on iOS and Android devices.

Backend API

  • Base URL: https://api.fishinglog.com/api (or configured via environment variable)
  • Authentication: AWS Cognito JWT Bearer tokens
  • User Pool ID: us-east-2_TZtGx1T3X
  • Client ID: 6i1opt39o2n5h5ihq471l1ev07
  • Swagger Docs: Available at /swagger endpoint

Authentication Flow

  1. User authenticates via AWS Cognito (use amazon-cognito-identity-js or @aws-amplify/auth)
  2. Receive JWT token from Cognito
  3. Include token in all API requests: Authorization: Bearer {token}
  4. Token expires - refresh using Cognito refresh token

Core

  • React Native (latest stable)
  • TypeScript (strongly recommended)
  • React Navigation (v6+) - Navigation
  • React Query / TanStack Query - API state management
  • Zustand / Redux Toolkit - Global state (if needed)

Authentication

  • @aws-amplify/auth or amazon-cognito-identity-js
  • @react-native-async-storage/async-storage - Token storage
  • react-native-keychain - Secure storage (optional, recommended)

API Client

  • axios - HTTP client
  • Create API service layer with interceptors for auth
  • Handle token refresh automatically

UI Components

  • TamaGUI (Pro version) - Primary component library with theming support
  • react-native-maps - Map integration
  • react-native-image-picker - Photo selection
  • react-native-image-crop-picker - Image editing
  • @react-native-community/datetimepicker - Date/time pickers

Forms & Validation

  • react-hook-form - Form management
  • zod or yup - Validation

Location

  • @react-native-community/geolocation - Location services
  • react-native-maps - Map display

Media

  • react-native-image-picker - Photo/video selection
  • react-native-video - Video playback
  • react-native-fast-image - Optimized images

Payments

  • @stripe/stripe-react-native - Stripe integration
  • See stripe-integration.md for implementation details

Feature Flags

  • Feature flag hooks for conditional rendering
  • See feature-flags.md for implementation guide

Notifications

  • @react-native-firebase/messaging or expo-notifications - Push notifications

Project Structure

src/
├── api/
│ ├── client.ts # Axios instance with auth
│ ├── endpoints/
│ │ ├── auth.ts
│ │ ├── fishingLog.ts
│ │ ├── gear.ts
│ │ ├── social.ts
│ │ ├── tournaments.ts
│ │ └── payments.ts
│ └── types.ts # API response types
├── components/
│ ├── common/ # Reusable components
│ ├── fishing/ # Fishing-specific components
│ ├── social/ # Social components
│ ├── payments/ # Payment components
│ └── feature-gates/ # Feature flag components
├── screens/
│ ├── Auth/
│ │ ├── LoginScreen.tsx
│ │ ├── RegisterScreen.tsx
│ │ └── ForgotPasswordScreen.tsx
│ ├── FishingLog/
│ │ ├── FishingLogListScreen.tsx
│ │ ├── FishingLogEntryScreen.tsx
│ │ └── CreateEntryScreen.tsx
│ ├── Social/
│ │ ├── FeedScreen.tsx
│ │ ├── PostDetailScreen.tsx
│ │ └── CirclesScreen.tsx
│ ├── Tournaments/
│ │ ├── TournamentListScreen.tsx
│ │ ├── TournamentDetailScreen.tsx
│ │ └── TournamentRegistrationScreen.tsx
│ └── Profile/
│ └── ProfileScreen.tsx
├── navigation/
│ ├── AppNavigator.tsx
│ ├── AuthNavigator.tsx
│ └── TabNavigator.tsx
├── hooks/
│ ├── useAuth.ts
│ ├── useFeatureFlags.ts
│ ├── useFishingLog.ts
│ └── usePayments.ts
├── store/
│ ├── authStore.ts
│ └── uiStore.ts
├── utils/
│ ├── storage.ts
│ └── permissions.ts
└── types/
└── index.ts

Core Features & Implementation

1. Authentication & User Profile

Screens:

  • LoginScreen
  • RegisterScreen
  • ForgotPasswordScreen
  • ProfileScreen

Endpoints:

  • GET /api/userprofile/me - Get current user profile
  • PUT /api/userprofile/me - Update profile
  • GET /api/userprofile/{userId} - Get public profile

Key Data:

  • User info, avatar, bio, location
  • Privacy settings (ProfileVisibility)
  • Subscription tier (Free, Basic, Pro)
  • Personal bests, achievements

Implementation Notes:

  • Store JWT token securely (use react-native-keychain or @react-native-async-storage/async-storage)
  • Handle token refresh automatically
  • Show subscription tier badge
  • Respect privacy settings when viewing profiles

Example:

// hooks/useAuth.ts
import { useQuery, useMutation } from '@tanstack/react-query';
import AsyncStorage from '@react-native-async-storage/async-storage';

export function useAuth() {
const [token, setToken] = useState<string | null>(null);

useEffect(() => {
AsyncStorage.getItem('authToken').then(setToken);
}, []);

const login = async (email: string, password: string) => {
// Cognito login logic
const cognitoToken = await cognitoLogin(email, password);
await AsyncStorage.setItem('authToken', cognitoToken);
setToken(cognitoToken);
};

const logout = async () => {
await AsyncStorage.removeItem('authToken');
setToken(null);
};

return { token, login, logout };
}

2. Fishing Log Entries

Screens:

  • FishingLogListScreen
  • FishingLogEntryScreen
  • CreateEntryScreen

Endpoints:

  • GET /api/fishinglog/entries - Get entries (respects privacy)
  • GET /api/fishinglog/entries/{id} - Get specific entry
  • POST /api/fishinglog/entries - Create entry
  • PUT /api/fishinglog/entries/{id} - Update entry
  • DELETE /api/fishinglog/entries/{id} - Delete entry
  • GET /api/fishinglog/sessions - Get fishing sessions
  • POST /api/fishinglog/sessions - Create session
  • POST /api/fishinglog/entries/{entryId}/catches - Add catch

Key Data:

  • FishingLogEntry: Date, location, weather, notes, visibility
  • CatchDetail: Species, length, weight, photos, gear used
  • FishingSession: Start/end time, location, conditions

Implementation Notes:

  • Use location services for automatic location
  • Support photo uploads (use react-native-image-picker)
  • Privacy controls: Public, Private, Friends, Circle
  • Filter by date range, species, location
  • Show map view of fishing locations
  • Link catches to gear setups

Example:

// screens/FishingLog/CreateEntryScreen.tsx
import { useForm } from 'react-hook-form';
import ImagePicker from 'react-native-image-picker';
import Geolocation from '@react-native-community/geolocation';

function CreateEntryScreen() {
const { control, handleSubmit } = useForm();
const [location, setLocation] = useState<Location | null>(null);

useEffect(() => {
Geolocation.getCurrentPosition(
(position) => {
setLocation({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
}
);
}, []);

const pickImage = () => {
ImagePicker.launchImageLibrary({}, (response) => {
if (response.uri) {
// Upload image and add to form
}
});
};

const onSubmit = async (data: FishingLogEntryForm) => {
await createFishingLogEntry({
...data,
latitude: location?.latitude,
longitude: location?.longitude
});
};

return (
<Form>
{/* Form fields */}
</Form>
);
}

3. Social Features

Screens:

  • FeedScreen
  • PostDetailScreen
  • CirclesScreen (if Circles feature enabled)

Endpoints:

  • GET /api/social/posts - Get feed
  • POST /api/social/posts - Create post
  • POST /api/social/posts/{id}/like - Like post
  • POST /api/social/posts/{id}/comments - Add comment
  • GET /api/circle - Get circles (if enabled)
  • GET /api/circle/discover - Discover circles (if enabled)

Feature Flag Check:

// screens/Social/CirclesScreen.tsx
import { useFeatureFlag } from '@/hooks/useFeatureFlags';
import { FeatureGate } from '@/components/FeatureGate';

function CirclesScreen() {
const circlesEnabled = useFeatureFlag('Circles');

if (!circlesEnabled) {
return (
<View>
<Text>This feature is not available.</Text>
</View>
);
}

return <CirclesContent />;
}

4. Tournaments

Screens:

  • TournamentListScreen
  • TournamentDetailScreen
  • TournamentRegistrationScreen (with payment)

Endpoints:

  • GET /api/tournament - List tournaments
  • GET /api/tournament/{id} - Tournament details
  • POST /api/tournament/{id}/register - Register (creates payment intent)

Stripe Payment Integration:

// screens/Tournaments/TournamentRegistrationScreen.tsx
import { useStripe } from '@stripe/stripe-react-native';
import { initStripe } from '@stripe/stripe-react-native';

// Initialize Stripe
initStripe({
publishableKey: process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY!,
merchantIdentifier: 'merchant.com.fishinglog', // iOS only
});

function TournamentRegistrationScreen({ tournamentId }: { tournamentId: number }) {
const { initPaymentSheet, presentPaymentSheet } = useStripe();
const [clientSecret, setClientSecret] = useState<string | null>(null);

const handleRegister = async () => {
// Create registration and payment intent
const response = await fetch(`/api/tournament/${tournamentId}/register`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({ /* registration data */ })
});

const data = await response.json();
setClientSecret(data.stripeClientSecret);

// Initialize payment sheet
const { error } = await initPaymentSheet({
paymentIntentClientSecret: data.stripeClientSecret,
merchantDisplayName: 'FishingLog',
});

if (error) {
Alert.alert('Error', error.message);
}
};

const handlePay = async () => {
const { error } = await presentPaymentSheet();

if (error) {
Alert.alert('Error', error.message);
} else {
Alert.alert('Success', 'Registration confirmed!');
// Navigate to tournament detail
}
};

return (
<View>
{!clientSecret ? (
<Button onPress={handleRegister}>Register</Button>
) : (
<Button onPress={handlePay}>Pay Entry Fee</Button>
)}
</View>
);
}

5. Charter Bookings

Screens:

  • CharterListScreen
  • CharterDetailScreen
  • CharterBookingScreen (with payment)

Endpoints:

  • GET /api/charter/listings - List charters
  • POST /api/charter/listings/{id}/book - Create booking (creates payment intent)

Feature Flag Check:

<FeatureGate feature="Charters">
<CharterListScreen />
</FeatureGate>

6. Gear Management

Screens:

  • GearCatalogScreen
  • GearSetupScreen
  • CreateSetupScreen

Endpoints:

  • GET /api/gear/rods - Get rod catalog
  • GET /api/gear/reels - Get reel catalog
  • GET /api/gear/setups - Get setups
  • POST /api/gear/setups - Create setup

Implementation Notes:

  • Search/filter gear catalog
  • Create custom gear setups
  • Link setups to catches
  • Track gear usage statistics

Feature Flags Implementation

Feature Flag Hook

// hooks/useFeatureFlags.ts
import { useQuery } from '@tanstack/react-query';
import { useAuth } from './useAuth';

export function useFeatureFlags() {
const { token } = useAuth();

return useQuery({
queryKey: ['featureFlags'],
queryFn: async () => {
const response = await fetch(
'https://api.fishinglog.com/api/admin/feature-flags/current-environment',
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
const data = await response.json();
return data.featureFlags;
},
staleTime: 5 * 60 * 1000,
enabled: !!token, // Only fetch if authenticated
});
}

export function useFeatureFlag(featureKey: string) {
const { data: flags } = useFeatureFlags();
return flags?.[featureKey] ?? false;
}

Feature Gate Component

// components/FeatureGate.tsx
import { useFeatureFlag } from '@/hooks/useFeatureFlags';
import { View, Text } from 'react-native';

interface FeatureGateProps {
feature: string;
children: React.ReactNode;
fallback?: React.ReactNode;
}

export function FeatureGate({ feature, children, fallback }: FeatureGateProps) {
const isEnabled = useFeatureFlag(feature);

if (!isEnabled) {
return fallback ? <>{fallback}</> : null;
}

return <>{children}</>;
}

Usage in Navigation

// navigation/TabNavigator.tsx
import { useFeatureFlag } from '@/hooks/useFeatureFlags';

function TabNavigator() {
const circlesEnabled = useFeatureFlag('Circles');
const tournamentsEnabled = useFeatureFlag('Tournaments');

return (
<Tab.Navigator>
<Tab.Screen name="Feed" component={FeedScreen} />
<Tab.Screen name="FishingLog" component={FishingLogScreen} />
{circlesEnabled && (
<Tab.Screen name="Circles" component={CirclesScreen} />
)}
{tournamentsEnabled && (
<Tab.Screen name="Tournaments" component={TournamentsScreen} />
)}
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}

API Client Setup

// api/client.ts
import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const apiClient = axios.create({
baseURL: process.env.REACT_APP_API_URL || 'https://api.fishinglog.com/api',
});

apiClient.interceptors.request.use(async (config) => {
const token = await AsyncStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});

apiClient.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
// Handle token refresh or redirect to login
await AsyncStorage.removeItem('authToken');
// Navigate to login screen
}
return Promise.reject(error);
}
);

Environment Variables

REACT_APP_API_URL=https://api.fishinglog.com/api
REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_test_...
REACT_APP_COGNITO_USER_POOL_ID=us-east-2_TZtGx1T3X
REACT_APP_COGNITO_CLIENT_ID=6i1opt39o2n5h5ihq471l1ev07

Implementation Checklist

Phase 1: Foundation

  • Initialize React Native project with TypeScript
  • Set up React Navigation
  • Configure API client with auth interceptors
  • Set up TanStack Query
  • Create auth context/store
  • Implement secure token storage
  • Set up error handling

Phase 2: Core Features

  • Implement authentication flow
  • Build fishing log entry screens
  • Create social feed
  • Implement feature flag hooks/components
  • Add conditional navigation based on flags
  • Build gear management screens

Phase 3: Payments & Advanced Features

  • Integrate Stripe payments (payment sheet)
  • Implement tournament registration with payment
  • Build charter booking flow
  • Add location services
  • Implement photo uploads
  • Build user profiles

Phase 4: Polish

  • Add loading states
  • Implement error boundaries
  • Add toast notifications
  • Optimize performance
  • Add push notifications
  • Implement offline support (if needed)

Critical Implementation Notes

Feature Flags

  1. Always check flags before rendering features
  2. Use FeatureGate component for conditional rendering
  3. Cache flags for 5 minutes (matches backend)
  4. Handle loading/error states gracefully
  5. Hide disabled features from navigation

Stripe Payments

  1. Initialize Stripe before using payment sheet
  2. Use payment sheet (not card input) for better UX
  3. Handle payment errors gracefully
  4. Use test cards during development
  5. Show clear success/error messages

Authentication

  1. Store tokens securely (use Keychain on iOS, Keystore on Android)
  2. Implement automatic token refresh
  3. Handle 401 errors by redirecting to login
  4. Clear tokens on logout
  5. Validate token expiration before API calls

Permissions

  1. Request location permission before using location
  2. Request camera permission before taking photos
  3. Handle permission denials gracefully
  4. Show permission rationale to users

Testing

Feature Flags

  • Test with flags enabled/disabled
  • Test flag loading states
  • Verify features are hidden when disabled
  • Test navigation updates when flags change

Stripe Payments

  • Use test cards: 4242 4242 4242 4242 (success)
  • Test payment failures
  • Test on both iOS and Android
  • Verify webhook updates (check backend logs)

Location Services

  • Test location permission flow
  • Test location accuracy
  • Handle location errors gracefully

Platform-Specific Considerations

iOS

  • Configure Info.plist for location permissions
  • Set up Stripe merchant identifier
  • Handle App Store review requirements

Android

  • Configure AndroidManifest.xml for permissions
  • Handle runtime permissions (Android 6+)
  • Set up Stripe merchant configuration

Documentation References

  • React Native Guide: docs/frontend/react-native.md
  • Stripe Integration: docs/frontend/stripe-integration.md
  • Feature Flags: docs/frontend/feature-flags.md
  • Backend API: docs/api/README.md

Success Criteria

A successful mobile app implementation should:

  • ✅ Handle authentication and token management securely
  • ✅ Respect feature flags for all features
  • ✅ Integrate Stripe payments correctly (payment sheet)
  • ✅ Handle errors gracefully
  • ✅ Provide good user feedback
  • ✅ Work on both iOS and Android
  • ✅ Handle permissions correctly
  • ✅ Be performant and responsive
  • ✅ Follow platform-specific guidelines