import { resolveSettingsHash, SETTINGS_GROUPS, SETTINGS_SECTIONS, type SettingsSectionDef, type SettingsSectionId, } from "@umt/contracts"; import { Bot, Database, Download, FolderTree, Globe, type LucideIcon, Monitor, Search, Settings2, Shield, Tags, Tv, Wand2, } from "lucide-react"; import type { ReactNode } from "react"; import { AccountSection } from "./account.tsx"; import { AcquireSection } from "./acquire.tsx"; import { AgentSection } from "./agent.tsx"; import { CacheSection } from "./cache.tsx"; import { DownloadersSection } from "./downloaders.tsx"; import { MediaServersSection } from "./instances.tsx"; import { InterfaceSection } from "./interface.tsx"; import { LibrarySection } from "./library.tsx"; import { MetadataSection } from "./metadata.tsx"; import { OrganizeSection } from "./organize.tsx"; import { SitesSection } from "./sites.tsx"; import { SystemSection } from "./system.tsx"; // 设置分区:文案、分组与字段归属在 contracts 的 SETTINGS_SECTIONS,这里只挂图标与渲染 const UI: Record ReactNode }> = { downloaders: { icon: Download, render: () => }, "media-servers": { icon: Tv, render: () => }, sites: { icon: Globe, render: () => }, metadata: { icon: Tags, render: () => }, acquire: { icon: Search, render: () => }, library: { icon: FolderTree, render: () => }, organize: { icon: Wand2, render: () => }, agent: { icon: Bot, render: () => }, system: { icon: Settings2, render: () => }, cache: { icon: Database, render: () => }, account: { icon: Shield, render: () => }, interface: { icon: Monitor, render: () => }, }; export type SectionView = SettingsSectionDef & { icon: LucideIcon; render: () => ReactNode }; export const SECTIONS: SectionView[] = SETTINGS_SECTIONS.map((s) => ({ ...s, ...UI[s.id] })); /** 左栏分组:接入 / 流程 / 系统 */ export const SECTION_GROUPS = SETTINGS_GROUPS.map((g) => ({ ...g, sections: SECTIONS.filter((s) => s.group === g.id), })); /** * URL hash:`#<分区>` 或 `#<分区>/<节>`;旧 hash 换成新位置(moved = true 时页面用 replace 改地址栏), * 不认识的落到第一个分区 */ export function parseSettingsHash(hash: string): { section: SectionView; anchor: string | null; moved: boolean } { const r = resolveSettingsHash(hash); const section = SECTIONS.find((s) => s.id === r.section) ?? (SECTIONS[0] as SectionView); return { section, anchor: r.section ? r.anchor : null, moved: r.moved }; } export const settingsHash = (section: string, anchor?: string | null) => `#${section}${anchor ? `/${anchor}` : ""}`;