undefined / components /HelpManagement.js
tuandesu's picture
hãy tạo một trang reactjs với tính năng cho phép admin load nội dung help từ file .html hoặc txt, sau đó hiện lên UI cho user, nếu login bằng admin thì hiện link edit --> click vào link này thì mở ra dialog để admin sửa nội dung help trong một HtmlEditor
d35c7df verified
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
const HelpManagement = ({ isAdmin }) => {
const [helpContent, setHelpContent] = useState('');
const [isEditing, setIsEditing] = useState(false);
const [file, setFile] = useState(null);
useEffect(() => {
fetchHelpContent();
}, []);
const fetchHelpContent = async () => {
try {
const response = await axios.get('/api/help-content');
setHelpContent(response.data.content);
} catch (error) {
toast.error('Failed to load help content');
}
};
const handleFileUpload = (e) => {
const file = e.target.files[0];
if (file) {
setFile(file);
}
};
const handleImport = async () => {
if (!file) return;
try {
const formData = new FormData();
formData.append('file', file);
const response = await axios.post('/api/help-content/import', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
setHelpContent(response.data.content);
toast.success('Help content imported successfully');
setFile(null);
} catch (error) {
toast.error('Failed to import help content');
}
};
const handleSave = async () => {
try {
await axios.put('/api/help-content', { content: helpContent });
toast.success('Help content saved successfully');
setIsEditing(false);
} catch (error) {
toast.error('Failed to save help content');
}
};
return (
<div className="container mx-auto p-6">
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6">
<div className="flex justify-between items-center mb-6">
<h2 className="text-2xl font-bold text-gray-800 dark:text-white">Help Center</h2>
{isAdmin && (
<div className="flex space-x-3">
{!isEditing ? (
<button
onClick={() => setIsEditing(true)}
className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"
>
Edit Content
</button>
) : (
<button
onClick={handleSave}
className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition"
>
Save Changes
</button>
)}
</div>
)}
</div>
{isEditing ? (
<div className="space-y-4">
<div className="mb-4">
<ReactQuill
theme="snow"
value={helpContent}
onChange={setHelpContent}
modules={{
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[{ list: 'ordered' }, { list: 'bullet' }],
['link', 'image'],
['clean'],
],
}}
/>
</div>
<div className="border-t pt-4">
<h3 className="text-lg font-medium text-gray-800 dark:text-white mb-3">Import from File</h3>
<div className="flex items-center space-x-3">
<input
type="file"
accept=".html,.txt"
onChange={handleFileUpload}
className="block w-full text-sm text-gray-500
file:mr-4 file:py-2 file:px-4
file:rounded-md file:border-0
file:text-sm file:font-semibold
file:bg-blue-50 file:text-blue-700
hover:file:bg-blue-100"
/>
<button
onClick={handleImport}
disabled={!file}
className={`px-4 py-2 rounded-lg ${file ? 'bg-blue-600 hover:bg-blue-700' : 'bg-gray-400'} text-white transition`}
>
Import
</button>
</div>
</div>
</div>
) : (
<div
className="prose dark:prose-invert max-w-none"
dangerouslySetInnerHTML={{ __html: helpContent }}
/>
)}
</div>
<ToastContainer position="bottom-right" autoClose={3000} />
</div>
);
};
export default HelpManagement;