import { useEffect, useMemo, useRef, useState } from 'react' import { Container } from 'react-bootstrap' import { Link } from 'react-router-dom' import { fetchUserSetting, listAllForums, saveUserSetting } from '../api/client' import { useTranslation } from 'react-i18next' import { useAuth } from '../context/AuthContext' export default function BoardIndex() { const [forums, setForums] = useState([]) const [error, setError] = useState('') const [loading, setLoading] = useState(true) const [collapsed, setCollapsed] = useState({}) const { t } = useTranslation() const { token } = useAuth() const collapsedKey = 'board_index.collapsed_categories' const storageKey = `speedbb_user_setting_${collapsedKey}` const saveTimer = useRef(null) useEffect(() => { listAllForums() .then(setForums) .catch((err) => setError(err.message)) .finally(() => setLoading(false)) }, []) useEffect(() => { if (!token) return let active = true const cached = localStorage.getItem(storageKey) if (cached) { try { const parsed = JSON.parse(cached) if (Array.isArray(parsed)) { const next = {} parsed.forEach((id) => { next[String(id)] = true }) setCollapsed(next) } } catch { localStorage.removeItem(storageKey) } } fetchUserSetting(collapsedKey) .then((setting) => { if (!active) return const next = {} if (Array.isArray(setting?.value)) { setting.value.forEach((id) => { next[String(id)] = true }) } setCollapsed(next) localStorage.setItem(storageKey, JSON.stringify(setting?.value || [])) }) .catch(() => {}) return () => { active = false } }, [token]) const getParentId = (forum) => { if (!forum.parent) return null if (typeof forum.parent === 'string') { return forum.parent.split('/').pop() } return forum.parent.id ?? null } const forumTree = useMemo(() => { const map = new Map() const roots = [] forums.forEach((forum) => { map.set(String(forum.id), { ...forum, children: [] }) }) forums.forEach((forum) => { const parentId = getParentId(forum) const node = map.get(String(forum.id)) if (parentId && map.has(String(parentId))) { map.get(String(parentId)).children.push(node) } else { roots.push(node) } }) const sortNodes = (nodes) => { nodes.sort((a, b) => { if (a.position !== b.position) return a.position - b.position return a.name.localeCompare(b.name) }) nodes.forEach((node) => sortNodes(node.children)) } sortNodes(roots) return roots }, [forums]) const renderRows = (nodes) => nodes.map((node) => (
{t('home.loading')}
} {error &&{error}
} {!loading && forumTree.length === 0 && ({t('home.empty')}
)} {forumTree.length > 0 && (