Skip to main content

React Native Frontend Development Prompt

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

Project Overview

FishingLog 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.

Backend API

Base URL: https://api.fishinglog.com/api (or your deployed URL) Authentication: AWS Cognito JWT Bearer tokens User Pool ID: us-east-2_TZtGx1T3X Client ID: 6i1opt39o2n5h5ihq471l1ev07

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 Features & API Endpoints

1. Authentication & User Profile

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

2. Fishing Log Entries

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

3. Gear Management

Endpoints:

  • GET /api/gear/rods - Get rod catalog
  • GET /api/gear/reels - Get reel catalog
  • GET /api/gear/lines - Get line catalog
  • GET /api/gear/lures - Get lure catalog
  • GET /api/gear/boats - Get user's boats
  • POST /api/gear/boats - Create boat
  • GET /api/gear/setups - Get gear setups
  • POST /api/gear/setups - Create setup

Key Data:

  • Reference data: Rods, Reels, Lines, Lures (catalog)
  • User-owned: Boats, GearSetups
  • GearSetup: Combines rod + reel + line + lures

Implementation Notes:

  • Search/filter gear catalog
  • Create custom gear setups
  • Link setups to catches
  • Track gear usage statistics
  • Boat management with photos

4. Social Features

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/social/friends - Get friends
  • POST /api/social/friends/{friendId} - Add friend

Key Data:

  • Post: Content, photos, location, visibility, likes, comments
  • Comment: Replies, likes
  • Privacy: Public, Friends, Circle, Private

Implementation Notes:

  • Infinite scroll feed
  • Real-time updates via SignalR (see Real-Time Updates section)
  • Photo uploads for posts
  • Hashtag support
  • Mentions (@username)
  • Privacy controls
  • Pull-to-refresh

5. Tournaments

Endpoints:

  • GET /api/tournament - Get tournaments
  • GET /api/tournament/{id} - Get tournament details
  • POST /api/tournament/{tournamentId}/register - Register
  • GET /api/tournament/{tournamentId}/results - Get leaderboard
  • GET /api/tournament/{tournamentId}/registrations - Get registrations

Key Data:

  • Tournament info, dates, entry fees
  • Registration status
  • Leaderboard/results
  • Prizes, sponsors

Implementation Notes:

  • Show upcoming tournaments
  • Registration with payment (Stripe)
  • Leaderboard with rankings
  • Submit catches for tournament
  • Tournament notifications

6. Regulations & Master Angler

Endpoints:

  • GET /api/regulations/by-location - Get regulations for location
  • GET /api/regulations/master-angler/{stateId} - Get Master Angler program
  • GET /api/regulations/master-angler/submissions - Get submissions

Key Data:

  • Bag limits, size limits, seasons
  • Fishing zones
  • Master Angler minimum sizes
  • Submission status

Implementation Notes:

  • Location-based regulations
  • Show current seasons
  • Master Angler eligibility checker
  • Submit catches for Master Angler
  • Regulation updates notifications

7. Personal Bests

Endpoints:

  • GET /api/personalbest/me - Get all PBs
  • GET /api/personalbest/me/criteria - Get PB criteria
  • POST /api/personalbest/me/criteria - Create criteria
  • PUT /api/personalbest/{pbId}/set-ultimate - Set ultimate PB

Key Data:

  • PB records by species
  • Criteria (length, weight, etc.)
  • Ultimate PB (best overall)

Implementation Notes:

  • Auto-detect PB when logging catch
  • PB badges/achievements
  • Compare to Master Angler minimums
  • PB statistics and charts

8. Fishing Spots & Reports

Endpoints:

  • GET /api/spots/nearby - Get nearby spots
  • GET /api/spots/{id} - Get spot details
  • POST /api/spots/{id}/rate - Rate spot
  • GET /api/reports/by-location - Get fishing reports
  • POST /api/reports - Create report

Key Data:

  • Spot location, ratings, boat ramps
  • Fishing reports (conditions, catches)

Implementation Notes:

  • Map view of spots
  • Location-based search
  • Spot ratings and reviews
  • Recent fishing reports
  • Weather integration

9. Charter Bookings

Endpoints:

  • GET /api/charter/listings - Get charter listings
  • POST /api/charter/listings/{listingId}/book - Book charter
  • GET /api/charter/bookings - Get bookings

Key Data:

  • Charter listings, prices, availability
  • Booking status, dates

Implementation Notes:

  • Browse charters
  • Calendar for availability
  • Booking with payment
  • Booking history

