import { Button, Drawer, FormField, Icon, Input, Notice, Space, Textarea } from '@stash/ui' import { useEffect, useState } from 'react' import { fetchItem, saveItem, type EntryRecord } from '../../items' /** * 条目编辑器(P2):右侧 Drawer 表单,就地改标题 / 简介 / 标签 / 正文等。 * * `updatedAt` 做乐观锁:别人先改过就提示刷新,避免静默覆盖。 */ type ItemEditorProps = { open: boolean itemKey: string | null onClose: () => void onSaved: (entry: EntryRecord) => void } type FormState = { name: string description: string tags: string badge: string comment: string summary: string body: string cover: string banner: string href: string } const emptyForm: FormState = { name: '', description: '', tags: '', badge: '', comment: '', summary: '', body: '', cover: '', banner: '', href: '', } export function ItemEditor({ open, itemKey, onClose, onSaved }: ItemEditorProps) { const [entry, setEntry] = useState(null) const [form, setForm] = useState(emptyForm) const [loading, setLoading] = useState(false) const [saving, setSaving] = useState(false) const [error, setError] = useState('') useEffect(() => { if (!open || itemKey === null) return let alive = true setLoading(true) setError('') fetchItem(itemKey).then((result) => { if (!alive) return setLoading(false) if (!result.ok) { setError(result.error) return } const next = result.entry setEntry(next) setForm({ name: next.name, description: next.description, tags: next.tags.join(','), badge: next.badge, comment: next.comment, summary: next.summary, body: next.body, cover: next.cover, banner: next.banner, href: next.href, }) }) return () => { alive = false } }, [open, itemKey]) const update = (patch: Partial) => setForm((previous) => ({ ...previous, ...patch })) const save = async () => { if (entry === null) return setSaving(true) setError('') const result = await saveItem(entry.key, entry.updated_at, { ...form, format: entry.format, icon: entry.icon, tags: form.tags .split(/[,,]/) .map((tag) => tag.trim()) .filter(Boolean), }) setSaving(false) if (!result.ok) { setError(result.error) return } onSaved(result.entry) onClose() } return ( } > {loading &&

正在读取…

} {error !== '' && ( {error} )} {!loading && entry !== null && ( update({ name: event.target.value })} /> update({ description: event.target.value })} /> update({ tags: event.target.value })} /> update({ comment: event.target.value })} />