# Unified Comments System This directory contains a unified comments system that consolidates all comment functionality across different contexts (feed, groups, acknowledgements, marketplace, and news) into a single, reusable component. ## Overview The unified comments system consists of: - **`CommentsSystem.tsx`** - Main component that orchestrates the entire comments system - **`CommentList.tsx`** - Renders lists of comments with pagination - **`CommentItem.tsx`** - Unified component that renders individual comments and their replies for all contexts (including groups) - **`Comment.tsx`** - Core comment rendering component that detects and handles group context automatically - **`ChildCommentList.tsx`** - Renders child comments with pagination - **`types.ts`** - TypeScript definitions for all components and handlers - **`commentConfigs.ts`** - Context-specific configurations for queries and mutations - **`commentPermissions.ts`** - Permission calculation utilities for comment actions - **`useCommentsSystem.ts`** - Hook for data fetching and state management - **`useCommentHandlers.ts`** - Hook for cache update handlers and user interactions ## Recent Architectural Changes ### Complete Comments System Unification (October 2025) The comments system has been fully unified across all contexts through multiple refactoring phases: #### Phase 1: Component Consolidation - **Deleted**: `GroupCommentItem.tsx` - merged into `CommentItem.tsx` - **Enhanced**: `CommentItem.tsx` now handles both standard and group contexts through conditional rendering - **Simplified**: Props have been standardized across all comment components - **Behavior Change**: Child comments are no longer auto-loaded; they must be explicitly requested by the user #### Phase 2: Core Component Unification - **Deleted**: `GroupComment.tsx` and `GroupChildCommentList.tsx` - merged into unified components - **Enhanced**: `Comment.tsx` now detects group context via `PostContext` and handles group permissions internally using `useGroupMember` hook - **Simplified**: `CommentItem.tsx` no longer needs conditional branching between group and non-group contexts - **Added**: `commentPermissions.ts` - centralized permission calculation logic #### Phase 3: Handler Clarification & Performance - **Renamed**: Comment handlers now clearly indicate they update cache (not server): `handleDeleteSuccess`, `handleEditSuccess`, `handleAddReactionSuccess`, `handleRemoveReactionSuccess` - **Performance**: Improved cache invalidation for paginated comments - **Behavior Change**: New comments now appear at the top (unshift) instead of bottom (push) for better UX - **Feature**: Added `shouldAutoLoad` option for paginated comments (currently enabled for articles/news context) This consolidation eliminates code duplication while maintaining context-specific functionality through conditional logic within a single set of unified components. ### How the Unified Architecture Works The comments system uses multiple layers to provide type-safe, context-specific rendering: #### CommentItem Layer Uses TypeScript discriminated unions to ensure correct props based on context: ```typescript type GroupVariantProps = { context: 'groups'; CustomPeopleList?: React.ComponentType; isGroupArchived?: boolean; userIsMember?: boolean; isGroupAdmin?: boolean; canManageComments?: never; canReact?: never; }; type StandardVariantProps = { context: 'feed' | 'articles' | 'acknowledgements' | 'marketplace'; canManageComments: boolean; canReact: boolean; CustomPeopleList?: never; }; ``` #### Comment Component Layer Automatically detects group context and calculates permissions: ```typescript const { groupId } = usePost(); // From PostContext const groupMemberContext = useGroupMember(); const isGroupContext = groupId !== undefined; // Permissions are calculated based on context const canManageComments = isGroupContext ? loggedUser?.id === user.id || groupMemberContext.isGroupAdmin : canManageCommentsProp ?? false; ``` This architecture provides: - **Type Safety**: Props are validated at compile-time based on context - **Single Source of Truth**: Unified components handle all contexts - **Context-Specific Features**: Groups use custom people lists and member checks, other contexts use explicit permissions - **Automatic Context Detection**: No need for manual context switching - **Cleaner Codebase**: Eliminated separate group-specific components ## Key Benefits 1. **Code Reusability**: Single set of components (`CommentItem`, `Comment`, `ChildCommentList`) handles all comment contexts including groups 2. **Type Safety**: Comprehensive TypeScript definitions with discriminated unions for context-specific props 3. **Maintainability**: Centralized logic reduces duplication - eliminated all group-specific comment components 4. **Consistency**: Unified behavior across all comment systems with context-specific adaptations 5. **Flexibility**: Context-specific configurations preserve domain distinctions through conditional rendering 6. **Simplified Architecture**: Fewer components to maintain while supporting all use cases 7. **Clear Responsibility**: Handler names clearly indicate cache update operations vs. server mutations 8. **Better UX**: New comments appear at the top for immediate visibility ## Migration Guide ### Migration Status The new components are drop-in replacements that maintain the same external API while using the unified system internally. No changes are needed in parent components - they can continue using the same imports and props. ### Example Usage (No Changes Required): ```tsx // This continues to work exactly the same import PostComments from './PostComments'; ; ``` The old components are preserved as `*Old.tsx` files for reference and can be safely deleted once the new system is verified in production. ### Technical Details of Recent Changes #### Context Detection The `Comment.tsx` component now automatically detects group context: ```typescript const { groupId } = usePost(); // From PostContext const groupMemberContext = useGroupMember(); const isGroupContext = groupId !== undefined; // Permissions are calculated based on context const canManageComments = isGroupContext ? loggedUser?.id === user.id || groupMemberContext.isGroupAdmin : canManageCommentsProp ?? false; const canReact = isGroupContext ? groupMemberContext.userIsMember && !groupMemberContext.isGroupArchived : canReactProp ?? false; ``` This eliminates the need for separate group-specific comment components. #### Context-Specific Rendering in CommentItem The component uses discriminated unions for type-safe context handling: ```typescript type GroupVariantProps = { context: 'groups'; CustomPeopleList?: React.ComponentType; isGroupArchived?: boolean; userIsMember?: boolean; isGroupAdmin?: boolean; canManageComments?: never; canReact?: never; }; type StandardVariantProps = { context: 'feed' | 'articles' | 'acknowledgements' | 'marketplace'; canManageComments: boolean; canReact: boolean; CustomPeopleList?: never; }; ``` This ensures TypeScript enforces correct props based on context at compile time. #### Cache Update Handlers Handlers have been renamed to clarify their role in cache management rather than server mutation: ```typescript // These handlers update the React Query cache after successful mutations handleDeleteSuccess: (commentId: number, parentId: number | null) => void; handleEditSuccess: (comment: CommentType) => void; handleAddReactionSuccess: (commentId, parentId, emoji, unified) => void; handleRemoveReactionSuccess: (commentId, parentId, emoji) => void; ``` The actual server mutations are handled by React Query mutation functions, while these handlers ensure the cache stays synchronized. ## Configuration The system uses `commentConfigs.ts` to define context-specific behavior: - **Query configurations**: Different endpoints and parameters per context - **Mutation configurations**: Context-specific success callbacks that handle cache updates - **Cache update handlers**: Optimistic updates and cache synchronization after mutations - **Component mappings**: Custom components for different contexts ### Key Configuration Features - **Builder pattern**: Configuration objects are created via builder functions for consistency - **Cache updates**: New comments are prepended (unshift) to appear at the top for better visibility - **Context-specific services**: Each context (feed, groups, acknowledgements, marketplace, news) uses its own service methods - **Flexible pagination**: Supports both auto-load and manual load patterns per context This allows the unified system to maintain all domain-specific functionality while providing a consistent interface.