10. Circles (Facebook Group-like Communities)

Circles are custom groups that allow users to create targeted sharing communities with rule-based content filtering, roles, applications, and contributor rankings.

Endpoints:

  • GET /api/circle - Get circles owned by current user
  • GET /api/circle/memberships - Get circles user is a member of
  • GET /api/circle/discover - Discover public circles (searchable, paginated)
  • GET /api/circle/{id} - Get circle details
  • POST /api/circle - Create a new circle
  • PUT /api/circle/{id} - Update circle (owner/admin only)
  • DELETE /api/circle/{id} - Delete circle (owner only)
  • POST /api/circle/{id}/join - Join a public circle
  • POST /api/circle/{id}/leave - Leave a circle
  • POST /api/circle/{id}/apply - Apply to join a circle (if requires approval)
  • GET /api/circle/{id}/applications - Get pending applications (moderator/admin/owner)
  • POST /api/circle/{id}/applications/{applicationId}/approve - Approve application
  • POST /api/circle/{id}/applications/{applicationId}/reject - Reject application
  • POST /api/circle/{id}/applications/{applicationId}/withdraw - Withdraw own application
  • GET /api/circle/{id}/members - Get circle members
  • POST /api/circle/{id}/members - Add member (owner/admin only)
  • PUT /api/circle/{id}/members/{userId}/role - Update member role (admin/owner only)
  • DELETE /api/circle/{id}/members/{userId}/remove - Remove member (moderator/admin/owner)
  • POST /api/circle/{id}/transfer-ownership - Transfer ownership (owner only)
  • GET /api/circle/{id}/contributors - Get top contributors
  • GET /api/circle/{id}/rules - Get circle rules
  • PUT /api/circle/{id}/rules - Update circle rules (owner/admin only)
  • POST /api/circle/{id}/rules/test - Test if content matches rules
  • POST /api/social/posts/{id}/share-to-circles - Auto-share post to matching circles
  • POST /api/fishinglog/entries/{id}/share-to-circles - Auto-share log entry to matching circles

Key Features:

  1. Circle Roles (like Facebook groups):

    • Owner - Full control, can transfer ownership
    • Admin - Can manage members, applications, settings
    • Moderator - Can approve/reject applications, remove members
    • Member - Standard member
  2. Application System:

    • Circles can require approval to join (RequiresApproval: true)
    • Users apply with optional message
    • Moderators/admins approve or reject applications
    • Users can withdraw their own applications
  3. Rule-Based Auto-Sharing:

    • Circles can define rules (species, location, brand, lure, fishing method, size, date range)
    • When AutoShare: true, content automatically shared to matching circles
    • One-click sharing evaluates all user's circles and shares to matches
  4. Contributor Rankings:

    • Tracks posts, log entries, and comments per member
    • Calculates contributor score (posts×2 + log entries×3 + comments×1)
    • Shows top contributors in circle
  5. Circle Types:

    • IsPublic: true - Discoverable, anyone can join (if no approval required)
    • IsPublic: false - Private, invite-only
    • RequiresApproval: true - Application required
    • RequiresApproval: false - Open joining

Circle Data Structure:

interface Circle {
id: string;
name: string;
description?: string;
color?: string; // Hex color for UI
icon?: string; // Emoji or icon name
ownerUserId: string;
isPublic: boolean;
requiresApproval: boolean;
enforceRules: boolean; // If false, all content can be shared manually
autoShare: boolean; // Auto-share matching content
rules?: string; // JSON string with rule criteria
memberCount: number;
postCount: number;
logEntryCount: number;
pendingApplicationCount: number;
createdAt: string;
updatedAt: string;
}

interface CircleMember {
userId: string;
userName: string;
role: 'Member' | 'Moderator' | 'Admin' | 'Owner';
contributorScore: number;
postCount: number;
logEntryCount: number;
commentCount: number;
joinedAt: string;
}

interface CircleApplication {
id: number;
circleId: string;
userId: string;
userName: string;
message?: string;
status: 'Pending' | 'Approved' | 'Rejected' | 'Withdrawn';
rejectionReason?: string;
appliedAt: string;
reviewedAt?: string;
reviewedByUserId?: string;
}

