import {RefreshCcw, Save} from 'lucide-react'; import {FormEvent, useEffect, useState} from 'react'; import { getAdminCreationEntryConfig, upsertAdminCreationEntryConfig, } from '../api/adminApiClient'; import type { AdminCreationEntryTypeConfigPayload, UnifiedCreationFieldPayload, UnifiedCreationSpecPayload, } from '../api/adminApiTypes'; import {useAdminWriteConfirm} from '../components/useAdminWriteConfirm'; import {handlePageError} from './pageUtils'; interface AdminCreationEntrySwitchPageProps { token: string; onUnauthorized: (message?: string) => void; } export function AdminCreationEntrySwitchPage({ token, onUnauthorized, }: AdminCreationEntrySwitchPageProps) { const [entries, setEntries] = useState([]); const [selectedId, setSelectedId] = useState('puzzle'); const [title, setTitle] = useState(''); const [subtitle, setSubtitle] = useState(''); const [badge, setBadge] = useState(''); const [imageSrc, setImageSrc] = useState(''); const [visible, setVisible] = useState(true); const [open, setOpen] = useState(true); const [sortOrder, setSortOrder] = useState('30'); const [categoryId, setCategoryId] = useState('recent'); const [categoryLabel, setCategoryLabel] = useState('最近创作'); const [categorySortOrder, setCategorySortOrder] = useState('10'); const [unifiedCreationSpecJson, setUnifiedCreationSpecJson] = useState(''); const [isLoading, setIsLoading] = useState(false); const [isSaving, setIsSaving] = useState(false); const [listErrorMessage, setListErrorMessage] = useState(''); const [errorMessage, setErrorMessage] = useState(''); const {confirmWrite, confirmDialog} = useAdminWriteConfirm(); useEffect(() => { void refreshEntries(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [token]); async function refreshEntries() { setIsLoading(true); setListErrorMessage(''); try { const response = await getAdminCreationEntryConfig(token); const nextEntries = sortEntries(response.entries); setEntries(nextEntries); fillForm( nextEntries.find((entry) => entry.id === selectedId) ?? nextEntries[0] ?? null, ); } catch (error: unknown) { handlePageError(error, onUnauthorized, setListErrorMessage); } finally { setIsLoading(false); } } async function handleSave(event: FormEvent) { event.preventDefault(); if (isSaving) { return; } const targetId = selectedId.trim(); setErrorMessage(''); const unifiedCreationSpecResult = parseUnifiedCreationSpecJson( targetId, unifiedCreationSpecJson, ); if (!unifiedCreationSpecResult.ok) { setErrorMessage(unifiedCreationSpecResult.message); return; } const confirmed = await confirmWrite({ action: '保存创作入口开关', target: targetId, }); if (!confirmed) { return; } setIsSaving(true); try { const response = await upsertAdminCreationEntryConfig(token, { id: targetId, title: title.trim(), subtitle: subtitle.trim(), badge: badge.trim(), imageSrc: imageSrc.trim(), visible, open, sortOrder: parseInteger(sortOrder), categoryId: categoryId.trim(), categoryLabel: categoryLabel.trim(), categorySortOrder: parseInteger(categorySortOrder), unifiedCreationSpec: unifiedCreationSpecResult.spec, }); const nextEntries = sortEntries(response.entries); setEntries(nextEntries); fillForm(nextEntries.find((entry) => entry.id === targetId) ?? null); } catch (error: unknown) { handlePageError(error, onUnauthorized, setErrorMessage); } finally { setIsSaving(false); } } function fillForm(entry: AdminCreationEntryTypeConfigPayload | null) { if (!entry) { return; } setSelectedId(entry.id); setTitle(entry.title); setSubtitle(entry.subtitle); setBadge(entry.badge); setImageSrc(entry.imageSrc); setVisible(entry.visible); setOpen(entry.open); setSortOrder(String(entry.sortOrder)); setCategoryId(entry.categoryId); setCategoryLabel(entry.categoryLabel); setCategorySortOrder(String(entry.categorySortOrder)); setUnifiedCreationSpecJson(formatUnifiedCreationSpecJson(entry.unifiedCreationSpec)); } return (

创作入口开关

控制创作中心入口展示与运行态路由可用性

{listErrorMessage ? (
{listErrorMessage}
) : null}
统一创作契约 {unifiedCreationSpecJson.trim() ? '已配置' : '未配置'}
{unifiedCreationSpecJson.trim() ? ( ) : (
未配置统一创作页契约
)}