import { useCallback, useEffect, useState, type FormEvent } from 'react'; import { getMindSpaceAdminConfig, getRybbitSsoUrl, getUmamiSsoUrl, updateMindSpaceAdminConfig } from '../../api/client'; const initial = { enabled: false, websiteId: '', analyticsUrl: 'http://127.0.0.1:3100', domains: '127.0.0.1,localhost', idSecretConfigured: false, }; export function AnalyticsConfigPage() { const [config, setConfig] = useState(initial); const [secret, setSecret] = useState(''); const [busy, setBusy] = useState(false); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [message, setMessage] = useState(null); const [openingUmami, setOpeningUmami] = useState(false); const [openingRybbit, setOpeningRybbit] = useState(false); const load = useCallback(async () => { setLoading(true); try { const result = await getMindSpaceAdminConfig(); setConfig({ ...initial, ...result.analytics }); } catch (err) { setError(err instanceof Error ? err.message : '加载 Analytics 配置失败'); } finally { setLoading(false); } }, []); useEffect(() => { void load(); }, [load]); const save = async (event: FormEvent) => { event.preventDefault(); setBusy(true); setError(null); setMessage(null); try { const result = await updateMindSpaceAdminConfig({ analytics: { enabled: config.enabled, websiteId: config.websiteId, analyticsUrl: config.analyticsUrl, domains: config.domains, ...(secret.trim() ? { idSecret: secret.trim() } : {}) }, }); setConfig({ ...initial, ...result.analytics }); setSecret(''); setMessage('Analytics 配置已保存;密钥不会在后台回显。'); } catch (err) { setError(err instanceof Error ? err.message : '保存 Analytics 配置失败'); } finally { setBusy(false); } }; const openUmami = async () => { setOpeningUmami(true); setError(null); try { window.location.assign(await getUmamiSsoUrl()); } catch (err) { setError(err instanceof Error ? err.message : '无法打开 Umami'); setOpeningUmami(false); } }; const openRybbit = async () => { setOpeningRybbit(true); setError(null); try { window.location.assign(await getRybbitSsoUrl()); } catch (err) { setError(err instanceof Error ? err.message : '无法打开 Rybbit'); setOpeningRybbit(false); } }; return

Analytics 配置

进入统计后台,或配置 Memind 生成页面的 Umami 统计。

{error &&

{error}

} {message &&

{message}

}

Rybbit 行为分析

查看页面访问、用户会话、停留时间、点击和会话回放等行为明细。

Umami

; }