interface CircleRules {
fishSpecies?: number[]; // Species IDs
locationRadius?: {
latitude: number;
longitude: number;
radiusKm: number;
};
states?: string[];
regions?: string[];
fishingMethods?: string[]; // "FlyFishing", "Spinning", etc.
minimumLengthCm?: number;
maximumLengthCm?: number;
minimumWeightKg?: number;
maximumWeightKg?: number;
startDate?: string; // ISO date
endDate?: string; // ISO date
brandIds?: string[]; // Brand GUIDs
lureIds?: string[]; // Lure GUIDs
contentKeywords?: string[]; // Keywords in content
}

Implementation Notes:

  • Creating Circles: Users can create circles with custom names, descriptions, colors, icons
  • Rule Configuration: Use a form to configure rules (species picker, location radius map, date ranges, etc.)
  • Auto-Share Toggle: When enabled, content automatically evaluates against circle rules
  • Application Management: Show pending applications to moderators/admins with approve/reject actions
  • Member Management: Show member list with roles, allow role changes (if admin/owner)
  • Contributor Leaderboard: Display top contributors sorted by score
  • Circle Discovery: Searchable list of public circles with filters
  • Multi-Circle Sharing: Single post/log entry can be shared to multiple circles simultaneously

UI Components Needed:

  • Circle creation/edit form
  • Rule configuration UI (species picker, location radius map, date pickers, etc.)
  • Application list with approve/reject actions
  • Member list with role badges and management actions
  • Contributor leaderboard
  • Circle discovery/search
  • Circle member role selector
  • Application form with message field

11. Events & Clubs

Endpoints:

  • GET /api/events - Get events
  • POST /api/events/{id}/register - Register for event
  • GET /api/clubs - Get clubs
  • POST /api/clubs/{id}/join - Join club

Key Data:

  • Events (expos, seminars, swap meets)
  • Clubs and memberships

Implementation Notes:

  • Event calendar
  • Event registration
  • Club directory
  • Club membership management

Technical Stack Recommendations

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)

API Client

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

Real-Time Updates

  • @microsoft/signalr - SignalR client for real-time updates
  • react-native-get-random-values - Required for SignalR
  • Real-time social feed updates, notifications, live data

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
│ │ └── ...
│ └── types.ts # API response types
├── components/
│ ├── common/ # Reusable components
│ ├── fishing/ # Fishing-specific components
│ └── social/ # Social components
├── screens/
│ ├── Auth/
│ ├── FishingLog/
│ ├── Gear/
│ ├── Social/
│ └── ...
├── navigation/
│ ├── AppNavigator.tsx
│ └── AuthNavigator.tsx
├── store/
│ ├── authStore.ts # Auth state
│ └── ...
├── hooks/
│ ├── useAuth.ts
│ ├── useFishingLog.ts
│ └── ...
├── utils/
│ ├── location.ts
│ ├── date.ts
│ └── ...
└── constants/
├── colors.ts
└── ...

Key Implementation Patterns

API Client Setup

// api/client.ts
import axios from 'axios';
import { getAuthToken } from './auth';

const api = axios.create({
baseURL: 'https://api.fishinglog.com/api',
});

api.interceptors.request.use(async (config) => {
const token = await getAuthToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});

api.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
// Refresh token and retry
await refreshToken();
return api.request(error.config);
}
return Promise.reject(error);
}
);

React Query Hooks

// hooks/useFishingLog.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { fishingLogApi } from '../api/endpoints/fishingLog';

export const useFishingLogEntries = (filters?: Filters) => {
return useQuery({
queryKey: ['fishingLog', 'entries', filters],
queryFn: () => fishingLogApi.getEntries(filters),
});
};

export const useCreateFishingLogEntry = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: fishingLogApi.createEntry,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['fishingLog'] });
},
});
};

Theming System

Overview

FishingLog includes a comprehensive theming system that allows users to fully customize their app experience. Themes can be applied at the user level, and events/charters can have custom branded themes. The system integrates seamlessly with TamaGUI's theming capabilities.

Theme API Endpoints

