Admin Panel Frontend Build Prompt
Use this prompt when building the FishingLog Admin Panel web application.
Project Overview
FishingLog Admin Panel is a comprehensive administrative interface for managing the FishingLog platform. It provides tools for user management, content moderation, payment processing, analytics, and system configuration.
Backend API
- Base URL:
https://api.fishinglog.com/api/admin(or configured via environment variable) - Authentication: AWS Cognito JWT Bearer tokens (Admin/Owner roles only)
- User Pool ID:
us-east-2_TZtGx1T3X - Client ID:
6i1opt39o2n5h5ihq471l1ev07 - Swagger Docs: Available at
/swaggerendpoint
Authentication & Authorization
- Admin endpoints require
UserRole.AdminorUserRole.Owner - Owner-only endpoints require
UserRole.Owner - Permission-based endpoints check specific permissions
- Token must be included:
Authorization: Bearer {token}
Recommended Tech Stack
Framework
- React (v18+) with TypeScript
- Next.js (recommended) or Vite + React Router
- TamaGUI (Pro version) - UI component library
- Tailwind CSS - Additional styling
State Management
- TanStack Query (React Query) - Server state
- Zustand - Client state
- React Context - Auth state
Forms & Validation
- react-hook-form - Form management
- zod - Schema validation
- TamaGUI Form Components - Form UI components
Charts & Visualization
- recharts or Chart.js - Charts
- TamaGUI Chart Components - Chart UI components
Data Tables
- TamaGUI Table or TanStack Table - Advanced tables
- Sorting, filtering, pagination built-in
Payments
- @stripe/stripe-js - Stripe integration for refunds
Project Structure
src/
├── app/ # Next.js app directory
│ ├── (auth)/
│ │ ├── login/
│ │ └── layout.tsx
│ ├── admin/
│ │ ├── dashboard/
│ │ ├── users/
│ │ ├── moderation/
│ │ ├── payments/
│ │ ├── feature-flags/
│ │ ├── circles/
│ │ ├── tournaments/
│ │ └── settings/
│ └── api/ # API routes (if needed)
├── components/
│ ├── admin/ # Admin-specific components
│ │ ├── ModerationQueue/
│ │ ├── UserManagement/
│ │ ├── PaymentTable/
│ │ ├── FeatureFlagManager/
│ │ └── Analytics/
│ ├── charts/ # Chart components
│ └── common/ # Shared components
├── lib/
│ ├── api/
│ │ ├── client.ts
│ │ └── endpoints/
│ │ ├── admin.ts
│ │ ├── payments.ts
│ │ └── featureFlags.ts
│ └── auth/
├── hooks/
│ ├── useAdmin.ts
│ ├── usePayments.ts
│ ├── useFeatureFlags.ts
│ └── useModeration.ts
├── store/
│ ├── authStore.ts
│ └── adminStore.ts
└── types/
└── admin.ts
Core Features & Implementation
1. Dashboard
Page: /admin/dashboard
Features:
- System overview statistics
- User growth charts
- Revenue analytics
- Content trends
- Popular content/species
- Geographic data
- Recent activity feed
Key Endpoints:
GET /api/admin/dashboard/overview- System statsGET /api/admin/dashboard/analytics/user-growth- User growthGET /api/admin/dashboard/analytics/revenue- RevenueGET /api/admin/dashboard/analytics/popular- Popular contentGET /api/admin/dashboard/analytics/geographic- Geographic data
Components:
- Stats cards (users, posts, revenue, etc.)
- Line charts (user growth, revenue)
- Bar charts (popular content)
- Map visualization (geographic data)
- Activity timeline
2. User Management
Page: /admin/users
Features:
- List all users with filtering/search
- View user details
- Change user roles
- Update subscription tiers
- View user activity timeline
- Ban/unban users
- Deactivate users
Key Endpoints:
GET /api/admin/users- List usersGET /api/admin/users/{id}- User detailsPUT /api/admin/users/{id}/role- Change rolePUT /api/admin/users/{id}/subscription- Update subscriptionGET /api/admin/users/{id}/activity-timeline- Activity timelinePOST /api/admin/user-bans- Ban userPOST /api/admin/user-bans/{id}/lift- Unban user
Components:
- User table with filters
- User detail modal/page
- Role change form
- Activity timeline component
- Ban form
3. Content Moderation
Page: /admin/moderation
Features:
- Pending review queue
- Approve/reject content
- View AI risk scores
- Override AI decisions
- Moderation statistics
- Moderation settings
Key Endpoints:
GET /api/admin/moderation/pending- Pending itemsPOST /api/admin/moderation/post/{id}/approve- Approve postPOST /api/admin/moderation/post/{id}/reject- Reject postGET /api/admin/moderation/statistics- StatisticsGET /api/admin/moderation-settings- SettingsPUT /api/admin/moderation-settings- Update settings
Components:
- Moderation queue table
- Content preview card
- Risk score indicator
- Category tags
- Approve/reject buttons
- Settings form
4. Payment Management
Page: /admin/payments
Features:
- List all payments (tournaments, bookings, advertisers)
- Filter by type, status, date range
- View failed payments
- Process refunds via Stripe API
- Payment statistics
- Export payment data
- View Stripe payment details
Key Endpoints:
GET /api/admin/payments- List paymentsGET /api/admin/payments/failed- Failed paymentsGET /api/admin/payments/statistics- StatisticsPOST /api/admin/payments/tournament-registration/{id}/refund- Process refund
Stripe Integration:
- Real refund processing through Stripe API
- Refund amount validation
- Refund reason tracking
- Audit logging with Stripe refund IDs
- See
stripe-integration.mdfor implementation details
Components:
- Payment table with Stripe status
- Payment detail modal (shows Stripe payment intent ID, charge ID)
- Refund form (amount, reason)
- Payment statistics cards
- Export button
- Stripe payment link (open in Stripe Dashboard)
Implementation Example:
// components/admin/PaymentTable.tsx
import { useMutation } from '@tanstack/react-query';
function RefundButton({ registrationId }: { registrationId: number }) {
const refundMutation = useMutation({
mutationFn: async ({ amount, reason }: { amount?: number; reason: string }) => {
const response = await fetch(
`/api/admin/payments/tournament-registration/${registrationId}/refund`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ amount, reason })
}
);
return response.json();
},
onSuccess: () => {
// Show success toast
// Invalidate payments query
}
});
return (
<Button onClick={() => refundMutation.mutate({ reason: 'Customer request' })}>
Process Refund
</Button>
);
}
5. Feature Flags Management
Page: /admin/feature-flags
Features:
- List all feature flags
- Enable/disable features per environment (Development, Staging, Production)
- View current environment status
- Set rollout percentages
- Target specific users for beta testing
- View feature flag history
- Filter by category
Key Endpoints:
GET /api/admin/feature-flags- List all flagsGET /api/admin/feature-flags/{key}- Get specific flagGET /api/admin/feature-flags/current-environment- Get current environment flagsPOST /api/admin/feature-flags- Create new flagPUT /api/admin/feature-flags/{key}- Update flagDELETE /api/admin/feature-flags/{key}- Delete flag
Feature Flag Data:
interface FeatureFlag {
id: number;
key: string; // e.g., "Circles"
name: string;
description?: string;
category?: string;
isEnabledInDevelopment: boolean;
isEnabledInStaging: boolean;
isEnabledInProduction: boolean;
isEnabledInCurrentEnvironment: boolean;
currentEnvironment: string;
rolloutPercentage?: number; // 0-100
targetUserIds?: string[]; // Beta testing
isActive: boolean;
lastEnabledAt?: string;
lastDisabledAt?: string;
createdAt: string;
updatedAt: string;
}
Components:
- Feature flags table with environment toggles
- Feature flag edit form
- Environment status badges
- Rollout percentage slider
- User targeting selector
- Category filter
- Current environment indicator
Implementation Example:
// components/admin/FeatureFlagManager.tsx
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
export function FeatureFlagManager() {
const queryClient = useQueryClient();
const { data: flags } = useQuery({
queryKey: ['admin', 'featureFlags'],
queryFn: async () => {
const response = await fetch('/api/admin/feature-flags', {
headers: { 'Authorization': `Bearer ${token}` }
});
return response.json();
}
});
const updateFlag = useMutation({
mutationFn: async ({ key, updates }: { key: string; updates: Partial<FeatureFlag> }) => {
const response = await fetch(`/api/admin/feature-flags/${key}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(updates)
});
return response.json();
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'featureFlags'] });
queryClient.invalidateQueries({ queryKey: ['featureFlags'] }); // Invalidate frontend cache
}
});
return (
<Table>
{flags?.map(flag => (
<TableRow key={flag.key}>
<TableCell>{flag.name}</TableCell>
<TableCell>
<Switch
checked={flag.isEnabledInDevelopment}
onCheckedChange={(checked) => updateFlag.mutate({
key: flag.key,
updates: { isEnabledInDevelopment: checked }
})}
/>
</TableCell>
<TableCell>
<Switch
checked={flag.isEnabledInStaging}
onCheckedChange={(checked) => updateFlag.mutate({
key: flag.key,
updates: { isEnabledInStaging: checked }
})}
/>
</TableCell>
<TableCell>
<Switch
checked={flag.isEnabledInProduction}
onCheckedChange={(checked) => updateFlag.mutate({
key: flag.key,
updates: { isEnabledInProduction: checked }
})}
/>
</TableCell>
<TableCell>
<Badge color={flag.isEnabledInCurrentEnvironment ? 'green' : 'red'}>
{flag.isEnabledInCurrentEnvironment ? 'Enabled' : 'Disabled'}
</Badge>
</TableCell>
</TableRow>
))}
</Table>
);
}
6. Circle Management
Page: /admin/circles
Features:
- List all circles with filtering
- View circle details (members, applications, rules)
- Update circle settings (admin override)
- Delete circles (admin override)
- Transfer circle ownership
- View circle statistics
Key Endpoints:
GET /api/admin/circles- List circlesGET /api/admin/circles/{id}- Get circle detailsPUT /api/admin/circles/{id}- Update circle settingsDELETE /api/admin/circles/{id}- Delete circlePOST /api/admin/circles/{id}/transfer-ownership- Transfer ownership
7. Tournament Management
Page: /admin/tournaments
Features:
- List tournaments
- Approve/reject tournaments
- View tournament details
- Monitor registrations
- View financial summaries
- Manage tournament organizers
Key Endpoints:
GET /api/admin/tournaments- List tournamentsGET /api/admin/tournaments/{id}- Tournament detailsPOST /api/admin/tournaments/{id}/approve- Approve tournamentGET /api/admin/tournaments/{id}/financial-summary- Financial summary
8. System Settings
Page: /admin/settings (Owner only)
Features:
- Manage system settings
- Configure AI moderation
- Manage site announcements
- View audit logs
- Manage employees and permissions
Key Endpoints:
GET /api/admin/system-settings- List settingsPUT /api/admin/system-settings/{key}- Update settingGET /api/admin/moderation-settings- Moderation settingsGET /api/admin/audit-logs- Audit logs
API Client Setup
// lib/api/client.ts
import axios from 'axios';
export const adminApiClient = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL || 'https://api.fishinglog.com/api',
});
adminApiClient.interceptors.request.use(async (config) => {
const token = await getAuthToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
adminApiClient.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
// Redirect to login
window.location.href = '/login';
}
if (error.response?.status === 403) {
// Show "Access Denied" message
showError('You do not have permission to perform this action');
}
return Promise.reject(error);
}
);
React Query Hooks
// hooks/usePayments.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { adminApiClient } from '@/lib/api/client';
export function usePayments(filters?: PaymentFilters) {
return useQuery({
queryKey: ['admin', 'payments', filters],
queryFn: async () => {
const response = await adminApiClient.get('/admin/payments', { params: filters });
return response.data;
}
});
}
export function useRefundPayment() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ id, amount, reason }: RefundRequest) => {
const response = await adminApiClient.post(
`/admin/payments/tournament-registration/${id}/refund`,
{ amount, reason }
);
return response.data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'payments'] });
}
});
}
Environment Variables
NEXT_PUBLIC_API_URL=https://api.fishinglog.com/api
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
NEXT_PUBLIC_COGNITO_USER_POOL_ID=us-east-2_TZtGx1T3X
NEXT_PUBLIC_COGNITO_CLIENT_ID=6i1opt39o2n5h5ihq471l1ev07
UI/UX Guidelines
Design System
- Layout: Sidebar navigation (collapsible), top bar with user info
- Colors: Primary (admin blue), Success (green), Warning (yellow), Error (red)
- Components: Data tables, cards, charts, modals, forms, toast notifications
Key UI Patterns
- Tables: Sortable, filterable, paginated, row actions, bulk actions
- Forms: Clear labels, validation feedback, loading states
- Modals: Confirmation dialogs for destructive actions
- Charts: Interactive charts with tooltips, date range selection
Implementation Checklist
Phase 1: Foundation
- Initialize Next.js project with TypeScript
- Set up TamaGUI and Tailwind CSS
- Configure API client with auth interceptors
- Set up TanStack Query
- Create auth context/provider
- Implement protected routes (admin only)
- Set up error handling and toast notifications
Phase 2: Core Admin Features
- Build dashboard with statistics and charts
- Implement user management (list, view, edit, ban)
- Build content moderation queue
- Create payment management with Stripe refunds
- Implement feature flags management
- Build circle management interface
Phase 3: Advanced Features
- Tournament management
- System settings (owner only)
- Analytics and reporting
- Audit log viewer
- Export functionality
Phase 4: Polish
- Add loading states everywhere
- Implement error boundaries
- Add confirmation dialogs
- Optimize performance
- Add keyboard shortcuts
- Implement bulk operations
Critical Implementation Notes
Stripe Refunds
- Always validate refund amount (cannot exceed original payment)
- Require refund reason for audit trail
- Show Stripe refund ID after successful refund
- Handle refund errors gracefully (insufficient funds, etc.)
- Update UI immediately after refund (optimistic update)
Feature Flags
- Invalidate frontend cache when flags are updated
- Show environment indicator clearly
- Require confirmation for production changes
- Log all flag changes in audit log
- Show current environment prominently
Security
- Verify admin role on every page load
- Handle 403 errors gracefully
- Never expose sensitive data in frontend
- Use HTTPS always
- Implement rate limiting awareness
Testing
Stripe Refunds
- Test successful refunds
- Test partial refunds
- Test refund errors (invalid charge ID, etc.)
- Verify refund appears in Stripe Dashboard
Feature Flags
- Test flag toggles for each environment
- Test flag creation/deletion
- Verify cache invalidation
- Test rollout percentage changes
Documentation References
- Admin Panel Guide:
docs/frontend/admin-panel.md - Stripe Integration:
docs/frontend/stripe-integration.md - Feature Flags:
docs/frontend/feature-flags.md - Backend API:
docs/api/admin-api.md
Success Criteria
A successful admin panel implementation should:
- ✅ Require admin authentication
- ✅ Handle all admin endpoints correctly
- ✅ Process Stripe refunds successfully
- ✅ Manage feature flags effectively
- ✅ Provide clear visual feedback
- ✅ Handle errors gracefully
- ✅ Be responsive and performant
- ✅ Follow accessibility best practices