Files
memind_adm/src/admin/pages/MindSpacePage.tsx
T

96 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useCallback, useEffect, useState, type FormEvent } from 'react';
import { getMindSpaceAdminConfig, updateMindSpaceAdminConfig } from '../../api/client';
import type { MindSpaceAdminConfig } from '../../types';
function safeConfig(config: MindSpaceAdminConfig | null): MindSpaceAdminConfig {
return config ?? { publicPageLimit: 10, analytics: { enabled: false, websiteId: '', analyticsUrl: 'http://127.0.0.1:3100', domains: '127.0.0.1,localhost', idSecretConfigured: false } };
}
export function MindSpacePage() {
const [config, setConfig] = useState<MindSpaceAdminConfig | null>(null);
const [limit, setLimit] = useState('10');
const [loading, setLoading] = useState(true);
const [busy, setBusy] = useState(false);
const [error, setError] = useState<string | null>(null);
const [message, setMessage] = useState<string | null>(null);
const load = useCallback(async () => {
setLoading(true);
setError(null);
setMessage(null);
try {
const nextConfig = await getMindSpaceAdminConfig();
setConfig(nextConfig);
setLimit(String(nextConfig.publicPageLimit));
} catch (err) {
setError(err instanceof Error ? err.message : '加载 MindSpace 配置失败');
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
void load();
}, [load]);
const handleSave = async (event: FormEvent) => {
event.preventDefault();
setBusy(true);
setError(null);
setMessage(null);
try {
const nextConfig = await updateMindSpaceAdminConfig({ publicPageLimit: Number(limit) });
setConfig(nextConfig);
setLimit(String(nextConfig.publicPageLimit));
setMessage(`已更新为 ${nextConfig.publicPageLimit},主站会立即按新值校验。`);
} catch (err) {
setError(err instanceof Error ? err.message : '保存 MindSpace 配置失败');
} finally {
setBusy(false);
}
};
const current = safeConfig(config);
return (
<div className="admin-page">
<div className="admin-page-head">
<h2>MindSpace </h2>
<p className="muted"></p>
</div>
{error && <p className="banner banner-error">{error}</p>}
{message && <p className="banner banner-info">{message}</p>}
<section className="admin-card">
<h2></h2>
<p className="muted">
{loading ? '—' : current.publicPageLimit}
</p>
<form className="admin-form" onSubmit={handleSave}>
<label className="admin-form-row">
<span>线</span>
<input
type="number"
min={1}
step={1}
value={limit}
onChange={(e) => setLimit(e.target.value)}
inputMode="numeric"
required
/>
</label>
<div className="admin-actions">
<button type="submit" className="send-btn" disabled={busy || loading}>
{busy ? '保存中...' : '保存配置'}
</button>
<button type="button" className="ghost-btn" onClick={() => void load()} disabled={busy}>
</button>
</div>
</form>
</section>
</div>
);
}