Base URL: /api/theme

  • GET /api/theme - Get all available themes (public + user's own)
  • GET /api/theme/{id} - Get a specific theme
  • GET /api/theme/me - Get current user's active theme
  • POST /api/theme - Create a new theme
  • PUT /api/theme/{id} - Update a theme (owner only)
  • DELETE /api/theme/{id} - Delete a theme (owner only)
  • POST /api/theme/{id}/apply - Apply theme to current user
  • DELETE /api/theme/me - Remove theme from current user (revert to default)
  • POST /api/theme/{id}/duplicate - Duplicate a theme

Theme Data Structure

interface Theme {
id: string;
name: string;
description?: string;
themeType: 'User' | 'Event' | 'Charter' | 'System' | 'Shared';
baseThemeId?: string;
themeTokens: string; // JSON string with TamaGUI theme tokens
backgroundColor?: string;
foregroundColor?: string;
accentColor?: string;
secondaryColor?: string;
borderColor?: string;
errorColor?: string;
warningColor?: string;
successColor?: string;
infoColor?: string;
fontFamily?: string;
headingFontFamily?: string;
baseFontSize?: number;
lineHeight?: number;
baseSpacing?: number;
borderRadius?: number;
logoUrl?: string;
faviconUrl?: string;
backgroundImageUrl?: string;
backgroundImagePosition?: string;
isActive: boolean;
isPublic: boolean;
isDefault: boolean;
usageCount: number;
createdAt: string;
updatedAt: string;
}

TamaGUI Theme Integration

1. Fetch User's Theme

// hooks/useTheme.ts
import { useQuery } from '@tanstack/react-query';
import { apiClient } from '../api/client';

export const useUserTheme = () => {
return useQuery({
queryKey: ['theme', 'me'],
queryFn: async () => {
const response = await apiClient.get('/api/theme/me');
return response.data;
},
staleTime: 5 * 60 * 1000, // Cache for 5 minutes
});
};

2. Convert Theme to TamaGUI Format

// utils/themeConverter.ts
import { Theme } from '../types/theme';

export const convertThemeToTamagui = (theme: Theme) => {
// Parse TamaGUI tokens from JSON
const tokens = JSON.parse(theme.themeTokens || '{}');

// Merge with quick access properties
return {
...tokens,
colors: {
...tokens.colors,
background: theme.backgroundColor || tokens.colors?.background || '#ffffff',
foreground: theme.foregroundColor || tokens.colors?.foreground || '#000000',
accent: theme.accentColor || tokens.colors?.accent || '#007AFF',
secondary: theme.secondaryColor || tokens.colors?.secondary || '#5856D6',
border: theme.borderColor || tokens.colors?.border || '#E5E5EA',
error: theme.errorColor || tokens.colors?.error || '#FF3B30',
warning: theme.warningColor || tokens.colors?.warning || '#FF9500',
success: theme.successColor || tokens.colors?.success || '#34C759',
info: theme.infoColor || tokens.colors?.info || '#5AC8FA',
},
typography: {
...tokens.typography,
fontFamily: theme.fontFamily || tokens.typography?.fontFamily || 'System',
headingFontFamily: theme.headingFontFamily || tokens.typography?.headingFontFamily || 'System',
fontSize: theme.baseFontSize || tokens.typography?.fontSize || 16,
lineHeight: theme.lineHeight || tokens.typography?.lineHeight || 1.5,
},
spacing: {
...tokens.spacing,
base: theme.baseSpacing || tokens.spacing?.base || 16,
},
borderRadius: {
...tokens.borderRadius,
base: theme.borderRadius || tokens.borderRadius?.base || 8,
},
};
};

3. Apply Theme in TamaGUI Provider

// App.tsx or ThemeProvider.tsx
import { TamaguiProvider } from '@tamagui/core';
import { useUserTheme } from './hooks/useTheme';
import { convertThemeToTamagui } from './utils/themeConverter';
import { config } from './tamagui.config';

export function App() {
const { data: theme, isLoading } = useUserTheme();

// Get default theme if user theme not loaded
const tamaguiTheme = theme
? convertThemeToTamagui(theme)
: getDefaultTheme();

if (isLoading) {
return <LoadingScreen />;
}

return (
<TamaguiProvider config={config} defaultTheme={tamaguiTheme}>
{/* Your app content */}
</TamaguiProvider>
);
}

4. Theme Management Hook

// hooks/useThemeManagement.ts
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../api/client';

export const useApplyTheme = () => {
const queryClient = useQueryClient();

return useMutation({
mutationFn: async (themeId: string) => {
await apiClient.post(`/api/theme/${themeId}/apply`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['theme', 'me'] });
queryClient.invalidateQueries({ queryKey: ['user'] });
},
});
};

export const useCreateTheme = () => {
const queryClient = useQueryClient();

return useMutation({
mutationFn: async (themeData: CreateThemeRequest) => {
const response = await apiClient.post('/api/theme', themeData);
return response.data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['theme'] });
},
});
};

Theme Customization UI

Theme Selection Screen

// screens/Settings/ThemeScreen.tsx
import { useQuery } from '@tanstack/react-query';
import { useApplyTheme } from '../../hooks/useThemeManagement';
import { List, Card, Button } from '@tamagui/core';

