# Social Features - LinkedIn/Facebook Style Following ## Overview The platform now includes comprehensive social networking features inspired by LinkedIn and Facebook, allowing users to follow and engage with: 1. **Leaders** - Elected officials, decision makers, community advocates 2. **Organizations** - Nonprofits, charities, government agencies 3. **Causes** - Policy topics and issues (oral health, housing, education, etc.) 4. **Other Users** - Fellow community members and advocates --- ## 🎯 Features ### Follow System - βœ… One-click follow/unfollow buttons (LinkedIn/Facebook style) - βœ… Hover effects ("Following" β†’ "Unfollow") - βœ… Real-time follower counts - βœ… Optimistic UI updates - βœ… Persistent follow state across sessions ### Profile Page - βœ… User profile with avatar, bio, location - βœ… Follower/following statistics - βœ… Tabbed interface showing: - Leaders you're following - Charities you're following - Causes you care about - βœ… Breakdown by category (e.g., "Following 5 leaders, 3 charities, 2 causes") ### Social Stats Component - βœ… Displays follower/following counts - βœ… Shows breakdown of what user follows - βœ… Clickable to view full lists - βœ… LinkedIn-style presentation --- ## πŸ“Š Database Schema ### New Tables #### `leaders` Public officials and decision makers - `id` - Primary key - `name`, `slug` - Identity - `title`, `office` - Position details - `city`, `state`, `jurisdiction` - Location - `email`, `phone`, `website` - Contact - `twitter`, `linkedin`, `facebook` - Social media - `follower_count` - Denormalized count - `is_verified` - Verification badge #### `organizations` Nonprofits, charities, advocacy groups - `id` - Primary key - `name`, `slug` - Identity - `description`, `logo_url` - Branding - `org_type` - 'nonprofit', 'government', 'advocacy', 'charity' - `city`, `state`, `address` - Location - `ein`, `ntee_code`, `revenue` - IRS data - `follower_count` - Denormalized count - `is_verified` - Verification badge #### `causes` Policy topics and issues - `id` - Primary key - `name`, `slug` - Identity - `description`, `icon_url`, `color` - Visual identity - `category` - 'health', 'education', 'housing', 'environment', etc. - `follower_count` - Denormalized count #### Follow Relationship Tables All use composite unique constraints to prevent duplicate follows: - `user_follows` - User β†’ User relationships - `leader_follows` - User β†’ Leader relationships - `organization_follows` - User β†’ Organization relationships - `cause_follows` - User β†’ Cause relationships Each contains: - `user_id` - Foreign key to users - `{entity}_id` - Foreign key to entity - `created_at` - Timestamp --- ## πŸ”Œ API Endpoints ### Follow Actions ```http POST /api/social/follow/user/{user_id} # Follow a user DELETE /api/social/follow/user/{user_id} # Unfollow a user POST /api/social/follow/leader/{leader_id} # Follow a leader DELETE /api/social/follow/leader/{leader_id} # Unfollow a leader POST /api/social/follow/organization/{org_id} # Follow an organization DELETE /api/social/follow/organization/{org_id} # Unfollow an organization POST /api/social/follow/cause/{cause_id} # Follow a cause DELETE /api/social/follow/cause/{cause_id} # Unfollow a cause ``` **Response:** ```json { "success": true, "following": true, "follower_count": 1234, "message": "Successfully followed leader" } ``` ### Check Following Status ```http GET /api/social/following/status?user_id=1&leader_id=2&org_id=3&cause_id=4 ``` **Response:** ```json { "user": false, "leader": true, "organization": true, "cause": false } ``` ### Get Statistics ```http GET /api/social/stats # Current user's stats GET /api/social/stats?user_id=123 # Another user's stats ``` **Response:** ```json { "followers": 150, "following": 42, "following_users": 10, "following_leaders": 15, "following_organizations": 12, "following_causes": 5 } ``` ### Get Following Lists ```http GET /api/social/following/leaders # Leaders you follow GET /api/social/following/organizations # Organizations you follow GET /api/social/following/causes # Causes you follow ``` **Response (Leaders):** ```json [ { "id": 1, "name": "Jane Smith", "slug": "jane-smith", "title": "Mayor", "office": "Office of the Mayor", "city": "Tuscaloosa", "state": "AL", "photo_url": "https://...", "follower_count": 1542, "is_verified": true } ] ``` --- ## 🎨 UI Components ### FollowButton Component **Location:** `frontend/src/components/FollowButton.tsx` **Props:** ```typescript interface FollowButtonProps { type: 'user' | 'leader' | 'organization' | 'cause' id: number initialFollowing?: boolean initialCount?: number showCount?: boolean compact?: boolean onFollowChange?: (following: boolean, count: number) => void } ``` **Usage:** ```tsx // Compact button (for cards) // Full button with count ``` **Features:** - LinkedIn-style hover effect: "Following" β†’ "Unfollow" (red) - Blue button when not following - White button with check mark when following - Loading spinner during API calls - Optimistic UI updates ### SocialStats Component **Location:** `frontend/src/components/SocialStats.tsx` **Props:** ```typescript interface SocialStatsProps { userId?: number // Optional, defaults to current user showBreakdown?: boolean // Show category breakdown clickable?: boolean // Link to profile page } ``` **Usage:** ```tsx // Show current user's stats // Show another user's stats ``` **Features:** - Displays follower/following counts - Shows breakdown by category (leaders, charities, causes, people) - Colored category badges - Links to profile page (optional) --- ## πŸ“± Pages ### Profile Page **Route:** `/profile` **Location:** `frontend/src/pages/Profile.tsx` **Features:** - User avatar and basic info - Social statistics with breakdown - Tabbed interface: - **Leaders** - Grid of leader cards with follow buttons - **Charities** - Grid of organization cards with follow buttons - **Causes** - Grid of cause cards with follow buttons - Empty states with CTAs ("Find leaders to follow β†’") - Verification badges for verified entities ### Find Leaders Page (Updated) **Route:** `/people` **Location:** `frontend/src/pages/PeopleFinder.tsx` **Changes:** - Added follow button to each person card - Shows follower count - LinkedIn-style card layout with separator - Follow button at bottom of each card --- ## πŸš€ Migration ### Run Database Migration ```bash cd /home/developer/projects/open-navigator source .venv/bin/activate python scripts/migrate_social_features.py ``` **Output:** ``` βœ… Social features tables created successfully! πŸ“Š New tables: βœ“ leaders - Public officials and decision makers βœ“ organizations - Nonprofits and charities βœ“ causes - Policy topics and issues βœ“ user_follows - Userβ†’User follows βœ“ leader_follows - Userβ†’Leader follows βœ“ organization_follows - Userβ†’Organization follows βœ“ cause_follows - Userβ†’Cause follows πŸŽ‰ Migration complete! Social features are ready to use. ``` --- ## πŸ“ Next Steps ### 1. Seed Data Create seed data for leaders, organizations, and causes: ```python # scripts/seed_social_data.py from api.models import Leader, Organization, Cause from api.database import SessionLocal db = SessionLocal() # Add Tuscaloosa Mayor leader = Leader( name="Walter Maddox", slug="walter-maddox", title="Mayor", office="Office of the Mayor", city="Tuscaloosa", state="Alabama", jurisdiction="City of Tuscaloosa", email="mayor@tuscaloosa.com", follower_count=0, is_verified=True ) db.add(leader) # Add causes causes = [ Cause( name="Oral Health", slug="oral-health", description="Access to dental care and oral health education", category="health", color="#354F52", follower_count=0 ), Cause( name="Affordable Housing", slug="affordable-housing", description="Creating affordable housing opportunities", category="housing", color="#52796F", follower_count=0 ), # Add more... ] db.add_all(causes) db.commit() ``` ### 2. Activity Feed Create a feed showing updates from followed entities: - New meeting minutes from followed leaders - Updates from followed organizations - News about followed causes ### 3. Notifications Notify users when: - Someone follows them - A followed leader posts something - A followed organization has an update - Activity on a followed cause ### 4. Recommendations Suggest who to follow based on: - Location (follow local leaders) - Interests (follow related causes) - Network (follow people in your network) ### 5. Analytics Track engagement metrics: - Most followed leaders - Most popular causes - Follow growth over time - Engagement rates --- ## 🎨 Design Principles ### LinkedIn/Facebook Patterns Used 1. **Follow Button States:** - Not following: Blue "Follow" button - Following: White "Following" button with check - Hover on following: Red "Unfollow" button 2. **Profile Layout:** - Large avatar at top - Stats prominently displayed - Tabbed content for different categories 3. **Social Proof:** - Follower counts visible everywhere - Verification badges for trusted entities - "X people follow this" messaging 4. **Discovery:** - Follow buttons on all entity cards - Empty states with clear CTAs - Category-based browsing ### Plain Language - βœ… "Charities" instead of "Nonprofits" - βœ… "Leaders" instead of "Officials" - βœ… "Following" instead of "Subscribed" - βœ… "Followers" instead of "Subscribers" --- ## πŸ” Authentication All follow endpoints require authentication: - User must be logged in via OAuth (HuggingFace, Google, Facebook, GitHub) - JWT token passed in Authorization header - `get_current_user` dependency validates token **Error Responses:** ```json { "detail": "Not authenticated" } ``` --- ## πŸ“š Resources ### API Documentation - Swagger UI: http://localhost:8000/docs - ReDoc: http://localhost:8000/redoc ### Code Files - **Backend:** - `api/models.py` - Database models - `api/routes/social.py` - API endpoints - `scripts/migrate_social_features.py` - Migration script - **Frontend:** - `frontend/src/components/FollowButton.tsx` - Follow button component - `frontend/src/components/SocialStats.tsx` - Stats display component - `frontend/src/pages/Profile.tsx` - Profile page - `frontend/src/pages/PeopleFinder.tsx` - Updated with follow buttons --- ## πŸŽ‰ Summary You now have a complete social networking system for civic engagement! Users can: 1. **Follow leaders** they care about 2. **Follow charities** doing important work 3. **Follow causes** they're passionate about 4. **Follow other users** in their network 5. **View their profile** with social stats 6. **See who they follow** in organized tabs This transforms the platform from a read-only information source into an **engaging social network for civic participation**! πŸš€