关闭评论后前台隐藏评论能力;外观/设置/公告改用 AdminField 与 Stepper。 Co-authored-by: Cursor <cursoragent@cursor.com>
165 lines
5.2 KiB
TypeScript
165 lines
5.2 KiB
TypeScript
"use client";
|
|
|
|
import { Globe, Loader2, MessageSquare, Save, UserPlus } from "lucide-react";
|
|
import { useState } from "react";
|
|
import {
|
|
AdminField,
|
|
AdminPageHeader,
|
|
AdminSection,
|
|
AdminSettingRow,
|
|
AdminSwitch,
|
|
} from "@/components/admin";
|
|
import { apiUpdateSiteSettings, type PublicSettings } from "@/lib/api";
|
|
import { toast } from "@/lib/toast";
|
|
|
|
export default function SettingsAdmin({ initial }: { initial: PublicSettings }) {
|
|
const [siteName, setSiteName] = useState(initial.site_name);
|
|
const [siteDescription, setSiteDescription] = useState(initial.site_description);
|
|
const [allowRegister, setAllowRegister] = useState(initial.allow_register);
|
|
const [allowComments, setAllowComments] = useState(initial.allow_comments !== false);
|
|
const [savedName, setSavedName] = useState(initial.site_name);
|
|
const [savedDesc, setSavedDesc] = useState(initial.site_description);
|
|
const [saving, setSaving] = useState(false);
|
|
const [togglingReg, setTogglingReg] = useState(false);
|
|
const [togglingComments, setTogglingComments] = useState(false);
|
|
|
|
const dirty = siteName.trim() !== savedName || siteDescription.trim() !== savedDesc;
|
|
|
|
const saveIdentity = async () => {
|
|
if (saving) return;
|
|
const name = siteName.trim();
|
|
if (!name) {
|
|
toast("站点名称不能为空");
|
|
return;
|
|
}
|
|
setSaving(true);
|
|
try {
|
|
const res = await apiUpdateSiteSettings({
|
|
site_name: name,
|
|
site_description: siteDescription.trim(),
|
|
});
|
|
setSiteName(res.site_name);
|
|
setSiteDescription(res.site_description);
|
|
setSavedName(res.site_name);
|
|
setSavedDesc(res.site_description);
|
|
toast("站点信息已保存", "ok");
|
|
} catch (e) {
|
|
toast(e instanceof Error ? e.message : "保存失败");
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
const toggleRegister = async () => {
|
|
if (togglingReg) return;
|
|
const next = !allowRegister;
|
|
setTogglingReg(true);
|
|
try {
|
|
const res = await apiUpdateSiteSettings({ allow_register: next });
|
|
setAllowRegister(res.allow_register);
|
|
toast(res.allow_register ? "已开放注册" : "已关闭注册", "ok");
|
|
} catch (e) {
|
|
toast(e instanceof Error ? e.message : "保存失败");
|
|
} finally {
|
|
setTogglingReg(false);
|
|
}
|
|
};
|
|
|
|
const toggleComments = async () => {
|
|
if (togglingComments) return;
|
|
const next = !allowComments;
|
|
setTogglingComments(true);
|
|
try {
|
|
const res = await apiUpdateSiteSettings({ allow_comments: next });
|
|
setAllowComments(res.allow_comments);
|
|
toast(res.allow_comments ? "已开放评论" : "已关闭评论", "ok");
|
|
} catch (e) {
|
|
toast(e instanceof Error ? e.message : "保存失败");
|
|
} finally {
|
|
setTogglingComments(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="max-w-3xl">
|
|
<AdminPageHeader
|
|
icon={Globe}
|
|
title="站点设置"
|
|
description="配置站点名称、简介与注册/评论开关;主题色、代码折叠与动画请到「外观」页调整"
|
|
/>
|
|
|
|
<div className="flex flex-col gap-4">
|
|
<AdminSection title="基本信息" description="用于页眉品牌、页脚版权与 SEO 元信息">
|
|
<AdminField
|
|
id="site-name"
|
|
className="mb-4"
|
|
label="站点名称"
|
|
maxLength={32}
|
|
value={siteName}
|
|
onChange={setSiteName}
|
|
placeholder="姜十三论坛"
|
|
/>
|
|
|
|
<AdminField
|
|
id="site-desc"
|
|
className="mb-4"
|
|
label="站点简介"
|
|
as="textarea"
|
|
minHeight="96px"
|
|
maxLength={160}
|
|
value={siteDescription}
|
|
onChange={setSiteDescription}
|
|
placeholder="一句话介绍社区定位…"
|
|
/>
|
|
|
|
<div className="flex justify-end">
|
|
<button
|
|
type="button"
|
|
className="btn btn-primary btn-sm"
|
|
disabled={!dirty || saving}
|
|
onClick={() => void saveIdentity()}
|
|
>
|
|
{saving ? <Loader2 size={14} className="animate-spin" /> : <Save size={14} />}
|
|
保存基本信息
|
|
</button>
|
|
</div>
|
|
</AdminSection>
|
|
|
|
<AdminSettingRow
|
|
title={
|
|
<>
|
|
<UserPlus size={15} /> 开放注册
|
|
</>
|
|
}
|
|
description="关闭后,游客将无法提交注册;已有账号仍可登录。适用于内测或维护期。"
|
|
control={
|
|
<AdminSwitch
|
|
checked={allowRegister}
|
|
disabled={togglingReg}
|
|
onChange={() => void toggleRegister()}
|
|
label="开放注册"
|
|
/>
|
|
}
|
|
/>
|
|
|
|
<AdminSettingRow
|
|
title={
|
|
<>
|
|
<MessageSquare size={15} /> 开放评论
|
|
</>
|
|
}
|
|
description="关闭后前台不展示评论入口、评论数量与已有评论,并提示本站不支持评论。适用于备案审核等合规需要。"
|
|
control={
|
|
<AdminSwitch
|
|
checked={allowComments}
|
|
disabled={togglingComments}
|
|
onChange={() => void toggleComments()}
|
|
label="开放评论"
|
|
/>
|
|
}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|