import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum' import { CreateCategoryRequest, CreatePostRequest, CreateTopicRequest, forumService } from '@/services/forum.service' import { useState, useEffect } from 'react' export function useForumData() { const [categories, setCategories] = useState([]) const [topics, setTopics] = useState([]) const [posts, setPosts] = useState([]) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) // Load initial data useEffect(() => { loadCategories() loadTopics() loadPosts() }, []) const loadCategories = async () => { try { setLoading(true) const response = await forumService.getCategories() setCategories(response.items) } catch (err) { setError('Failed to load categories') console.error('Error loading categories:', err) } finally { setLoading(false) } } const loadTopics = async (categoryId?: string) => { try { setLoading(true) const response = await forumService.getTopics({ categoryId }) setTopics(response.items) } catch (err) { setError('Failed to load topics') console.error('Error loading topics:', err) } finally { setLoading(false) } } const loadPosts = async (topicId?: string) => { try { setLoading(true) const response = await forumService.getPosts({ topicId }) setPosts(response.items) } catch (err) { setError('Failed to load posts') console.error('Error loading posts:', err) } finally { setLoading(false) } } // Category operations const createCategory = async (categoryData: CreateCategoryRequest) => { try { setLoading(true) const newCategory = await forumService.createCategory(categoryData) setCategories((prev) => [...prev, newCategory]) return newCategory } catch (err) { setError('Failed to create category') console.error('Error creating category:', err) throw err } finally { setLoading(false) } } const updateCategory = async (id: string, updates: Partial) => { try { setLoading(true) const updatedCategory = await forumService.updateCategory(id, updates) setCategories((prev) => prev.map((cat) => (cat.id === id ? updatedCategory : cat))) return updatedCategory } catch (err) { setError('Failed to update category') console.error('Error updating category:', err) throw err } finally { setLoading(false) } } const updateCategoryLockState = async (id: string) => { await forumService.updateCategoryLockState(id) await loadCategories() // refresh after update } const updateCategoryActiveState = async (id: string) => { await forumService.updateCategoryActiveState(id) await loadCategories() // refresh after update } const deleteCategory = async (id: string) => { try { setLoading(true) await forumService.deleteCategory(id) setCategories((prev) => prev.filter((cat) => cat.id !== id)) // Also remove related topics and posts const topicsToDelete = topics.filter((topic) => topic.categoryId === id) const topicIds = topicsToDelete.map((t) => t.id) setTopics((prev) => prev.filter((topic) => topic.categoryId !== id)) setPosts((prev) => prev.filter((post) => !topicIds.includes(post.topicId))) } catch (err) { setError('Failed to delete category') console.error('Error deleting category:', err) throw err } finally { setLoading(false) } } // Topic operations const createTopic = async (topicData: CreateTopicRequest) => { try { setLoading(true) const newTopic = await forumService.createTopic(topicData) setTopics((prev) => [...prev, newTopic]) // Update category topic count setCategories((prev) => prev.map((cat) => cat.id === topicData.categoryId ? { ...cat, topicCount: cat.topicCount + 1 } : cat, ), ) return newTopic } catch (err) { setError('Failed to create topic') console.error('Error creating topic:', err) throw err } finally { setLoading(false) } } const updateTopic = async (id: string, updates: Partial) => { try { setLoading(true) const updatedTopic = await forumService.updateTopic(id, updates) setTopics((prev) => prev.map((topic) => (topic.id === id ? updatedTopic : topic))) return updatedTopic } catch (err) { setError('Failed to update topic') console.error('Error updating topic:', err) throw err } finally { setLoading(false) } } const deleteTopic = async (id: string) => { try { setLoading(true) const topic = topics.find((t) => t.id === id) await forumService.deleteTopic(id) setTopics((prev) => prev.filter((t) => t.id !== id)) setPosts((prev) => prev.filter((post) => post.topicId !== id)) // Update category counts if (topic) { setCategories((prev) => prev.map((cat) => cat.id === topic.categoryId ? { ...cat, topicCount: Math.max(0, cat.topicCount - 1), postCount: Math.max( 0, cat.postCount - posts.filter((p) => p.topicId === id).length, ), } : cat, ), ) } } catch (err) { setError('Failed to delete topic') console.error('Error deleting topic:', err) throw err } finally { setLoading(false) } } const pinTopic = async (id: string) => { try { const updatedTopic = await forumService.pinTopic(id) setTopics((prev) => prev.map((topic) => (topic.id === id ? updatedTopic : topic))) return updatedTopic } catch (err) { setError('Failed to pin topic') console.error('Error pinning topic:', err) throw err } } const unpinTopic = async (id: string) => { try { const updatedTopic = await forumService.unpinTopic(id) setTopics((prev) => prev.map((topic) => (topic.id === id ? updatedTopic : topic))) return updatedTopic } catch (err) { setError('Failed to unpin topic') console.error('Error unpinning topic:', err) throw err } } const lockTopic = async (id: string) => { try { const updatedTopic = await forumService.lockTopic(id) setTopics((prev) => prev.map((topic) => (topic.id === id ? updatedTopic : topic))) return updatedTopic } catch (err) { setError('Failed to lock topic') console.error('Error locking topic:', err) throw err } } const unlockTopic = async (id: string) => { try { const updatedTopic = await forumService.unlockTopic(id) setTopics((prev) => prev.map((topic) => (topic.id === id ? updatedTopic : topic))) return updatedTopic } catch (err) { setError('Failed to unlock topic') console.error('Error unlocking topic:', err) throw err } } const solvedTopic = async (id: string) => { try { const updatedTopic = await forumService.solvedTopic(id) setTopics((prev) => prev.map((topic) => (topic.id === id ? updatedTopic : topic))) return updatedTopic } catch (err) { setError('Failed to mark topic as solved') console.error('Error marking topic as solved:', err) throw err } } const unsolvedTopic = async (id: string) => { try { const updatedTopic = await forumService.unsolvedTopic(id) setTopics((prev) => prev.map((topic) => (topic.id === id ? updatedTopic : topic))) return updatedTopic } catch (err) { setError('Failed to mark topic as unsolved') console.error('Error marking topic as unsolved:', err) throw err } } // Post operations const createPost = async (postData: CreatePostRequest) => { try { setLoading(true) const newPost = await forumService.createPost(postData) setPosts((prev) => [...prev, newPost]) // Update topic and category post counts const topic = topics.find((t) => t.id === postData.topicId) if (topic) { setTopics((prev) => prev.map((t) => (t.id === postData.topicId ? { ...t, replyCount: t.replyCount + 1 } : t)), ) setCategories((prev) => prev.map((cat) => cat.id === topic.categoryId ? { ...cat, postCount: cat.postCount + 1 } : cat, ), ) } return newPost } catch (err) { setError('Failed to create post') console.error('Error creating post:', err) throw err } finally { setLoading(false) } } const updatePost = async (id: string, updates: Partial) => { try { setLoading(true) const updatedPost = await forumService.updatePost(id, updates) setPosts((prev) => prev.map((post) => (post.id === id ? updatedPost : post))) return updatedPost } catch (err) { setError('Failed to update post') console.error('Error updating post:', err) throw err } finally { setLoading(false) } } const deletePost = async (id: string) => { try { setLoading(true) const post = posts.find((p) => p.id === id) await forumService.deletePost(id) setPosts((prev) => prev.filter((p) => p.id !== id)) // Update topic and category counts if (post) { const topic = topics.find((t) => t.id === post.topicId) if (topic) { setTopics((prev) => prev.map((t) => t.id === post.topicId ? { ...t, replyCount: Math.max(0, t.replyCount - 1) } : t, ), ) setCategories((prev) => prev.map((cat) => cat.id === topic.categoryId ? { ...cat, postCount: Math.max(0, cat.postCount - 1) } : cat, ), ) } } } catch (err) { setError('Failed to delete post') console.error('Error deleting post:', err) throw err } finally { setLoading(false) } } const likePost = async (id: string) => { try { const updatedPost = await forumService.likePost(id) setPosts((prev) => prev.map((post) => (post.id === id ? updatedPost : post))) return updatedPost } catch (err) { setError('Failed to like post') console.error('Error liking post:', err) throw err } } const unlikePost = async (id: string) => { try { const updatedPost = await forumService.unlikePost(id) setPosts((prev) => prev.map((post) => (post.id === id ? updatedPost : post))) return updatedPost } catch (err) { setError('Failed to unlike post') console.error('Error unliking post:', err) throw err } } const markPostAsAcceptedAnswer = async (id: string) => { try { const updatedPost = await forumService.markPostAsAcceptedAnswer(id) setPosts((prev) => prev.map((post) => (post.id === id ? updatedPost : post))) return updatedPost } catch (err) { setError('Failed to mark post as accepted answer') console.error('Error marking post as accepted answer:', err) throw err } } const unmarkPostAsAcceptedAnswer = async (id: string) => { try { const updatedPost = await forumService.unmarkPostAsAcceptedAnswer(id) setPosts((prev) => prev.map((post) => (post.id === id ? updatedPost : post))) return updatedPost } catch (err) { setError('Failed to unmark post as accepted answer') console.error('Error unmarking post as accepted answer:', err) throw err } } return { // Data categories, topics, posts, loading, error, // Load functions loadCategories, loadTopics, loadPosts, // Category operations createCategory, updateCategory, updateCategoryLockState, updateCategoryActiveState, deleteCategory, // Topic operations createTopic, updateTopic, deleteTopic, pinTopic, unpinTopic, lockTopic, unlockTopic, solvedTopic, unsolvedTopic, // Post operations createPost, updatePost, deletePost, likePost, unlikePost, markPostAsAcceptedAnswer, unmarkPostAsAcceptedAnswer, // Utility clearError: () => setError(null), } }