Frontend State Management
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Frontend state management in SoulSeer is handled through a combination of React Context for global, persistent state and local component state for UI-specific data. The architecture focuses on real-time updates via WebSockets and structured data synchronization between the client and the backend API.
The system manages critical domains including user authentication status, real-time communication events, community forum interactions, and administrative oversight. By utilizing TypeScript interfaces and shared validators, the frontend ensures data consistency across these various stateful domains.
Global State Providers
Global state is distributed through React Context providers that wrap the application, ensuring that core services like authentication and real-time messaging are accessible to all components.
WebSocket Context
The WebSocketContext acts as a real-time push channel. It manages the lifecycle of the WebSocket connection, including authentication via Auth0 tokens and automatic exponential backoff reconnection logic.
The provider maintains a registry of listeners and dispatches incoming messages based on their type field. Components interact with this state using a subscribe function that returns an unsubscribe cleanup routine.
| Feature | Implementation Detail |
|---|---|
| Ping Interval | 25,000ms |
| Initial Reconnect | 1,000ms |
| Max Reconnect | 30,000ms |
| Event Dispatch | Map of Sets for O(1) listener lookups |
Sources: client/src/contexts/WebSocketContext.tsx:16-43, client/src/contexts/WebSocketContext.tsx:145-165
Authentication State
The AuthState interface defines the core user data structure used throughout the application. It synchronizes Auth0 profile data with the local database to manage specialized roles and balances.
| Field | Type | Description |
|---|---|---|
user | User | null | The currently logged-in user object. |
isAuthenticated | boolean | Flag for current login status. |
isLoading | boolean | Flag for active auth verification. |
balance | number | User funds in cents (alias for accountBalance). |
Sources: client/src/types/index.ts:7-24
Component-Level State Management
Local state is heavily utilized for managing asynchronous data fetching, form inputs, and UI transitions.
Asynchronous Data Loading
Pages such as the CommunityHubPage and AdminDashboard use useState and useEffect patterns to manage remote data fetching. This includes handling loading indicators and error states.
Form and Modal State
Complex forms, such as the Reader Creation form in the Admin Dashboard, manage nested object states to ensure atomic updates before submission. Modals use boolean flags or object-referential state (e.g., editUser) to control visibility and context.
| Component | State Managed | Purpose |
|---|---|---|
CommunityHubPage | newTitle, newContent, newCategory | Post creation form. |
AdminDashboard | editUser, editForm | Modal-based reader profile updates. |
ReaderProfilePage | startingType | Tracks active reading request type (chat/voice/video). |
Sources: client/src/pages/dashboard/AdminDashboard.tsx:64-96, client/src/pages/readers/ReaderProfilePage.tsx:34-40
Data Validation and Type Safety
State integrity is maintained through shared validators and TypeScript types. This prevents the state from being populated with malformed data from API responses or user input.
Shared Validators
The project uses zod schemas to validate data structures before they are committed to the state or sent to the server.
// Example from shared/src/validators.ts
export const readingTypeSchema = z.enum(["chat", "voice", "video"]);
export const createForumPostSchema = z.object({
title: z.string().min(1).max(200),
content: z.string().min(1).max(10_000),
category: forumCategorySchema,
});
Sources: shared/src/validators.ts:16-118
Type Definitions
Centralized type definitions in client/src/types/index.ts ensure that components across the monorepo share a common understanding of entities like User, Reading, and Transaction.
Sources: client/src/types/index.ts:7-122
Summary
SoulSeer's frontend state management utilizes a reactive architecture where global concerns (Auth, Real-time) are isolated in Context Providers, while operational data (Forums, Admin tasks) is managed within local component scopes. This separation, combined with strict TypeScript typing and shared Zod validation, creates a robust environment for managing the complex, real-time interactions required by the platform.