File size: 11,499 Bytes
896453f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# 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)
<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:**
```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
<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

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