export function ThemeScreen() {
const { data: themes } = useQuery({
queryKey: ['theme'],
queryFn: () => apiClient.get('/api/theme').then(r => r.data),
});

const applyTheme = useApplyTheme();

return (
<List>
{themes?.map(theme => (
<Card key={theme.id}>
<Card.Header>
<Card.Title>{theme.name}</Card.Title>
{theme.description && <Card.Description>{theme.description}</Card.Description>}
</Card.Header>
<Card.Footer>
<Button onPress={() => applyTheme.mutate(theme.id)}>
Apply Theme
</Button>
</Card.Footer>
</Card>
))}
</List>
);
}

Theme Editor Screen

// screens/Settings/ThemeEditorScreen.tsx
import { useForm } from 'react-hook-form';
import { useCreateTheme } from '../../hooks/useThemeManagement';
import { ColorPicker, Slider } from '@tamagui/core';

export function ThemeEditorScreen() {
const createTheme = useCreateTheme();
const { control, handleSubmit } = useForm();

const onSubmit = (data) => {
createTheme.mutate({
name: data.name,
accentColor: data.accentColor,
backgroundColor: data.backgroundColor,
// ... other theme properties
themeTokens: JSON.stringify({
colors: {
accent: data.accentColor,
background: data.backgroundColor,
// ... more colors
},
// ... other tokens
}),
});
};

return (
<Form onSubmit={handleSubmit(onSubmit)}>
{/* Theme customization form */}
</Form>
);
}

Event/Charter Theme Support

When viewing events or charter pages, check if they have a custom theme:

// hooks/useEventTheme.ts
export const useEventTheme = (eventId: number) => {
return useQuery({
queryKey: ['event', eventId, 'theme'],
queryFn: async () => {
const event = await apiClient.get(`/api/events/${eventId}`);
if (event.data.themeId) {
const theme = await apiClient.get(`/api/theme/${event.data.themeId}`);
return theme.data;
}
return null;
},
});
};

Default Theme

Always provide a default theme fallback:

// utils/defaultTheme.ts
export const getDefaultTheme = () => ({
colors: {
background: '#ffffff',
foreground: '#000000',
accent: '#007AFF',
secondary: '#5856D6',
border: '#E5E5EA',
error: '#FF3B30',
warning: '#FF9500',
success: '#34C759',
info: '#5AC8FA',
},
typography: {
fontFamily: 'System',
headingFontFamily: 'System',
fontSize: 16,
lineHeight: 1.5,
},
spacing: {
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32,
},
borderRadius: {
sm: 4,
md: 8,
lg: 12,
full: 9999,
},
});

Best Practices

  1. Cache Themes: Cache user theme to avoid repeated API calls
  2. Theme Preview: Show theme preview before applying
  3. Theme Gallery: Create a gallery of public themes for discovery
  4. Theme Templates: Provide theme templates for quick setup
  5. Accessibility: Ensure themes maintain accessibility standards
  6. Performance: Lazy load theme data, don't block app initialization
  7. Fallback: Always have a default theme ready

Design Guidelines

Colors

  • Primary: Fishing/water theme (blues, greens) - customizable via themes
  • Accent: Orange/red for catches, achievements - customizable via themes
  • Neutral: Grays for text, backgrounds - customizable via themes
  • Note: Colors are now user-customizable through the theming system

Typography

  • Headings: Bold, clear hierarchy - customizable via themes
  • Body: Readable, appropriate sizes - customizable via themes
  • Labels: Clear, concise
  • Note: Font families and sizes are customizable through themes

Icons

  • Use consistent icon set (Material Icons, FontAwesome, etc.)
  • Fishing-specific icons where appropriate
  • Bottom tab navigation for main sections
  • Stack navigation for detail screens
  • Drawer for settings/profile

Privacy & Permissions

Required Permissions

  • Location - For fishing spots, regulations, log entries
  • Camera - For catch photos
  • Photo Library - For selecting photos
  • Notifications - For tournament updates, social interactions

Privacy Controls

  • Respect user privacy settings
  • Show privacy indicators (Public/Friends/Private)
  • Handle consent for data sharing

Performance Considerations

  • Image Optimization - Compress images before upload
  • Lazy Loading - Load images as needed
  • Pagination - Use pagination for lists
  • Caching - Cache API responses appropriately
  • Offline Support - Consider offline-first approach

