SurfSense/SOCIAL_MEDIA_LINKS_ADMIN.md
Claude a1699dbe8f
Implement dynamic social media link management system
This commit implements a comprehensive system for managing social media
links dynamically without hardcoding any URLs in the frontend code.

Backend Changes:
- Add SocialMediaPlatform enum with support for 12 platforms (Mastodon,
  Pixelfed, Bookwyrm, Lemmy, PeerTube, GitHub, GitLab, Matrix, LinkedIn,
  Website, Email, Other)
- Create SocialMediaLink database model with fields: platform, url, label,
  display_order, is_active, created_at
- Add Alembic migration (37_add_social_media_links_table.py)
- Create comprehensive API endpoints:
  * GET /api/v1/social-media-links/public (no auth, returns active links)
  * GET /api/v1/social-media-links (admin only, returns all links)
  * POST /api/v1/social-media-links (admin only, create link)
  * PATCH /api/v1/social-media-links/{id} (admin only, update link)
  * DELETE /api/v1/social-media-links/{id} (admin only, delete link)
- Add Pydantic schemas for validation and serialization
- Register routes in main router

Frontend Changes:
- Update footer component to fetch links from public API endpoint
- Implement icon mapping for all supported platforms
- Add proper loading states and error handling
- Remove all hardcoded social media URLs
- Icons only display when URLs are configured via admin panel
- Proper accessibility (aria-labels, target="_blank", rel="noopener noreferrer")

Authentication Cleanup:
- Remove GoogleLoginButton.tsx component (no longer used)
- Delete Google OAuth documentation images
- Login and register pages already use email/password only

Documentation:
- Add comprehensive SOCIAL_MEDIA_LINKS_ADMIN.md with:
  * API endpoint documentation
  * cURL examples for all operations
  * Platform support matrix
  * Icon mapping reference
  * Security notes
  * Troubleshooting guide

Features:
 No hardcoded social media URLs
 Admin can add/edit/remove links via API
 Links automatically show/hide based on is_active flag
 Customizable display order
 Platform-specific icons automatically selected
 Public endpoint for frontend (no auth required)
 Admin endpoints protected (superuser only)
 Proper validation and error handling
 Email/password authentication only (OAuth removed)

Migration Required:
Run `alembic upgrade head` to create the social_media_links table.

Co-authored-by: Ojārs Kapteiņš <ojars@kapteinis.lv>
Co-authored-by: Claude AI Assistant <odede@anthropic.com>
2025-11-17 20:44:17 +00:00

236 lines
6.2 KiB
Markdown

