Skip to main content

Web App Frontend Development Prompt

Use this document when building the FishingLog web application.

Project Overview

FishingLog is a comprehensive fishing log and social platform web application. 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 @aws-amplify/auth or amazon-cognito-identity-js)
  2. Receive JWT token from Cognito
  3. Include token in all API requests: Authorization: Bearer {token}
  4. Token expires - refresh using Cognito refresh token

Framework

  • React (v18+) with TypeScript
  • Next.js (recommended) or Vite + React Router
  • Tailwind CSS - Styling
  • TamaGUI (Pro version) - Component library

State Management

  • TanStack Query (React Query) - Server state
  • Zustand or Jotai - Client state (if needed)
  • React Context - Auth state

Forms & Validation

  • react-hook-form - Form management
  • zod - Schema validation

API Client

  • axios or fetch with interceptors
  • Auto token refresh
  • Error handling

Real-Time Updates

  • @microsoft/signalr - SignalR client for real-time updates
  • Real-time social feed updates, notifications, live data

Maps

  • Google Maps or Mapbox - Map integration
  • react-map-gl (Mapbox) or **@react-google-maps/api`

Charts

  • recharts or Chart.js - Data visualization
  • @tanstack/react-charts - Advanced charts

File Uploads

  • react-dropzone - File uploads
  • Direct S3 uploads (if backend supports)

Payments

  • @stripe/stripe-js - Stripe integration
  • @stripe/react-stripe-js - Stripe React components

Feature Flags

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

Project Structure

src/
├── app/ # Next.js app directory (if using Next.js)
│ ├── (auth)/
│ ├── (dashboard)/
│ └── api/ # API routes (if needed)
├── components/
│ ├── ui/ # Reusable UI components
│ ├── fishing/ # Fishing-specific components
│ ├── social/ # Social components
│ └── layout/ # Layout components
├── lib/
│ ├── api/ # API client
│ │ ├── client.ts
│ │ └── endpoints/
│ ├── auth/ # Auth utilities
│ └── utils/ # Utilities
├── hooks/ # Custom hooks
├── store/ # State management
├── types/ # TypeScript types
└── styles/ # Global styles

Core Features & Implementation

1. Authentication

Implementation:

  • Login/Register pages
  • Password reset flow
  • Token management (localStorage or httpOnly cookies)
  • Protected routes
  • Auth context/provider

Key Endpoints:

  • Cognito authentication (not API endpoint)
  • GET /api/userprofile/me - Get current user

2. Dashboard

Features:

  • Recent fishing log entries
  • Quick stats (total catches, PBs, etc.)
  • Upcoming tournaments
  • Social feed preview
  • Recent activity

Components:

  • Stats cards
  • Activity timeline
  • Quick actions

3. Fishing Log

Pages:

  • List View: All entries with filters (date, species, location)
  • Map View: Entries plotted on map
  • Detail View: Full entry with catches, photos, gear
  • Create/Edit: Form for creating/editing entries

Key Endpoints:

  • GET /api/fishinglog/entries - List entries
  • POST /api/fishinglog/entries - Create entry
  • GET /api/fishinglog/entries/{id} - Get entry
  • PUT /api/fishinglog/entries/{id} - Update entry
  • POST /api/fishinglog/entries/{entryId}/catches - Add catch

Components:

  • Entry card/list item
  • Entry detail view
  • Catch form
  • Photo gallery
  • Map integration
  • Privacy controls

4. Gear Management

Pages:

  • Gear Catalog: Browse rods, reels, lines, lures
  • My Gear: User's boats and setups
  • Setup Builder: Create gear setups
  • Gear Detail: View gear specs, reviews

Key Endpoints:

  • GET /api/gear/rods - Rod catalog
  • GET /api/gear/setups - User setups
  • POST /api/gear/setups - Create setup
  • GET /api/gear/boats - User boats

Components:

  • Gear catalog grid
  • Setup builder form
  • Gear comparison
  • Usage statistics

5. Social Feed

Pages:

  • Feed: Main social feed
  • Post Detail: Full post with comments
  • Create Post: Post creation form
  • Profile: User profiles

Key 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

Components:

  • Post card
  • Comment thread
  • Like button
  • Photo upload
  • Hashtag/mention support

6. Tournaments

Pages:

  • Tournament List: Browse tournaments
  • Tournament Detail: Full tournament info
  • Leaderboard: Tournament results
  • Registration: Register for tournament

Key Endpoints:

  • GET /api/tournament - List tournaments
  • GET /api/tournament/{id} - Tournament details
  • POST /api/tournament/{tournamentId}/register - Register
  • GET /api/tournament/{tournamentId}/results - Leaderboard

Components:

  • Tournament card
  • Leaderboard table
  • Registration form
  • Payment integration

7. Regulations

Pages:

  • Regulations Map: Interactive map with zones
  • Regulations List: Regulations by location
  • Master Angler: Master Angler program info
  • Submissions: User's Master Angler submissions

Key Endpoints:

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

Components:

  • Regulation card
  • Zone map
  • Master Angler checker
  • Submission form

8. Personal Bests

Pages:

  • PB Dashboard: All personal bests
  • PB Detail: Specific PB record
  • PB Criteria: Manage criteria

Key Endpoints:

  • GET /api/personalbest/me - Get PBs
  • GET /api/personalbest/me/criteria - Get criteria
  • POST /api/personalbest/me/criteria - Create criteria

Components:

  • PB card
  • PB statistics
  • Criteria form

9. Fishing Spots & Reports

Pages:

  • Spots Map: Map of fishing spots
  • Spot Detail: Spot information
  • Reports: Fishing reports by location

Key Endpoints:

  • GET /api/spots/nearby - Nearby spots
  • GET /api/reports/by-location - Reports
  • POST /api/reports - Create report

Components:

  • Spot map
  • Spot card
  • Report form

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.

Pages:

  • Circle List: My circles (owned and memberships)
  • Circle Discovery: Browse public circles
  • Circle Detail: View circle info, members, posts
  • Circle Settings: Manage circle settings, rules, members
  • Application Management: Review pending applications (moderator/admin)
  • Member Management: View/manage members and roles
  • Contributor Leaderboard: Top contributors in circle

Key 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
}

Components:

  • 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
  • Circle card component
  • Circle settings panel

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
  • Role-Based UI: Show/hide actions based on user's role in circle

11. User Profile

Pages:

  • Profile: User profile page
  • Settings: Account settings
  • Privacy: Privacy controls

Key Endpoints:

  • GET /api/userprofile/me - Get profile
  • PUT /api/userprofile/me - Update profile
  • GET /api/userprofile/{userId} - Public profile

Components:

  • Profile header
  • Profile stats
  • Settings form
  • Privacy controls

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 '@/lib/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

// lib/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/layout.tsx or providers/ThemeProvider.tsx
'use client';

import { TamaguiProvider } from '@tamagui/core';
import { useUserTheme } from '@/hooks/useTheme';
import { convertThemeToTamagui } from '@/lib/utils/themeConverter';
import { config } from '@/tamagui.config';

export function ThemeProvider({ children }: { children: React.ReactNode }) {
const { data: theme, isLoading } = useUserTheme();

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

if (isLoading) {
return <div>Loading theme...</div>;
}

return (
<TamaguiProvider config={config} defaultTheme={tamaguiTheme}>
{children}
</TamaguiProvider>
);
}

4. Theme Management Hook

// hooks/useThemeManagement.ts
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '@/lib/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'] });
// Force page reload to apply theme changes
window.location.reload();
},
});
};

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 Page

// app/settings/themes/page.tsx
'use client';

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

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

const applyTheme = useApplyTheme();

return (
<div>
<h1>Choose Your Theme</h1>
<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>
</div>
);
}

Theme Editor Page

// app/settings/themes/editor/page.tsx
'use client';

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

export default function ThemeEditorPage() {
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;
},
});
};

CSS Variables Integration (Alternative)

For web apps, you can also inject theme as CSS variables:

// lib/utils/applyThemeCSS.ts
export const applyThemeCSS = (theme: Theme) => {
const root = document.documentElement;
const tokens = JSON.parse(theme.themeTokens || '{}');

root.style.setProperty('--color-background', theme.backgroundColor || tokens.colors?.background);
root.style.setProperty('--color-foreground', theme.foregroundColor || tokens.colors?.foreground);
root.style.setProperty('--color-accent', theme.accentColor || tokens.colors?.accent);
// ... more CSS variables
};

Default Theme

Always provide a default theme fallback:

// lib/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-ui, -apple-system, sans-serif',
headingFontFamily: 'system-ui, -apple-system, sans-serif',
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 (WCAG contrast ratios)
  6. Performance: Lazy load theme data, don't block page initialization
  7. Fallback: Always have a default theme ready
  8. SSR: Handle theme loading in Next.js SSR context
  9. Dark Mode: Consider supporting dark mode variants in themes

UI/UX Guidelines

Design System

Colors:

  • Primary: Fishing theme (blues, teals) - customizable via themes
  • Accent: Orange/red for catches, achievements - customizable via themes
  • Neutral: Grays for text, backgrounds - customizable via themes
  • Success: Green for approved actions - customizable via themes
  • Warning: Yellow for pending items - customizable via themes
  • Error: Red for errors - customizable via themes
  • Note: All colors are now user-customizable through the theming system

Typography:

  • Headings: Clear hierarchy - customizable via themes
  • Body: Readable, appropriate sizes - customizable via themes
  • Code: Monospace for technical content
  • Note: Font families and sizes are customizable through themes

Spacing:

  • Consistent spacing scale (4px, 8px, 16px, 24px, 32px) - customizable via themes
  • Responsive spacing for mobile/desktop

Components:

  • Consistent button styles (styled via TamaGUI with theme support)
  • Form inputs with validation
  • Cards for content blocks
  • Modals for actions
  • Toast notifications for feedback

Responsive Design

  • Mobile First: Design for mobile, enhance for desktop
  • Breakpoints: sm (640px), md (768px), lg (1024px), xl (1280px)
  • Touch Targets: Minimum 44x44px for mobile
  • Navigation: Mobile hamburger menu, desktop sidebar/topbar

Accessibility

  • Semantic HTML
  • ARIA labels where needed
  • Keyboard navigation
  • Screen reader support
  • Color contrast (WCAG AA minimum)

API Integration Patterns

API Client Setup

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

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

apiClient.interceptors.request.use(async (config) => {
const token = await getAuthToken();
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
await refreshToken();
return apiClient.request(error.config);
}
return Promise.reject(error);
}
);

React Query Hooks

// hooks/useFishingLog.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { fishingLogApi } from '@/lib/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'] });
},
});
};

Performance Optimization

  • Code Splitting: Lazy load routes/components
  • Image Optimization: Use Next.js Image or similar
  • Caching: Cache API responses appropriately
  • Pagination: Use pagination for large lists
  • Virtual Scrolling: For very long lists
  • Debouncing: For search inputs

SEO Considerations

  • Meta Tags: Proper meta tags for all pages
  • Open Graph: Social sharing tags
  • Structured Data: JSON-LD for rich snippets
  • Sitemap: Generate sitemap
  • Robots.txt: Proper robots.txt

Security

  • XSS Prevention: Sanitize user input
  • CSRF Protection: Use CSRF tokens if needed
  • Secure Storage: Don't store sensitive data in localStorage
  • HTTPS: Always use HTTPS
  • Content Security Policy: Implement CSP headers

Testing

  • Unit Tests: Jest + React Testing Library
  • Integration Tests: Test API integration
  • E2E Tests: Playwright or Cypress
  • Visual Regression: Percy or Chromatic

Deployment

  • Hosting: Vercel (Next.js) or Netlify
  • Environment Variables: Use .env files
  • CI/CD: GitHub Actions or similar
  • Monitoring: Sentry for error tracking
  • Analytics: Google Analytics or Plausible

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
  • Web App Build Prompt - Complete build guide for this web application

Real-Time Updates (SignalR)

Setup

  1. Install package:
npm install @microsoft/signalr
  1. Create SignalR service:
// lib/signalr/socialHub.ts
import * as signalR from '@microsoft/signalr';
import { getAuthToken } from '@/lib/auth';

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

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

this.connection = new signalR.HubConnectionBuilder()
.withUrl(`${process.env.NEXT_PUBLIC_API_URL}/hubs/social`, {
accessTokenFactory: () => token,
})
.withAutomaticReconnect()
.build();

await this.connection.start();
}

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

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 React components:
// components/SocialFeed.tsx
'use client';

import { useEffect } from 'react';
import { socialHub } from '@/lib/signalr/socialHub';
import { useQuery, useQueryClient } from '@tanstack/react-query';

export function SocialFeed() {
const queryClient = useQueryClient();
const { data: posts } = useQuery({
queryKey: ['posts'],
queryFn: () => fetchPosts(),
});

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();
};
}, [queryClient]);

return (
<div>
{posts?.map(post => (
<PostCard key={post.id} post={post} />
))}
</div>
);
}

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.

Key Considerations

  1. Real-time Updates: ✅ SignalR implemented - use for social feed updates
  2. Offline Support: Service workers for offline functionality
  3. Push Notifications: Browser push notifications
  4. File Uploads: Direct S3 uploads or via API
  5. Error Handling: Graceful error handling and user feedback