{post.title}
+ {post.excerpt &&{post.excerpt}
} +diff --git a/src/components/shim/PageEditor.tsx b/src/components/shim/PageEditor.tsx new file mode 100644 index 0000000..be2e839 --- /dev/null +++ b/src/components/shim/PageEditor.tsx @@ -0,0 +1,220 @@ +// Simple Page Editor Component +import React, { useState } from 'react'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +interface PageEditorProps { + siteId: string; + pageId?: string; + initialData?: { + name: string; + route: string; + html_content: string; + meta_title?: string; + meta_description?: string; + status: string; + }; + onSave?: (page: any) => void; + onCancel?: () => void; +} + +export default function PageEditor({ siteId, pageId, initialData, onSave, onCancel }: PageEditorProps) { + const [formData, setFormData] = useState(initialData || { + name: '', + route: '/', + html_content: '', + meta_title: '', + meta_description: '', + status: 'draft' + }); + + const queryClient = useQueryClient(); + + const saveMutation = useMutation({ + mutationFn: async (data: typeof formData) => { + const url = pageId + ? `/api/shim/pages/${pageId}` + : `/api/shim/pages/create`; + + const method = pageId ? 'PUT' : 'POST'; + + const response = await fetch(url, { + method, + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${import.meta.env.PUBLIC_GOD_MODE_TOKEN || 'local-dev-token'}` + }, + body: JSON.stringify({ ...data, site_id: siteId }) + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.message || 'Failed to save page'); + } + + return response.json(); + }, + onSuccess: (page) => { + queryClient.invalidateQueries({ queryKey: ['pages'] }); + if (onSave) onSave(page); + } + }); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + saveMutation.mutate(formData); + }; + + const handlePreview = () => { + if (pageId) { + window.open(`/preview/page/${pageId}`, '_blank'); + } else { + alert('Please save the page first to preview it'); + } + }; + + return ( +
+ ); +} diff --git a/src/components/shim/PostEditor.tsx b/src/components/shim/PostEditor.tsx new file mode 100644 index 0000000..88dff27 --- /dev/null +++ b/src/components/shim/PostEditor.tsx @@ -0,0 +1,220 @@ +// Simple Post Editor Component +import React, { useState } from 'react'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +interface PostEditorProps { + siteId: string; + postId?: string; + initialData?: { + name: string; + slug: string; + html_content: string; + meta_title?: string; + meta_description?: string; + status: string; + }; + onSave?: (post: any) => void; + onCancel?: () => void; +} + +export default function PostEditor({ siteId, postId, initialData, onSave, onCancel }: PostEditorProps) { + const [formData, setFormData] = useState(initialData || { + name: '', + slug: '/', + html_content: '', + meta_title: '', + meta_description: '', + status: 'draft' + }); + + const queryClient = useQueryClient(); + + const saveMutation = useMutation({ + mutationFn: async (data: typeof formData) => { + const url = postId + ? `/api/shim/posts/${postId}` + : `/api/shim/posts/create`; + + const method = postId ? 'PUT' : 'POST'; + + const response = await fetch(url, { + method, + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${import.meta.env.PUBLIC_GOD_MODE_TOKEN || 'local-dev-token'}` + }, + body: JSON.stringify({ ...data, site_id: siteId }) + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.message || 'Failed to save post'); + } + + return response.json(); + }, + onSuccess: (post) => { + queryClient.invalidateQueries({ queryKey: ['posts'] }); + if (onSave) onSave(post); + } + }); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + saveMutation.mutate(formData); + }; + + const handlePreview = () => { + if (postId) { + window.open(`/preview/post/${postId}`, '_blank'); + } else { + alert('Please save the post first to preview it'); + } + }; + + return ( + + ); +} diff --git a/src/pages/admin/pages/new.astro b/src/pages/admin/pages/new.astro new file mode 100644 index 0000000..4848d5f --- /dev/null +++ b/src/pages/admin/pages/new.astro @@ -0,0 +1,39 @@ +--- +// Admin: Create New Page +import AdminLayout from '@/layouts/AdminLayout.astro'; +import PageEditor from '@/components/shim/PageEditor'; + +// Get first site ID (for demo, you'd select from a dropdown) +const { rows: sites } = await (await import('@/lib/db')).pool.query<{id: string}>('SELECT id FROM sites LIMIT 1'); +const siteId = sites[0]?.id; + +if (!siteId) { + return Astro.redirect('/admin/sites'); +} +--- + +Add a new static page to your site
+Add a new blog post
+{post.excerpt}
} +