'use client'; import { useRouter } from 'next/navigation'; import { Button } from '@nice/ui/components/button'; import { Card, CardContent, CardHeader, CardTitle } from '@nice/ui/components/card'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DialogClose, } from '@nice/ui/components/dialog'; import { Input } from '@nice/ui/components/input'; import { Label } from '@nice/ui/components/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@nice/ui/components/select'; import { Separator } from '@nice/ui/components/separator'; import { Badge } from '@nice/ui/components/badge'; import { Textarea } from '@nice/ui/components/textarea'; import { Switch } from '@nice/ui/components/switch'; import { IconArrowLeft, IconCheck, IconClock, IconDeviceFloppy, IconSettings, IconCalendar } from '@tabler/icons-react'; import { DateTimePicker } from '@nice/ui/components/date-time-picker'; import { useQuery } from '@tanstack/react-query'; import { useTRPC } from '@fenghuo/client'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import 'dayjs/locale/zh-cn'; import { DeptSelect } from '../selector/dept-select'; import { TermSelect } from '../selector/term-select'; import { PostStatus, PostType } from '@fenghuo/common/post'; import { useEditorContext } from '@/components/articles/context'; import { useIsClient } from '@/hooks/use-is-client'; dayjs.extend(relativeTime); dayjs.locale('zh-cn'); interface EditorSidebarProps { className?: string; } export function EditorSidebar({ className }: EditorSidebarProps) { const router = useRouter(); const trpc = useTRPC(); const isClient = useIsClient(); // 使用编辑器Context const { state, updateField, save } = useEditorContext(); // 获取分类数据 const { data: taxonomiesData } = useQuery({ ...trpc.taxonomy.findMany.queryOptions({ where: { postTypes: { has: PostType.ARTICLE, }, }, }), }); const handleBack = () => { router.back(); }; const handleSave = (options?: { newStatus?: PostStatus; successMessage?: string }) => { save(options); }; const handleTermChange = (taxonomyId: string, termId: string | string[] | null) => { // 只处理单选情况,如果是数组取第一个值,如果是空数组则为null const finalTermId = Array.isArray(termId) ? (termId.length > 0 ? termId[0] : null) : termId; const otherTerms = state.terms.filter((t) => t.taxonomyId !== taxonomyId); const newTerms = finalTermId ? [...otherTerms, { id: finalTermId, taxonomyId }] : otherTerms; updateField('terms', newTerms); }; const formatTime = (date: Date) => { return dayjs(date).fromNow(); }; const renderAutoSaveStatus = () => { if (state.isSaving) { return (
保存中...
); } if (state.lastSaved && !state.hasUnsavedChanges) { return (
{isClient ? `已保存 ${formatTime(state.lastSaved)}` : '已保存'}
); } return (
{state.hasUnsavedChanges ? '有未保存的更改' : '未保存更改'}
); }; return (
{state.status === PostStatus.DRAFT ? '草稿' : state.status === PostStatus.PUBLISHED ? '已发布' : '已归档'}
{renderAutoSaveStatus()}
{state.status === PostStatus.DRAFT && ( 确认发布 发布后,文章将对所有有权限的用户可见。您确定要发布吗? )}
文章设置
updateField('title', e.target.value)} placeholder="请输入文章标题" className="text-sm" required={state.status === PostStatus.PUBLISHED || state.status === PostStatus.ARCHIVED} />