import { lazy, Suspense, useState } from 'react' import Modal from '../../../components/Modal.jsx' import { api } from '../../../api/client.js' const RichTextEditor = lazy(() => import('../../../components/RichTextEditor.jsx')) const CATEGORIES = [ { v: 'news', l: 'News' }, { v: 'five-on-friday', l: 'Five on Friday' }, { v: 'newsletter', l: 'Newsletter' }, { v: 'screenshots', l: 'Screenshots' }, ] const DB_TO_URL = { news: 'news', five_on_friday: 'five-on-friday', newsletter: 'newsletter', screenshot: 'screenshots' } export default function PostEditor({ post, onClose, onSaved }) { const isEdit = Boolean(post) const [form, setForm] = useState({ category: post ? DB_TO_URL[post.category] || 'news' : 'news', title: post?.title || '', slug: post?.slug || '', excerpt: post?.excerpt || '', body: post?.body || '', image_url: post?.image_url || '', published: post ? Boolean(post.published) : false, }) const [busy, setBusy] = useState(false) const [uploading, setUploading] = useState(false) const [error, setError] = useState('') const set = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.type === 'checkbox' ? e.target.checked : e.target.value })) const isScreenshot = form.category === 'screenshots' async function onUpload(e) { const file = e.target.files?.[0] if (!file) return setUploading(true) setError('') try { const res = await api.admin.uploadImage(file) setForm((f) => ({ ...f, image_url: res.image_url })) } catch (err) { setError(err.message || 'Upload failed') } finally { setUploading(false) } } async function save() { if (!form.title.trim()) return setError('Title is required.') if (isScreenshot && !form.image_url) return setError('Screenshots need an image.') setBusy(true) setError('') const payload = { category: form.category, title: form.title.trim(), slug: form.slug.trim() || null, excerpt: form.excerpt.trim() || null, body: form.body || null, image_url: form.image_url || null, published: form.published, } try { if (isEdit) await api.admin.updatePost(post.id, payload) else await api.admin.createPost(payload) onSaved() } catch (err) { setError(err.message || 'Could not save the post.') setBusy(false) } } async function remove() { if (!confirm('Delete this post? This cannot be undone.')) return setBusy(true) try { await api.admin.deletePost(post.id) onSaved() } catch (err) { setError(err.message || 'Could not delete.') setBusy(false) } } return ( {isEdit && ( )} } >
{error &&

{error}

}
Body }> setForm((f) => ({ ...f, body: html }))} variant={isScreenshot ? 'minimal' : 'post'} />
) } const delStyle = { border: '1px solid #6e3b38', borderRadius: 999, padding: '7px 16px', background: 'rgba(110,59,56,0.18)', color: '#d98b84', fontSize: '0.86rem', cursor: 'pointer', marginRight: 'auto', }