221 lines
6.6 KiB
Markdown
221 lines
6.6 KiB
Markdown
# Site Content Management System
|
|
|
|
This document explains how to manage site content (modals, rules, etc.) using the new database-driven system.
|
|
|
|
## Overview
|
|
|
|
The site content management system allows administrators to modify:
|
|
- Modal content (welcome modal, rules, instructions)
|
|
- Help text (paint faster, map lagging)
|
|
- Footer links and contact information
|
|
- Site title and branding
|
|
- Any other text content on the site
|
|
|
|
Content is stored in MySQL and can be edited through an admin interface, supporting multiple locales (English, Chinese, etc.).
|
|
|
|
## Architecture
|
|
|
|
### Database Schema
|
|
|
|
**Table: `SiteContent`**
|
|
- `id`: Auto-incrementing primary key
|
|
- `key`: Unique string identifier (e.g., `modal.rules.title`)
|
|
- `value`: Text content
|
|
- `locale`: Language code (en, zh, etc.)
|
|
- `createdAt`: Creation timestamp
|
|
- `updatedAt`: Last update timestamp
|
|
|
|
### Backend API Endpoints
|
|
|
|
**Public Endpoint:**
|
|
- `GET /api/site-content?locale=en` - Fetch all content for a locale (used by frontend)
|
|
|
|
**Admin Endpoints (require authentication & admin role):**
|
|
- `GET /api/admin/site-content` - Get all content items
|
|
- `POST /api/admin/site-content` - Create or update a single item
|
|
- `POST /api/admin/site-content/bulk` - Bulk update multiple items
|
|
- `DELETE /api/admin/site-content/:key` - Delete an item
|
|
- `POST /api/admin/site-content/initialize` - Initialize default content
|
|
|
|
### Frontend Integration
|
|
|
|
**File: `frontend/_app/info.js`**
|
|
- Automatically loads content from API on page load
|
|
- Falls back to hardcoded defaults if API fails
|
|
- Uses MutationObserver to patch modals when they appear
|
|
- Supports locale switching
|
|
|
|
## Setup Instructions
|
|
|
|
### 1. Database Migration
|
|
|
|
Run the Prisma migration to create the `SiteContent` table:
|
|
|
|
```bash
|
|
pnpm db:push
|
|
```
|
|
|
|
### 2. Initialize Default Content
|
|
|
|
After the database is set up, initialize the default content by making a POST request:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3000/api/admin/site-content/initialize \
|
|
-H "Cookie: j=YOUR_ADMIN_JWT_TOKEN"
|
|
```
|
|
|
|
Or use the admin UI (see below).
|
|
|
|
### 3. Access the Admin UI
|
|
|
|
Navigate to: `http://localhost:3000/_app/admin-content-editor.html`
|
|
|
|
**Note:** You must be logged in as an admin with a valid JWT token in cookies.
|
|
|
|
## Using the Admin UI
|
|
|
|
### Interface Features
|
|
|
|
1. **Locale Selector** - Switch between languages (en, zh)
|
|
2. **Reload Button** - Refresh content from database
|
|
3. **Add New Item** - Create new content entries
|
|
4. **Initialize Defaults** - Populate database with default content
|
|
5. **Save All Changes** - Bulk save modified items
|
|
6. **Delete Button** - Remove individual items
|
|
|
|
### Content Keys
|
|
|
|
Content is organized using dot-notation keys:
|
|
|
|
#### Modal Content Keys
|
|
|
|
**Overview Section:**
|
|
- `modal.overview.title` - "Overview" heading
|
|
- `modal.overview.videoUrl` - YouTube embed URL
|
|
|
|
**Paint Faster Section:**
|
|
- `modal.paintFaster.title` - Section heading
|
|
- `modal.paintFaster.mobile` - Instructions for mobile users
|
|
- `modal.paintFaster.desktop` - Instructions for desktop users
|
|
|
|
**Map Lagging Section:**
|
|
- `modal.mapLagging.title` - Section heading
|
|
- `modal.mapLagging.text` - Help text
|
|
- `modal.mapLagging.link` - Link to hardware acceleration guide
|
|
|
|
**Rules Section:**
|
|
- `modal.rules.title` - "Rules" heading
|
|
- `modal.rules.badge` - Badge text (e.g., "Important")
|
|
- `modal.rules.item.0` - First rule (with emoji)
|
|
- `modal.rules.item.1` - Second rule
|
|
- `modal.rules.item.N` - Additional rules (add as needed)
|
|
- `modal.rules.footer` - Footer warning text
|
|
|
|
**Footer Section:**
|
|
- `modal.footer.email` - Contact email
|
|
- `modal.footer.discord.url` - Discord invite URL
|
|
- `modal.footer.discord.text` - Discord link text
|
|
- `modal.footer.github.url` - GitHub organization URL
|
|
- `modal.footer.github.text` - GitHub link text
|
|
- `modal.footer.instagram.url` - Instagram URL
|
|
- `modal.footer.instagram.text` - Instagram link text
|
|
- `modal.footer.terms.url` - Terms of service URL
|
|
- `modal.footer.terms.text` - Terms link text
|
|
- `modal.footer.privacy.url` - Privacy policy URL
|
|
- `modal.footer.privacy.text` - Privacy link text
|
|
|
|
**Site-wide:**
|
|
- `site.title` - Site title/branding
|
|
|
|
### Adding New Rules
|
|
|
|
To add a new rule to the rules modal:
|
|
|
|
1. Click "Add New Item"
|
|
2. Set key to `modal.rules.item.4` (or next available number)
|
|
3. Set value to `🚀 Your new rule text here`
|
|
4. Click "Add Item"
|
|
5. Repeat for other locales (en, zh, etc.)
|
|
|
|
The frontend will automatically display all numbered rules in order.
|
|
|
|
### Workflow Example
|
|
|
|
1. **Login as admin** to your FurryPlace instance
|
|
2. **Navigate to** `/_app/admin-content-editor.html`
|
|
3. **Select locale** (e.g., English)
|
|
4. **Click "Initialize Defaults"** (first time only)
|
|
5. **Edit content** directly in the text fields
|
|
6. **Click "Save All Changes"** to persist to database
|
|
7. **Refresh your main site** - changes appear immediately!
|
|
|
|
## Development Notes
|
|
|
|
### Adding New Content Fields
|
|
|
|
To add new editable content:
|
|
|
|
1. Choose a unique key (e.g., `modal.newSection.title`)
|
|
2. Add to the initialize defaults in `src/routes/site-content.ts`
|
|
3. Update the monkey patch in `frontend/_app/info.js` to use the new key
|
|
4. Add documentation to this file
|
|
|
|
### Locale Support
|
|
|
|
Currently supports:
|
|
- `en` - English
|
|
- `zh` - Chinese
|
|
|
|
To add a new locale:
|
|
1. Add option to locale selector in admin UI
|
|
2. Initialize default content for that locale
|
|
3. Update frontend locale detection in `info.js`
|
|
|
|
### Caching Considerations
|
|
|
|
- Frontend caches API response per page load
|
|
- No server-side caching (content always fresh from DB)
|
|
- Consider adding Redis/memory cache for production
|
|
|
|
## Troubleshooting
|
|
|
|
### Content Not Updating
|
|
|
|
1. Check browser console for `[WPLACE_INFO]` logs
|
|
2. Verify API endpoint returns data: `GET /api/site-content?locale=en`
|
|
3. Clear browser cache and reload
|
|
4. Check database for content entries: `SELECT * FROM SiteContent;`
|
|
|
|
### Admin UI Not Loading
|
|
|
|
1. Verify you're logged in as admin
|
|
2. Check browser cookies for `j` JWT token
|
|
3. Verify `role` in User table is set to `admin`
|
|
4. Check browser console for authentication errors
|
|
|
|
### Default Content Missing
|
|
|
|
Run initialization endpoint:
|
|
```bash
|
|
curl -X POST http://localhost:3000/api/admin/site-content/initialize \
|
|
-H "Cookie: j=YOUR_JWT_TOKEN"
|
|
```
|
|
|
|
## Security Notes
|
|
|
|
- Admin endpoints require authentication AND `role='admin'`
|
|
- Input validation prevents injection attacks
|
|
- Keys restricted to alphanumeric + dots + underscores
|
|
- No HTML rendering (XSS protection via text replacement)
|
|
|
|
## Future Enhancements
|
|
|
|
- [ ] Add wysiwyg editor for formatted text
|
|
- [ ] Support for images/media uploads
|
|
- [ ] Version history and rollback
|
|
- [ ] Multi-tenant support (different content per domain)
|
|
- [ ] Import/export functionality (JSON/CSV)
|
|
- [ ] Preview changes before publishing
|
|
- [ ] Scheduled content changes
|
|
- [ ] Content approval workflow
|