Add comprehensive social media management system and improve admin pages

## Social Media Management System
- Add SocialMediaLink database model with platform, URL, icon, and ordering
- Create complete CRUD API endpoints for admin social media management
- Implement admin social media management page with Material-UI DataGrid
- Add "Social Media" menu item to admin navigation
- Update footer to dynamically load and display enabled social media links
- Support multiple platforms: Facebook, Twitter, Instagram, YouTube, LinkedIn, GitHub, TikTok
- Include proper icon mapping and fallback handling

## Admin Pages Improvements
- Replace broken TinyMCE editor with working WYSIWYG rich text editor
- Create SimpleRichEditor component with toolbar for formatting
- Fix admin authentication to use cookies instead of localStorage tokens
- Update all admin API calls to use credentials: 'include'
- Increase content editor height to 800px for better editing experience
- Add Lexical editor component as alternative (not currently used)

## Footer Pages System
- Create 8 comprehensive footer pages: About, Blog, Support, API Docs, Terms, Privacy, Cookies, GDPR
- Implement dynamic footer link management with smart categorization
- Separate Quick Links and Legal sections with automatic filtering
- Remove duplicate hardcoded links and use database-driven system
- All footer pages are fully written with professional content

## Database & Dependencies
- Add uuid package for ID generation
- Update Prisma schema with new SocialMediaLink model and relations
- Seed default social media links for Facebook, Twitter, Instagram, YouTube
- Add Lexical rich text editor packages (@lexical/react, etc.)

## Technical Improvements
- Fix async params compatibility for Next.js 15
- Update MUI DataGrid deprecated props
- Improve admin layout navigation structure
- Add proper TypeScript interfaces for all new components
- Implement proper error handling and user feedback

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-24 12:08:01 +00:00
parent 3b34d7518b
commit 4adf1d286e
17 changed files with 1817 additions and 122 deletions

View File

@@ -22,8 +22,8 @@ import {
Grid,
Paper
} from '@mui/material';
import { Editor } from '@tinymce/tinymce-react';
import { ImageUpload } from './image-upload';
import { SimpleRichEditor } from './simple-rich-editor';
interface Page {
id?: string;
@@ -128,16 +128,15 @@ export function PageEditor({ open, onClose, page, onSave }: PageEditorProps) {
setError(null);
try {
const token = localStorage.getItem('authToken');
const url = page ? `/api/admin/pages/${page.id}` : '/api/admin/pages';
const method = page ? 'PUT' : 'POST';
const response = await fetch(url, {
method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify(formData)
});
@@ -174,54 +173,16 @@ export function PageEditor({ open, onClose, page, onSave }: PageEditorProps) {
case 'RICH_TEXT':
return (
<Box sx={{ mt: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
<Typography variant="subtitle2">Content</Typography>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="subtitle2">Rich Text Content</Typography>
<Button size="small" onClick={() => setImageUploadOpen(true)}>
Insert Image
</Button>
</Box>
<Editor
onInit={(evt, editor) => editorRef.current = { getEditor: () => editor }}
<SimpleRichEditor
value={formData.content}
onEditorChange={(content) => setFormData(prev => ({ ...prev, content }))}
init={{
height: 400,
menubar: true,
plugins: [
'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
'insertdatetime', 'media', 'table', 'help', 'wordcount'
],
toolbar: 'undo redo | blocks | ' +
'bold italic forecolor | alignleft aligncenter ' +
'alignright alignjustify | bullist numlist outdent indent | ' +
'removeformat | link image | code | help',
content_style: 'body { font-family: Arial, Helvetica, sans-serif; font-size: 14px }',
images_upload_handler: (blobInfo: any) => {
return new Promise((resolve, reject) => {
const formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
const token = localStorage.getItem('authToken');
fetch('/api/admin/media', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
})
.then(response => response.json())
.then(result => {
if (result.success) {
resolve(result.data.url);
} else {
reject(result.error || 'Upload failed');
}
})
.catch(error => reject(error));
});
}
}}
onChange={(content) => setFormData(prev => ({ ...prev, content }))}
height={800}
/>
</Box>
);
@@ -237,7 +198,7 @@ export function PageEditor({ open, onClose, page, onSave }: PageEditorProps) {
</Box>
<TextField
multiline
rows={20}
rows={60}
fullWidth
variant="outlined"
value={formData.content}
@@ -253,7 +214,7 @@ export function PageEditor({ open, onClose, page, onSave }: PageEditorProps) {
<Typography variant="subtitle2" gutterBottom>Markdown Content</Typography>
<TextField
multiline
rows={20}
rows={60}
fullWidth
variant="outlined"
value={formData.content}