CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
This is the React frontend application for Sprout's Listings Engine - a ticket purchasing and reselling platform. It provides interfaces for ticket inventory management, purchase workflows, and administrative functions.
Commands
Development
# Start development server (port 5173)
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Run linting
npm run lint
# Type checking only
npx tsc --noEmit
Docker Development
# Build and run in Docker
docker build -t sprout-app .
docker run -p 5173:5173 sprout-app
Architecture
Technology Stack
- Frontend: React 18.3 + TypeScript
- Build Tool: Vite 5.4
- Styling: Tailwind CSS + Shadcn UI components
- State Management: TanStack Query (React Query) for server state
- Routing: React Router DOM v6
- Forms: React Hook Form + Zod validation
- Search: MeiliSearch integration
Directory Structure
src/
├── components/ # Reusable UI components
│ └── ui/ # Shadcn UI components
├── views/ # Page-level components
│ ├── Admin/
│ ├── ClaimPurchases/
│ ├── PendingFulfillment/
│ └── TicketMaster/
├── context/ # React Context providers (auth)
├── hooks/ # Custom React hooks
├── lib/ # Utilities and external integrations
├── config.ts # App configuration
└── App.tsx # Main app with routing
Key Architectural Patterns
-
API Integration:
- Direct
fetchcalls wrapped in React Query hooks - JWT authentication with Bearer tokens
- All API logic in feature-specific
hooks.tsfiles
- Direct
-
Authentication Flow:
- Google OAuth via backend redirect
- JWT tokens stored in localStorage
- Auth context provides user state and token management
- Protected routes with role-based access control
-
Data Fetching Pattern:
// Standard pattern in hooks.ts files
export const useDataHook = (params) => {
const { token } = useAuth();
return useQuery({
queryKey: ['data-key', ...params],
queryFn: async () => {
const response = await fetch(`${API_URL}/endpoint`, {
headers: { Authorization: `Bearer ${token}` }
});
if (!response.ok) throw new Error('Failed');
return response.json();
},
enabled: !!token
});
}; -
Component Structure:
- Functional components only (no classes)
- Named exports for all functions
- Co-located types in
types.tsfiles - Desktop-first responsive design
Integration with Backend Services
This frontend connects to the main Sprout backend services:
- Main API:
VITE_BACKEND_API_URL(typically port 3000) - MeiliSearch:
VITE_MEILISEARCH_HOSTfor search functionality
The backend architecture includes:
- NestJS server with REST API
- PostgreSQL database with Prisma ORM
- Redis/BullMQ for queue processing
- ETL service for ticket inventory
- Skybox token extractor for VividSeats auth
Development Guidelines
Code Style
- Functional programming patterns (avoid classes)
- TypeScript interfaces over types
- Lowercase with dashes for directories
- Descriptive variable names
- DRY principles
UI/UX
- Shadcn components with Tailwind utilities
- Desktop-first responsive design
- Toast notifications for user feedback
- Loading states via React Query
Performance
- Dynamic imports for code splitting
- React.memo for expensive components
- TanStack Query for efficient data caching
- Debounced search inputs
Common Tasks
Adding a New Feature
- Create view directory in
src/views/ - Add route in
App.tsx - Create
hooks.tsfor API calls - Define types in
types.ts - Build UI with Shadcn components
Working with API
- Add endpoint configuration in feature's
hooks.ts - Use React Query for data fetching
- Include JWT token in Authorization header
- Handle errors with toast notifications
Styling Components
- Use Tailwind utility classes
- Follow Shadcn component patterns
- Use
cn()utility for conditional classes - Keep responsive design desktop-first
Environment Variables
VITE_BACKEND_API_URL=http://localhost:3000/api
VITE_MEILISEARCH_HOST=http://localhost:7700
VITE_MEILISEARCH_API_KEY=your-key
VITE_ENV=development
Important Notes
- No test framework is currently configured
- Authentication state persists in localStorage
- All API errors should show toast notifications
- Role-based routes are defined in
config.ts - The app expects backend services to be running (see parent CLAUDE.md)