From df1a3b726efed69c822bc99797c1d85fee060b03 Mon Sep 17 00:00:00 2001 From: Ender Date: Fri, 24 Oct 2025 15:53:34 +0200 Subject: [PATCH] feat: add post status, delete functionality and improve metadata handling in editor --- apps/admin/src/components/EditorShell.tsx | 59 +++++++++++++++++++---- apps/api/src/posts.ts | 14 ++++++ 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/apps/admin/src/components/EditorShell.tsx b/apps/admin/src/components/EditorShell.tsx index ca7bc62..e744e03 100644 --- a/apps/admin/src/components/EditorShell.tsx +++ b/apps/admin/src/components/EditorShell.tsx @@ -1,4 +1,4 @@ -import { Box, Button, Stack, Typography } from '@mui/material'; +import { Box, Button, Stack, Typography, TextField, MenuItem } from '@mui/material'; import AdminLayout from '../layout/AdminLayout'; import Recorder from '../features/recorder/Recorder'; import RichEditor from './RichEditor'; @@ -13,6 +13,7 @@ export default function EditorShell({ onLogout, initialPostId, onBack }: { onLog const editorRef = useRef(null); const [meta, setMeta] = useState({ title: '', tagsText: '', canonicalUrl: '', featureImage: '' }); const [postClips, setPostClips] = useState>([]); + const [postStatus, setPostStatus] = useState<'inbox' | 'editing' | 'ready_for_publish' | 'published' | 'archived'>('editing'); useEffect(() => { const savedId = initialPostId || localStorage.getItem('voxblog_draft_id'); @@ -26,7 +27,17 @@ export default function EditorShell({ onLogout, initialPostId, onBack }: { onLog const data = await res.json(); setDraft(data.contentHtml || ''); setDraftId(data.id || savedId); + localStorage.setItem('voxblog_draft_id', data.id || savedId); + if (data.contentHtml) localStorage.setItem('voxblog_draft', data.contentHtml); if (Array.isArray(data.audioClips)) setPostClips(data.audioClips); + setMeta((m) => ({ + ...m, + title: data.title || '', + tagsText: data.tagsText || '', + canonicalUrl: data.canonicalUrl || '', + featureImage: data.featureImage || '' + })); + if (data.status) setPostStatus(data.status); } } catch {} })(); @@ -64,9 +75,40 @@ export default function EditorShell({ onLogout, initialPostId, onBack }: { onLog return ( - - VoxBlog Editor + + + Post + setMeta((m) => ({ ...m, title: e.target.value }))} + sx={{ flex: 1, minWidth: 200 }} + /> + setPostStatus(e.target.value as any)} sx={{ minWidth: 200 }}> + inbox + editing + ready_for_publish + published + archived + + + {draftId && ( + + )} + {onBack && } @@ -77,14 +119,11 @@ export default function EditorShell({ onLogout, initialPostId, onBack }: { onLog initialClips={postClips} /> - Post + Content setDraft(html)} placeholder="Write your post..." /> - - - {draftId && ( - ID: {draftId} - )} - + {draftId && ( + ID: {draftId} + )} { } }); +// Delete post (and its audio clips) +router.delete('/:id', async (req, res) => { + try { + const id = req.params.id; + if (!id) return res.status(400).json({ error: 'id is required' }); + await db.delete(audioClips).where(eq(audioClips.postId, id)); + await db.delete(posts).where(eq(posts.id, id)); + return res.json({ success: true }); + } catch (err) { + console.error('Delete post error:', err); + return res.status(500).json({ error: 'Failed to delete post' }); + } +}); + export default router;