新增模块: - 友链(friendlink)后端处理 + 前端管理页与友链板 - 书库(library):导入、章节、封面、阅读页、横竖版自适应 AdaptiveCoverSlot - 顶栏导航(header_nav)配置与 MobileTabBar/MobileRailDrawers 移动端抽屉 - 排行榜 service 测试、站点页面测试、时间线发布(timeline_release) 其它改动: - 后端 handlers/services 全量小幅调整 - 前端组件、库函数、URL/品牌/站点 URL 工具更新 - Lightbox 图片、MdEntries 条目卡、coverColor 派生色相等前端能力
52 lines
2.5 KiB
TypeScript
52 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useState } from "react";
|
|
import ConfirmDialog from "@/components/ConfirmDialog";
|
|
import useUnsavedGuard from "@/hooks/useUnsavedGuard";
|
|
import BasicIdentityPanel from "./BasicIdentityPanel";
|
|
import BrandSeoPanel from "./BrandSeoPanel";
|
|
import FooterLinksPanel from "./FooterLinksPanel";
|
|
import HeaderNavPanel from "./HeaderNavPanel";
|
|
import MobileTabBarPanel from "./MobileTabBarPanel";
|
|
import UrlStylePanel from "./UrlStylePanel";
|
|
import type { PublicSettings } from "@/lib/api";
|
|
|
|
export default function BasicSettings({ initial }: { initial: PublicSettings }) {
|
|
const [live, setLive] = useState(initial);
|
|
const [basicDirty, setBasicDirty] = useState(false);
|
|
const [brandDirty, setBrandDirty] = useState(false);
|
|
const [seoDirty, setSeoDirty] = useState(false);
|
|
const [urlStyleDirty, setUrlStyleDirty] = useState(false);
|
|
const [mobileTabsDirty, setMobileTabsDirty] = useState(false);
|
|
const [headerNavDirty, setHeaderNavDirty] = useState(false);
|
|
const dirty = basicDirty || brandDirty || seoDirty || urlStyleDirty || mobileTabsDirty || headerNavDirty;
|
|
const leave = useUnsavedGuard(dirty);
|
|
|
|
const onBasicDirty = useCallback((d: boolean) => setBasicDirty(d), []);
|
|
const onBrandDirty = useCallback((d: boolean) => setBrandDirty(d), []);
|
|
const onSeoDirty = useCallback((d: boolean) => setSeoDirty(d), []);
|
|
const onUrlStyleDirty = useCallback((d: boolean) => setUrlStyleDirty(d), []);
|
|
const onMobileTabsDirty = useCallback((d: boolean) => setMobileTabsDirty(d), []);
|
|
const onHeaderNavDirty = useCallback((d: boolean) => setHeaderNavDirty(d), []);
|
|
|
|
return (
|
|
<div className="admin-settings-stack">
|
|
<BasicIdentityPanel initial={live} onSaved={setLive} onDirtyChange={onBasicDirty} />
|
|
<BrandSeoPanel initial={live} onSaved={setLive} onDirtyChange={onBrandDirty} />
|
|
<UrlStylePanel initial={live} onSaved={setLive} onDirtyChange={onUrlStyleDirty} />
|
|
<HeaderNavPanel initial={live} onSaved={setLive} onDirtyChange={onHeaderNavDirty} />
|
|
<MobileTabBarPanel initial={live} onSaved={setLive} onDirtyChange={onMobileTabsDirty} />
|
|
<FooterLinksPanel initial={live} onSaved={setLive} onDirtyChange={onSeoDirty} />
|
|
<ConfirmDialog
|
|
open={leave.leaveOpen}
|
|
title="有未保存的修改"
|
|
message="离开后,当前保存单元里尚未写入的修改会丢失。确定离开?"
|
|
confirmLabel="离开"
|
|
danger
|
|
onCancel={leave.cancelLeave}
|
|
onConfirm={leave.confirmLeave}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|