180 lines
5.8 KiB
TypeScript
180 lines
5.8 KiB
TypeScript
import React, { useState } from 'react'
|
|
import { FaFolder, FaCommentAlt, FaFileAlt, FaChartBar } from 'react-icons/fa'
|
|
import { CategoryManagement } from './CategoryManagement'
|
|
import { TopicManagement } from './TopicManagement'
|
|
import { PostManagement } from './PostManagement'
|
|
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
|
|
import { AdminStats } from './Dashboard'
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|
|
|
interface AdminViewProps {
|
|
categories: ForumCategory[]
|
|
topics: ForumTopic[]
|
|
posts: ForumPost[]
|
|
loading: boolean
|
|
onCreateCategory: (category: {
|
|
name: string
|
|
slug: string
|
|
description: string
|
|
icon: string
|
|
displayOrder: number
|
|
isActive: boolean
|
|
isLocked: boolean
|
|
}) => Promise<void>
|
|
onUpdateCategory: (id: string, category: Partial<ForumCategory>) => Promise<void>
|
|
onUpdateCategoryLockState: (id: string) => Promise<void>
|
|
onUpdateCategoryActiveState: (id: string) => Promise<void>
|
|
onDeleteCategory: (id: string) => Promise<void>
|
|
onCreateTopic: (topic: {
|
|
title: string
|
|
content: string
|
|
categoryId: string
|
|
isPinned?: boolean
|
|
isLocked?: boolean
|
|
}) => Promise<void>
|
|
onUpdateTopic: (id: string, topic: Partial<ForumTopic>) => Promise<void>
|
|
onDeleteTopic: (id: string) => Promise<void>
|
|
onPinTopic: (id: string) => Promise<void>
|
|
onUnpinTopic: (id: string) => Promise<void>
|
|
onLockTopic: (id: string) => Promise<void>
|
|
onUnlockTopic: (id: string) => Promise<void>
|
|
onMarkTopicAsSolved: (id: string) => Promise<void>
|
|
onMarkTopicAsUnsolved: (id: string) => Promise<void>
|
|
onCreatePost: (post: { topicId: string; content: string; parentPostId?: string }) => Promise<void>
|
|
onUpdatePost: (id: string, post: Partial<ForumPost>) => Promise<void>
|
|
onDeletePost: (id: string) => Promise<void>
|
|
onMarkPostAsAcceptedAnswer: (id: string) => Promise<void>
|
|
onUnmarkPostAsAcceptedAnswer: (id: string) => Promise<void>
|
|
}
|
|
|
|
type AdminSection = 'stats' | 'categories' | 'topics' | 'posts'
|
|
|
|
export function AdminView({
|
|
categories,
|
|
topics,
|
|
posts,
|
|
loading,
|
|
onCreateCategory,
|
|
onUpdateCategory,
|
|
onDeleteCategory,
|
|
onUpdateCategoryLockState,
|
|
onUpdateCategoryActiveState,
|
|
onCreateTopic,
|
|
onUpdateTopic,
|
|
onDeleteTopic,
|
|
onPinTopic,
|
|
onUnpinTopic,
|
|
onLockTopic,
|
|
onUnlockTopic,
|
|
onMarkTopicAsSolved,
|
|
onMarkTopicAsUnsolved,
|
|
onCreatePost,
|
|
onUpdatePost,
|
|
onDeletePost,
|
|
onMarkPostAsAcceptedAnswer,
|
|
onUnmarkPostAsAcceptedAnswer,
|
|
}: AdminViewProps) {
|
|
const [activeSection, setActiveSection] = useState<AdminSection>('stats')
|
|
const { translate } = useLocalization()
|
|
|
|
const navigationItems = [
|
|
{
|
|
id: 'stats' as AdminSection,
|
|
label: translate('::App.Forum.Dashboard.Dashboard'),
|
|
icon: FaChartBar,
|
|
},
|
|
{
|
|
id: 'categories' as AdminSection,
|
|
label: translate('::App.Forum.Dashboard.Categories'),
|
|
icon: FaFolder,
|
|
},
|
|
{
|
|
id: 'topics' as AdminSection,
|
|
label: translate('::App.Forum.Dashboard.Topics'),
|
|
icon: FaCommentAlt,
|
|
},
|
|
{
|
|
id: 'posts' as AdminSection,
|
|
label: translate('::App.Forum.Dashboard.Posts'),
|
|
icon: FaFileAlt,
|
|
},
|
|
]
|
|
|
|
return (
|
|
<div className="mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<div className="flex flex-col lg:flex-row gap-8">
|
|
{/* Sidebar Navigation */}
|
|
<div className="lg:w-64 flex-shrink-0 p-4 bg-gray-50">
|
|
<nav className="space-y-2">
|
|
{navigationItems.map((item) => {
|
|
const Icon = item.icon
|
|
return (
|
|
<button
|
|
key={item.id}
|
|
onClick={() => setActiveSection(item.id)}
|
|
className={`w-full flex items-center space-x-3 px-4 py-3 rounded-lg text-left transition-colors ${
|
|
activeSection === item.id
|
|
? 'bg-blue-100 text-blue-700'
|
|
: 'text-gray-600 hover:bg-gray-100 hover:text-gray-900'
|
|
}`}
|
|
>
|
|
<Icon className="w-5 h-5" />
|
|
<span className="font-medium">{item.label}</span>
|
|
</button>
|
|
)
|
|
})}
|
|
</nav>
|
|
</div>
|
|
|
|
{/* Main Content */}
|
|
<div className="flex-1">
|
|
{activeSection === 'stats' && (
|
|
<AdminStats categories={categories} topics={topics} posts={posts} />
|
|
)}
|
|
|
|
{activeSection === 'categories' && (
|
|
<CategoryManagement
|
|
categories={categories}
|
|
loading={loading}
|
|
onCreateCategory={onCreateCategory}
|
|
onUpdateCategory={onUpdateCategory}
|
|
onDeleteCategory={onDeleteCategory}
|
|
onUpdateCategoryLockState={onUpdateCategoryLockState}
|
|
onUpdateCategoryActiveState={onUpdateCategoryActiveState}
|
|
/>
|
|
)}
|
|
|
|
{activeSection === 'topics' && (
|
|
<TopicManagement
|
|
topics={topics}
|
|
categories={categories}
|
|
loading={loading}
|
|
onCreateTopic={onCreateTopic}
|
|
onUpdateTopic={onUpdateTopic}
|
|
onDeleteTopic={onDeleteTopic}
|
|
onPinTopic={onPinTopic}
|
|
onUnpinTopic={onUnpinTopic}
|
|
onLockTopic={onLockTopic}
|
|
onUnlockTopic={onUnlockTopic}
|
|
onMarkTopicAsSolved={onMarkTopicAsSolved}
|
|
onMarkTopicAsUnsolved={onMarkTopicAsUnsolved}
|
|
/>
|
|
)}
|
|
|
|
{activeSection === 'posts' && (
|
|
<PostManagement
|
|
posts={posts}
|
|
topics={topics}
|
|
loading={loading}
|
|
onCreatePost={onCreatePost}
|
|
onUpdatePost={onUpdatePost}
|
|
onDeletePost={onDeletePost}
|
|
onMarkPostAsAcceptedAnswer={onMarkPostAsAcceptedAnswer}
|
|
onUnmarkPostAsAcceptedAnswer={onUnmarkPostAsAcceptedAnswer}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|