mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-22 23:31:12 +02:00
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>
236 lines
6.2 KiB
Markdown
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
|