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 ( +
+ + {/* Name */} +
+ + setFormData({ ...formData, name: e.target.value })} + className="w-full px-4 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white focus:outline-none focus:border-blue-500" + required + /> +
+ + {/* Route */} +
+ + setFormData({ ...formData, route: e.target.value })} + className="w-full px-4 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white focus:outline-none focus:border-blue-500" + pattern="^\/[a-z0-9-\/]*$" + placeholder="/about" + required + /> +

Example: /about, /contact, /services/web

+
+ + {/* HTML Content */} +
+ +