Manages allocation data and loading states using TanStack Query.
Parameters:
pageId(optional): The page ID to fetch allocation data for
Returns:
{
currentAllocationCents: number;
isLoading: boolean;
error: Error | null;
refetch: () => void;
}Example:
const allocationState = useAllocationState('page-123');
console.log(allocationState.currentAllocationCents); // 500 (= $5.00)Handles allocation changes with intelligent batching and optimistic updates.
Parameters:
pageId(optional): The page ID for allocation actions
Returns:
{
handleAllocationChange: (intervalMultiplier: number, event?: Event) => Promise<void>;
isProcessing: boolean;
lastError: Error | null;
}Example:
const { handleAllocationChange, isProcessing } = useAllocationActions('page-123');
// Increase allocation by $0.50 (using default $0.50 interval)
await handleAllocationChange(1);
// Decrease allocation by $0.50 (using default $0.50 interval)
await handleAllocationChange(-1);
// Increase allocation by $1.00 (2x the default interval)
await handleAllocationChange(2);Manages user allocation interval preferences. The allocation interval determines how much each plus/minus button click changes the allocation amount.
Default Interval: $0.50 (50 cents)
Available Intervals:
- $0.01 (1 cent)
- $0.10 (10 cents)
- $0.50 (50 cents) - Default
- $1.00 (100 cents)
- $5.00 (500 cents)
- $10.00 (1000 cents)
Returns:
{
allocationIntervalCents: number; // Current interval in cents (default: 50)
isLoading: boolean;
setAllocationInterval: (cents: number) => Promise<void>;
}Example:
const { allocationIntervalCents, setAllocationInterval } = useAllocationInterval();
console.log(allocationIntervalCents); // 50 (= $0.50 default)
// Change to $1.00 increments
await setAllocationInterval(100);Full-featured allocation interface with composition bar and controls.
Props:
interface AllocationBarProps {
pageId?: string;
pageTitle?: string;
authorId?: string;
visible?: boolean;
className?: string;
variant?: 'default' | 'simple' | 'user';
isUserAllocation?: boolean;
username?: string;
}Usage:
<AllocationBar
pageId="page-123"
pageTitle="My Article"
authorId="author-456"
variant="default"
/>Simplified allocation bar for embedding within other components.
Props:
interface EmbeddedAllocationBarProps {
pageId: string;
authorId?: string;
pageTitle?: string;
className?: string;
}Usage:
<EmbeddedAllocationBar
pageId="page-123"
authorId="author-456"
className="my-custom-class"
/>Quick allocation interface with preset amount buttons.
Props:
interface SimpleAllocationBarProps {
pageId?: string;
pageTitle?: string;
authorId?: string;
visible?: boolean;
className?: string;
isUserAllocation?: boolean;
username?: string;
}Usage:
<SimpleAllocationBar
pageId="page-123"
pageTitle="Quick Article"
/>Displays allocation amounts with consistent formatting.
Props:
interface AllocationAmountDisplayProps {
allocationCents: number;
availableBalanceCents?: number;
variant?: 'page' | 'user';
className?: string;
flashType?: 'accent' | 'red' | null;
allocationIntervalCents?: number;
}Usage:
<AllocationAmountDisplay
allocationCents={500} // Displays "$5.00/mo to page"
availableBalanceCents={3000} // Shows "Available: $30.00" when allocation is 0
variant="page"
className="text-lg font-bold"
/>Reusable increment/decrement controls.
Props:
interface AllocationControlsProps {
onIncrease: (event: Event) => void;
onDecrease: (event: Event) => void;
canIncrease: boolean;
canDecrease: boolean;
isProcessing: boolean;
className?: string;
}Intelligent request batching and coalescing system.
Configuration:
interface BatcherConfig {
maxBatchSize?: number; // Default: 5
maxWaitTime?: number; // Default: 100ms
minWaitTime?: number; // Default: 10ms
adaptiveDelay?: boolean; // Default: false
enableCoalescing?: boolean; // Default: true
maxRetries?: number; // Default: 2
}Usage:
const batcher = new AllocationBatcher({
maxBatchSize: 10,
maxWaitTime: 200,
enableCoalescing: true
});
// Requests are automatically batched and coalesced
await batcher.batchRequest({
pageId: 'page-123',
changeCents: 100,
source: 'FloatingBar'
});Centralized error handling with user-friendly messages.
Methods:
class AllocationErrorHandler {
static handleAllocationError(error: Error, context: AllocationContext): AllocationErrorResult;
static getErrorFrequency(errorType: string): number;
static shouldShowError(error: Error): boolean;
}Error Types:
INSUFFICIENT_FUNDS: User doesn't have enough balanceNETWORK_ERROR: Connection or server issuesVALIDATION_ERROR: Invalid allocation parametersRATE_LIMIT_ERROR: Too many requestsUNKNOWN_ERROR: Unexpected errors
interface AllocationRequest {
pageId: string;
changeCents: number;
source: 'FloatingBar' | 'EmbeddedBar' | 'QuickActions';
}
interface AllocationResponse {
success: boolean;
currentAllocation: number;
error?: string;
}
interface AllocationState {
currentAllocationCents: number;
isLoading: boolean;
error: Error | null;
}
interface UsdBalance {
totalUsdCents: number;
allocatedUsdCents: number;
availableUsdCents: number;
allocationCount: number;
}interface FloatingAllocationBarProps {
pageId?: string;
pageTitle?: string;
authorId?: string;
visible?: boolean;
className?: string;
}
interface AllocationCompositionData {
totalAllocatedCents: number;
userAllocationCents: number;
isOutOfFunds: boolean;
allocationPercentage: number;
}Fetch current allocation for a page.
Response:
{
currentAllocation: number; // Allocation in cents
}Update allocation for a page.
Request Body:
{
pageId: string;
changeCents: number;
source: string;
}Response:
{
success: boolean;
currentAllocation: number;
error?: string;
}Get user's USD balance information.
Response:
{
totalUsdCents: number;
allocatedUsdCents: number;
availableUsdCents: number;
allocationCount: number;
}// ✅ Good
const allocationState = useAllocationState(pageId);
// ❌ Bad - Don't create custom state management
const [allocation, setAllocation] = useState(0);// ✅ Good
if (allocationState.isLoading) {
return <LoadingSpinner />;
}
// ❌ Bad - Don't ignore loading states
return <div>{allocationState.currentAllocationCents}</div>;// ✅ Good
<ErrorBoundary fallback={<AllocationErrorFallback />}>
<AllocationBar pageId={pageId} />
</ErrorBoundary>// ✅ Good
interface MyComponentProps extends AllocationBarProps {
customProp: string;
}
// ❌ Bad - Don't use any types
const MyComponent = (props: any) => { ... };// Test utilities available
import { mockAllocationState, mockAllocationActions } from '@/test-utils/allocation';
// Mock allocation state for testing
mockAllocationState({
currentAllocationCents: 500,
isLoading: false,
error: null
});// Helper functions for testing
import { renderWithAllocationProviders, createMockAllocationData } from '@/test-utils';This API reference provides comprehensive documentation for developers working with the allocation system. All components, hooks, and utilities follow these established patterns for consistency and maintainability.
- Allocation System Architecture - System architecture and design principles
- Payments and Allocations - Complete payment flow overview
- Financial Data Architecture - Context separation patterns
- Collection Naming Standards - Database collection names for allocations