| import React, { useState, useEffect } from 'react'; |
| import DOMPurify from 'dompurify'; |
| import { Editor } from '@tinymce/tinymce-react'; |
|
|
| const HelpSystem = ({ isAdmin = false }) => { |
| const [helpContent, setHelpContent] = useState(''); |
| const [editMode, setEditMode] = useState(false); |
| const [loading, setLoading] = useState(true); |
| const [error, setError] = useState(null); |
|
|
| |
| useEffect(() => { |
| const loadHelpContent = async () => { |
| try { |
| const response = await fetch('/api/help'); |
| if (!response.ok) throw new Error('Failed to load help content'); |
| const data = await response.text(); |
| setHelpContent(data); |
| } catch (err) { |
| setError(err.message); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| loadHelpContent(); |
| }, []); |
|
|
| const handleSave = async (newContent) => { |
| try { |
| const response = await fetch('/api/help', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ content: newContent }), |
| }); |
| |
| if (!response.ok) throw new Error('Failed to save help content'); |
| |
| setHelpContent(newContent); |
| setEditMode(false); |
| } catch (err) { |
| setError(err.message); |
| } |
| }; |
|
|
| if (loading) return <div className="p-4 text-center">Loading help content...</div>; |
| if (error) return <div className="p-4 text-red-500">Error: {error}</div>; |
|
|
| return ( |
| <div className="max-w-4xl mx-auto p-6 bg-white dark:bg-gray-800 rounded-lg shadow"> |
| <div className="flex justify-between items-center mb-4"> |
| <h2 className="text-xl font-bold text-gray-900 dark:text-white">Help Center</h2> |
| {isAdmin && !editMode && ( |
| <button |
| onClick={() => setEditMode(true)} |
| className="text-primary-500 hover:text-primary-600 dark:hover:text-primary-400" |
| > |
| Edit Content |
| </button> |
| )} |
| </div> |
| |
| {editMode ? ( |
| <div className="space-y-4"> |
| <Editor |
| apiKey="your-tinymce-api-key" |
| value={helpContent} |
| init={{ |
| height: 500, |
| menubar: true, |
| plugins: [ |
| 'advlist autolink lists link image charmap print preview anchor', |
| 'searchreplace visualblocks code fullscreen', |
| 'insertdatetime media table paste code help wordcount' |
| ], |
| toolbar: |
| 'undo redo | formatselect | bold italic backcolor | \ |
| alignleft aligncenter alignright alignjustify | \ |
| bullist numlist outdent indent | removeformat | help' |
| }} |
| onEditorChange={(newContent) => setHelpContent(newContent)} |
| /> |
| <div className="flex space-x-3"> |
| <button |
| onClick={() => handleSave(helpContent)} |
| className="px-4 py-2 bg-primary-500 text-white rounded hover:bg-primary-600" |
| > |
| Save Changes |
| </button> |
| <button |
| onClick={() => setEditMode(false)} |
| className="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400" |
| > |
| Cancel |
| </button> |
| </div> |
| </div> |
| ) : ( |
| <div |
| className="prose dark:prose-invert max-w-none" |
| dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(helpContent) }} |
| /> |
| )} |
| </div> |
| ); |
| }; |
|
|
| export default HelpSystem; |