import { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import { Globe2, ExternalLink, Star } from 'lucide-react'; import { Spinner } from '@/components/ui/spinner'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { notify } from '@/lib/notify'; import { api } from '../../api/client'; import type { CommunityInstance } from '../../api/types'; import { useAdminGuard } from '../../layouts/AdminLayout'; import { formatTime } from '../../utils/content'; import { cn } from '@/lib/utils'; export default function AdminCommunityPage() { const { ready } = useAdminGuard(); const [hubEnabled, setHubEnabled] = useState(false); const [list, setList] = useState([]); const [loading, setLoading] = useState(true); const [featuringId, setFeaturingId] = useState(null); useEffect(() => { if (!ready) return; setLoading(true); api.adminCommunityInstances() .then((r) => { setHubEnabled(!!r.hub_enabled); setList(Array.isArray(r.instances) ? r.instances : []); }) .catch(() => { setList([]); }) .finally(() => setLoading(false)); }, [ready]); const handleToggleFeatured = async (row: CommunityInstance) => { if (featuringId) return; setFeaturingId(row.instance_id); try { const r = await api.adminFeatureCommunityInstance(row.instance_id, { featured: !row.featured, featured_note: row.featured_note || '', }); setList((prev) => prev.map((item) => ( item.instance_id === row.instance_id ? { ...item, ...r.instance } : item ))); notify.success(r.message); } catch (e: unknown) { notify.error(e instanceof Error ? e.message : '操作失败'); } finally { setFeaturingId(null); } }; if (!ready || loading) { return
; } return (

公网实例

接收自愿上报的心跳;设为精选后会出现在 {' '} 公开展柜

{!hubEnabled && (

本站未开启社区枢纽。该能力仅供官方主站运维配置开启( app.ini[community] hub = true {' '}或环境变量 JIANG13_COMMUNITY_HUB=1 ),普通部署无需也无法在后台打开。

)}
实例列表 {list.length} 个
{list.length === 0 ? (

暂无上报记录

) : (
{list.map((row) => ( ))}
状态 站点 版本 用户 帖子 最近心跳 精选
{row.online ? '在线' : '离线'}
{row.featured && } {row.site_name || '未命名站点'} {row.site_url}
{row.version || '—'} {row.users} {row.posts} {formatTime(row.last_seen_at)}
)}
); }