Testing

  • Unit tests for utilities/hooks
  • Integration tests for API calls
  • E2E tests for critical flows (login, create entry)

Deployment

  • iOS: App Store via TestFlight
  • Android: Google Play Store
  • Use EAS Build (Expo) or Fastlane for builds
  • Environment variables for API URLs

Additional Resources

  • See API_ENDPOINTS_SUMMARY.md for complete API documentation
  • See backend README.md for API details
  • Backend uses Swagger/OpenAPI for API docs
  • Stripe Integration - Payment processing guide
  • Feature Flags - Feature flag implementation guide
  • Real-Time Updates - SignalR integration guide
  • Mobile App Build Prompt - Complete build guide for this mobile application

Real-Time Updates (SignalR)

Setup

  1. Install packages:
npm install @microsoft/signalr
npm install react-native-get-random-values
  1. Import at app entry point:
// App.tsx or index.js
import 'react-native-get-random-values';
  1. Create SignalR service:
// services/signalr/socialHub.ts
import * as signalR from '@microsoft/signalr';
import { getAuthToken } from '../auth';

class SocialHubService {
private connection: signalR.HubConnection | null = null;

async connect() {
const token = await getAuthToken();

this.connection = new signalR.HubConnectionBuilder()
.withUrl(`${API_URL}/hubs/social`, {
accessTokenFactory: () => token,
headers: {
'Authorization': `Bearer ${token}`,
},
})
.withAutomaticReconnect({
nextRetryDelayInMilliseconds: (retryContext) => {
return Math.min(1000 * Math.pow(2, retryContext.previousRetryCount), 30000);
},
})
.build();

await this.connection.start();
}

async disconnect() {
if (this.connection) {
await this.connection.stop();
}
}

onNewPost(callback: (post: Post) => void) {
this.connection?.on('NewPost', callback);
}

onPostLiked(callback: (data: any) => void) {
this.connection?.on('PostLiked', callback);
}

onCommentAdded(callback: (data: any) => void) {
this.connection?.on('CommentAdded', callback);
}

async subscribeToPost(postId: string) {
await this.connection?.invoke('SubscribeToPost', postId);
}
}

export const socialHub = new SocialHubService();
  1. Use in components:
// screens/SocialFeedScreen.tsx
import { useEffect } from 'react';
import { socialHub } from '../services/signalr/socialHub';
import { useQuery, useQueryClient } from '@tanstack/react-query';

export function SocialFeedScreen() {
const queryClient = useQueryClient();

useEffect(() => {
socialHub.connect();

socialHub.onNewPost((newPost) => {
queryClient.setQueryData(['posts'], (old: Post[]) => {
return [newPost, ...(old || [])];
});
});

socialHub.onPostLiked((data) => {
queryClient.setQueryData(['posts'], (old: Post[]) => {
return old?.map(post =>
post.id === data.postId
? { ...post, likeCount: data.likeCount }
: post
) || [];
});
});

return () => {
socialHub.disconnect();
};
}, []);

// ... rest of component
}

Available Hubs

  • /hubs/social - Social feed updates (posts, likes, comments)
  • /hubs/notifications - User notifications
  • /hubs/admin - Admin panel updates (admin only)

Events

SocialHub:

  • NewPost - New post created
  • PostLiked - Post liked
  • PostUnliked - Post unliked
  • CommentAdded - Comment added

NotificationHub:

  • NotificationReceived - New notification

See docs/infrastructure/real-time-updates-strategy.md for complete details.

Questions to Consider

  1. Offline Support: Should app work offline? Cache entries locally?
  2. Real-time Updates: ✅ SignalR implemented - use for social feed updates
  3. Push Notifications: What events trigger notifications?
  4. Analytics: What user actions to track?
  5. Error Handling: How to handle API errors gracefully?

Stripe Payment Integration

See Stripe Integration Guide for:

  • Payment sheet implementation
  • Tournament registration payments
  • Charter booking payments
  • Subscription management
  • Error handling and testing

Key Endpoints:

  • POST /api/tournament/{id}/register - Creates payment intent
  • POST /api/charter/listings/{id}/book - Creates booking payment

Feature Flags

See Feature Flags Guide for:

  • Feature flag hooks and components
  • Conditional rendering based on flags
  • Environment-specific feature control

Key Endpoints:

  • GET /api/admin/feature-flags/current-environment - Get current environment flags

Common Flags:

  • Circles - Social circles feature (disabled in production)
  • Tournaments - Tournament management
  • Charters - Charter booking system