2025-08-11 06:34:44 +00:00
|
|
|
|
import { useEffect } from 'react'
|
2025-06-23 14:58:13 +00:00
|
|
|
|
import { useForumData } from './useForumData'
|
|
|
|
|
|
import { AdminView } from './admin/AdminView'
|
2025-08-13 14:58:33 +00:00
|
|
|
|
import { Container } from '@/components/shared'
|
2025-08-14 07:10:56 +00:00
|
|
|
|
import { Helmet } from 'react-helmet'
|
|
|
|
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
2025-06-23 14:58:13 +00:00
|
|
|
|
|
|
|
|
|
|
export function Management() {
|
|
|
|
|
|
const {
|
|
|
|
|
|
categories,
|
|
|
|
|
|
topics,
|
|
|
|
|
|
posts,
|
|
|
|
|
|
loading,
|
|
|
|
|
|
error,
|
|
|
|
|
|
createCategory,
|
|
|
|
|
|
updateCategory,
|
2025-06-23 21:22:11 +00:00
|
|
|
|
updateCategoryLockState,
|
|
|
|
|
|
updateCategoryActiveState,
|
2025-06-23 14:58:13 +00:00
|
|
|
|
deleteCategory,
|
|
|
|
|
|
createTopic,
|
|
|
|
|
|
updateTopic,
|
|
|
|
|
|
deleteTopic,
|
|
|
|
|
|
pinTopic,
|
|
|
|
|
|
unpinTopic,
|
|
|
|
|
|
lockTopic,
|
|
|
|
|
|
unlockTopic,
|
2025-06-24 07:09:33 +00:00
|
|
|
|
solvedTopic,
|
|
|
|
|
|
unsolvedTopic,
|
2025-06-23 14:58:13 +00:00
|
|
|
|
createPost,
|
|
|
|
|
|
updatePost,
|
|
|
|
|
|
deletePost,
|
|
|
|
|
|
markPostAsAcceptedAnswer,
|
|
|
|
|
|
unmarkPostAsAcceptedAnswer,
|
|
|
|
|
|
clearError,
|
|
|
|
|
|
} = useForumData()
|
2025-08-14 07:10:56 +00:00
|
|
|
|
const { translate } = useLocalization()
|
2025-06-23 14:58:13 +00:00
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
|
|
|
|
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
|
// Search modal will be opened by Header component
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
document.addEventListener('keydown', handleKeyDown)
|
|
|
|
|
|
return () => document.removeEventListener('keydown', handleKeyDown)
|
|
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (error) {
|
|
|
|
|
|
const timer = setTimeout(() => {
|
|
|
|
|
|
clearError()
|
|
|
|
|
|
}, 5000)
|
|
|
|
|
|
return () => clearTimeout(timer)
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [error, clearError])
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
2025-08-13 14:58:33 +00:00
|
|
|
|
<Container>
|
2025-08-14 07:10:56 +00:00
|
|
|
|
<Helmet
|
|
|
|
|
|
titleTemplate="%s | Kurs Platform"
|
|
|
|
|
|
title={translate('::' + 'App.ForumManagement')}
|
|
|
|
|
|
defaultTitle="Kurs Platform"
|
|
|
|
|
|
></Helmet>
|
|
|
|
|
|
|
2025-06-23 14:58:13 +00:00
|
|
|
|
{error && (
|
|
|
|
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
|
|
|
|
|
|
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative">
|
|
|
|
|
|
<strong className="font-bold">Error: </strong>
|
|
|
|
|
|
<span className="block sm:inline">{error}</span>
|
|
|
|
|
|
<button onClick={clearError} className="absolute top-0 bottom-0 right-0 px-4 py-3">
|
|
|
|
|
|
<span className="sr-only">Dismiss</span>×
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
<AdminView
|
|
|
|
|
|
categories={categories}
|
|
|
|
|
|
topics={topics}
|
|
|
|
|
|
posts={posts}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
onCreateCategory={(data) => createCategory(data).then(() => {})}
|
|
|
|
|
|
onUpdateCategory={(id, data) => updateCategory(id, data).then(() => {})}
|
2025-06-23 21:22:11 +00:00
|
|
|
|
onUpdateCategoryLockState={(id) => updateCategoryLockState(id).then(() => {})}
|
|
|
|
|
|
onUpdateCategoryActiveState={(id) => updateCategoryActiveState(id).then(() => {})}
|
2025-06-23 14:58:13 +00:00
|
|
|
|
onDeleteCategory={(id) => deleteCategory(id).then(() => {})}
|
|
|
|
|
|
onCreateTopic={(data) => createTopic(data).then(() => {})}
|
|
|
|
|
|
onUpdateTopic={(id, data) => updateTopic(id, data).then(() => {})}
|
|
|
|
|
|
onDeleteTopic={(id) => deleteTopic(id).then(() => {})}
|
|
|
|
|
|
onPinTopic={(id) => pinTopic(id).then(() => {})}
|
|
|
|
|
|
onUnpinTopic={(id) => unpinTopic(id).then(() => {})}
|
|
|
|
|
|
onLockTopic={(id) => lockTopic(id).then(() => {})}
|
|
|
|
|
|
onUnlockTopic={(id) => unlockTopic(id).then(() => {})}
|
2025-06-24 07:09:33 +00:00
|
|
|
|
onMarkTopicAsSolved={(id) => solvedTopic(id).then(() => {})}
|
|
|
|
|
|
onMarkTopicAsUnsolved={(id) => unsolvedTopic(id).then(() => {})}
|
2025-06-23 14:58:13 +00:00
|
|
|
|
onCreatePost={(data) => createPost(data).then(() => {})}
|
|
|
|
|
|
onUpdatePost={(id, data) => updatePost(id, data).then(() => {})}
|
|
|
|
|
|
onDeletePost={(id) => deletePost(id).then(() => {})}
|
|
|
|
|
|
onMarkPostAsAcceptedAnswer={(id) => markPostAsAcceptedAnswer(id).then(() => {})}
|
|
|
|
|
|
onUnmarkPostAsAcceptedAnswer={(id) => unmarkPostAsAcceptedAnswer(id).then(() => {})}
|
|
|
|
|
|
/>
|
2025-08-13 14:58:33 +00:00
|
|
|
|
</Container>
|
2025-06-23 14:58:13 +00:00
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default Management
|