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
- User authenticates via AWS Cognito (use
@aws-amplify/authoramazon-cognito-identity-js) - Receive JWT token from Cognito
- Include token in all API requests:
Authorization: Bearer {token} - Token expires - refresh using Cognito refresh token
Recommended Tech Stack
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.mdfor 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 entriesPOST /api/fishinglog/entries- Create entryGET /api/fishinglog/entries/{id}- Get entryPUT /api/fishinglog/entries/{id}- Update entryPOST /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 catalogGET /api/gear/setups- User setupsPOST /api/gear/setups- Create setupGET /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 feedPOST /api/social/posts- Create postPOST /api/social/posts/{id}/like- Like postPOST /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 tournamentsGET /api/tournament/{id}- Tournament detailsPOST /api/tournament/{tournamentId}/register- RegisterGET /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 regulationsGET /api/regulations/master-angler/{stateId}- Master AnglerGET /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 PBsGET /api/personalbest/me/criteria- Get criteriaPOST /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 spotsGET /api/reports/by-location- ReportsPOST /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 userGET /api/circle/memberships- Get circles user is a member ofGET /api/circle/discover- Discover public circles (searchable, paginated)GET /api/circle/{id}- Get circle detailsPOST /api/circle- Create a new circlePUT /api/circle/{id}- Update circle (owner/admin only)DELETE /api/circle/{id}- Delete circle (owner only)POST /api/circle/{id}/join- Join a public circlePOST /api/circle/{id}/leave- Leave a circlePOST /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 applicationPOST /api/circle/{id}/applications/{applicationId}/reject- Reject applicationPOST /api/circle/{id}/applications/{applicationId}/withdraw- Withdraw own applicationGET /api/circle/{id}/members- Get circle membersPOST /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 contributorsGET /api/circle/{id}/rules- Get circle rulesPUT /api/circle/{id}/rules- Update circle rules (owner/admin only)POST /api/circle/{id}/rules/test- Test if content matches rulesPOST /api/social/posts/{id}/share-to-circles- Auto-share post to matching circlesPOST /api/fishinglog/entries/{id}/share-to-circles- Auto-share log entry to matching circles
Key Features:
-
Circle Roles (like Facebook groups):
Owner- Full control, can transfer ownershipAdmin- Can manage members, applications, settingsModerator- Can approve/reject applications, remove membersMember- Standard member
-
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
- Circles can require approval to join (
-
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
-
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
-
Circle Types:
IsPublic: true- Discoverable, anyone can join (if no approval required)IsPublic: false- Private, invite-onlyRequiresApproval: true- Application requiredRequiresApproval: 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 profilePUT /api/userprofile/me- Update profileGET /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 themeGET /api/theme/me- Get current user's active themePOST /api/theme- Create a new themePUT /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 userDELETE /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
- Cache Themes: Cache user theme to avoid repeated API calls
- Theme Preview: Show theme preview before applying
- Theme Gallery: Create a gallery of public themes for discovery
- Theme Templates: Provide theme templates for quick setup
- Accessibility: Ensure themes maintain accessibility standards (WCAG contrast ratios)
- Performance: Lazy load theme data, don't block page initialization
- Fallback: Always have a default theme ready
- SSR: Handle theme loading in Next.js SSR context
- 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.mdfor complete API documentation - See backend
README.mdfor 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
- Install package:
npm install @microsoft/signalr
- 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();
- 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 createdPostLiked- Post likedPostUnliked- Post unlikedCommentAdded- Comment added
NotificationHub:
NotificationReceived- New notification
See docs/infrastructure/real-time-updates-strategy.md for complete details.
Key Considerations
- Real-time Updates: ✅ SignalR implemented - use for social feed updates
- Offline Support: Service workers for offline functionality
- Push Notifications: Browser push notifications
- File Uploads: Direct S3 uploads or via API
- Error Handling: Graceful error handling and user feedback