open-navigator / docs /SOCIAL_FEATURES.md
jcbowyer's picture
Deploy: Consolidated gold tables, fixed nginx docs routing
896453f verified

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

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:

{
  "success": true,
  "following": true,
  "follower_count": 1234,
  "message": "Successfully followed leader"
}

Check Following Status

GET /api/social/following/status?user_id=1&leader_id=2&org_id=3&cause_id=4

Response:

{
  "user": false,
  "leader": true,
  "organization": true,
  "cause": false
}

Get Statistics

GET /api/social/stats              # Current user's stats
GET /api/social/stats?user_id=123  # Another user's stats

Response:

{
  "followers": 150,
  "following": 42,
  "following_users": 10,
  "following_leaders": 15,
  "following_organizations": 12,
  "following_causes": 5
}

Get Following Lists

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):

[
  {
    "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:

interface FollowButtonProps {
  type: 'user' | 'leader' | 'organization' | 'cause'
  id: number
  initialFollowing?: boolean
  initialCount?: number
  showCount?: boolean
  compact?: boolean
  onFollowChange?: (following: boolean, count: number) => void
}

Usage:

// Compact button (for cards)
<FollowButton 
  type="leader" 
  id={leader.id}
  initialFollowing={false}
  compact={true}
/>

// Full button with count
<FollowButton 
  type="organization" 
  id={org.id}
  initialFollowing={true}
  initialCount={1234}
  showCount={true}
/>

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:

interface SocialStatsProps {
  userId?: number          // Optional, defaults to current user
  showBreakdown?: boolean  // Show category breakdown
  clickable?: boolean      // Link to profile page
}

Usage:

// Show current user's stats
<SocialStats showBreakdown={true} />

// Show another user's stats
<SocialStats userId={123} showBreakdown={false} />

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

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:

# 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:

{
  "detail": "Not authenticated"
}

πŸ“š Resources

API Documentation

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! πŸš€