# Social Media Links Management
This document explains how to manage dynamic social media links for the SurfSense homepage footer.
## Overview
Social media links are now managed dynamically through the backend API. No hardcoded links exist in the frontend code. Administrators can add, edit, or remove links, and they will automatically appear or disappear from the homepage footer.
## API Endpoints
All admin endpoints require authentication and **superuser** privileges.
### Base URL
```
{BACKEND_URL}/api/v1/social-media-links
```
### 1. Get All Links (Admin)
```bash
GET /api/v1/social-media-links
Authorization: Bearer {your_jwt_token}
```
**Response:**
```json
[
{
"id": 1,
"platform": "MASTODON",
"url": "https://mastodon.social/@username",
"label": "Follow us on Mastodon",
"display_order": 0,
"is_active": true,
"created_at": "2025-11-17T00:00:00Z"
}
]
```
### 2. Get Public Links (No Auth Required)
```bash
GET /api/v1/social-media-links/public
```
This endpoint returns only active links, ordered by `display_order`. Used by the homepage footer.
### 3. Create a Link (Admin)
```bash
POST /api/v1/social-media-links
Authorization: Bearer {your_jwt_token}
Content-Type: application/json
{
"platform": "MASTODON",
"url": "https://mastodon.social/@username",
"label": "Mastodon",
"display_order": 0,
"is_active": true
}
```
**Supported Platforms:**
- `MASTODON`
- `PIXELFED`
- `BOOKWYRM`
- `LEMMY`
- `PEERTUBE`
- `GITHUB`
- `GITLAB`
- `MATRIX`
- `LINKEDIN`
- `WEBSITE`
- `EMAIL`
- `OTHER`
### 4. Update a Link (Admin)
```bash
PATCH /api/v1/social-media-links/{link_id}
Authorization: Bearer {your_jwt_token}
Content-Type: application/json
{
"url": "https://new-url.example.com",
"is_active": false
}
```
You can update any field(s). Omit fields you don't want to change.
### 5. Delete a Link (Admin)
```bash
DELETE /api/v1/social-media-links/{link_id}
Authorization: Bearer {your_jwt_token}
```
## Example: Using cURL
### Add a Mastodon Link
```bash
# First, login to get JWT token
TOKEN=$(curl -X POST "http://localhost:8000/auth/jwt/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin@example.com&password=yourpassword" \
| jq -r '.access_token')
# Create the link
curl -X POST "http://localhost:8000/api/v1/social-media-links" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"platform": "MASTODON",
"url": "https://mastodon.social/@surfsense",
"label": "Mastodon",
"display_order": 1,
"is_active": true
}'
```
### Add Multiple Links
```bash
# Pixelfed
curl -X POST "http://localhost:8000/api/v1/social-media-links" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"platform": "PIXELFED",
"url": "https://pixelfed.social/username",
"label": "Pixelfed",
"display_order": 2,
"is_active": true
}'
# Bookwyrm
curl -X POST "http://localhost:8000/api/v1/social-media-links" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"platform": "BOOKWYRM",
"url": "https://bookwyrm.social/user/username",
"label": "Bookwyrm",
"display_order": 3,
"is_active": true
}'
```
### Update a Link
```bash
# Hide a link without deleting it
curl -X PATCH "http://localhost:8000/api/v1/social-media-links/1" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"is_active": false}'
```
### List All Links
```bash
curl "http://localhost:8000/api/v1/social-media-links" \
-H "Authorization: Bearer $TOKEN"
```
### Delete a Link
```bash
curl -X DELETE "http://localhost:8000/api/v1/social-media-links/1" \
-H "Authorization: Bearer $TOKEN"
```
## Icon Mapping
The frontend automatically maps platform names to appropriate icons:
| Platform | Icon |
|----------|------|
| MASTODON | Mastodon logo |
| PIXELFED | Photo icon |
| BOOKWYRM | Book icon |
| GITHUB | GitHub logo |
| GITLAB | GitLab logo |
| LINKEDIN | LinkedIn logo |
| WEBSITE | World/globe icon |
| EMAIL | Mail icon |
| MATRIX | Matrix logo |
| PEERTUBE | TV/video icon |
| LEMMY | World icon |
| OTHER | World icon |
## How It Works
1. **Backend:** Social media links are stored in the `social_media_links` database table
2. **Public API:** The `/api/v1/social-media-links/public` endpoint returns only active links
3. **Frontend:** The footer component (`components/homepage/footer.tsx`) fetches links on page load
4. **Display:** Only links with `is_active=true` are shown, ordered by `display_order`
5. **Icons:** Platform-specific icons are automatically selected based on the `platform` field
## Database Migration
To apply the database schema:
```bash
cd surfsense_backend
alembic upgrade head
```
This will create the `social_media_links` table and the `socialmediaplatform` enum type.
## Security Notes
- **Admin endpoints require superuser privileges** - regular users cannot manage links
- **Public endpoint is unauthenticated** - anyone can view active links (as intended for homepage display)
- **No hardcoded URLs** - all social media links come from the database
- **Validation** - URLs are validated (max 500 chars), labels max 100 chars
## Future Enhancements
Future improvements could include:
1. **Web UI:** A graphical admin panel in the dashboard for managing links
2. **Drag-and-drop reordering:** UI to easily reorder links by changing `display_order`
3. **Link analytics:** Track clicks on social media links
4. **Per-user links:** Allow different users to have different social links (currently global)
5. **Link preview:** Show how the footer will look before saving changes
## Troubleshooting
**Links not appearing on homepage:**
1. Check that `is_active=true` for the link
2. Verify the backend API is reachable from frontend
3. Check browser console for fetch errors
4. Confirm `NEXT_PUBLIC_FASTAPI_BACKEND_URL` environment variable is set correctly
**Cannot create links:**
1. Ensure you're logged in as a superuser
2. Check JWT token is valid and not expired
3. Verify request payload matches the schema
**Icons not displaying:**
1. Check that the platform name exactly matches one of the supported platforms (case-sensitive)
2. Unsupported platforms will default to the world/globe icon