Spaces:
Running on CPU Upgrade
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:
- Leaders - Elected officials, decision makers, community advocates
- Organizations - Nonprofits, charities, government agencies
- Causes - Policy topics and issues (oral health, housing, education, etc.)
- 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 keyname,slug- Identitytitle,office- Position detailscity,state,jurisdiction- Locationemail,phone,website- Contacttwitter,linkedin,facebook- Social mediafollower_count- Denormalized countis_verified- Verification badge
organizations
Nonprofits, charities, advocacy groups
id- Primary keyname,slug- Identitydescription,logo_url- Brandingorg_type- 'nonprofit', 'government', 'advocacy', 'charity'city,state,address- Locationein,ntee_code,revenue- IRS datafollower_count- Denormalized countis_verified- Verification badge
causes
Policy topics and issues
id- Primary keyname,slug- Identitydescription,icon_url,color- Visual identitycategory- '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 relationshipsleader_follows- User β Leader relationshipsorganization_follows- User β Organization relationshipscause_follows- User β Cause relationships
Each contains:
user_id- Foreign key to users{entity}_id- Foreign key to entitycreated_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
Follow Button States:
- Not following: Blue "Follow" button
- Following: White "Following" button with check
- Hover on following: Red "Unfollow" button
Profile Layout:
- Large avatar at top
- Stats prominently displayed
- Tabbed content for different categories
Social Proof:
- Follower counts visible everywhere
- Verification badges for trusted entities
- "X people follow this" messaging
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_userdependency validates token
Error Responses:
{
"detail": "Not authenticated"
}
π Resources
API Documentation
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Code Files
Backend:
api/models.py- Database modelsapi/routes/social.py- API endpointsscripts/migrate_social_features.py- Migration script
Frontend:
frontend/src/components/FollowButton.tsx- Follow button componentfrontend/src/components/SocialStats.tsx- Stats display componentfrontend/src/pages/Profile.tsx- Profile pagefrontend/src/pages/PeopleFinder.tsx- Updated with follow buttons
π Summary
You now have a complete social networking system for civic engagement! Users can:
- Follow leaders they care about
- Follow charities doing important work
- Follow causes they're passionate about
- Follow other users in their network
- View their profile with social stats
- 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! π