"use client"; import { useEffect, useState } from "react"; import { api } from "@/lib/api"; import { cn } from "@/lib/utils"; import { Pencil, Trash2, X, Download, Star, EyeOff, } from "lucide-react"; export default function BlogPage() { const [posts, setPosts] = useState([]); const [categories, setCategories] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [importOpen, setImportOpen] = useState(false); const [importInput, setImportInput] = useState(""); const [importPreview, setImportPreview] = useState(null); const [importing, setImporting] = useState(false); const [fetching, setFetching] = useState(false); const [editingPost, setEditingPost] = useState(null); const [editForm, setEditForm] = useState({ title: "", slug: "", excerpt: "", categories: [] as string[], featured: false, visible: true, }); const loadData = async () => { try { const [p, c] = await Promise.all([ api.getPosts({ all: true }), api.getCategories(), ]); setPosts(p.posts || []); setCategories(c); } catch (err: any) { setError(err.message); } finally { setLoading(false); } }; useEffect(() => { loadData(); }, []); const handleFetchPreview = async () => { if (!importInput.trim()) return; setFetching(true); setError(""); try { const isNaddr = importInput.startsWith("naddr"); const data = await api.fetchNostrEvent( isNaddr ? { naddr: importInput } : { eventId: importInput } ); setImportPreview(data); } catch (err: any) { setError(err.message); setImportPreview(null); } finally { setFetching(false); } }; const handleImport = async () => { if (!importInput.trim()) return; setImporting(true); setError(""); try { const isNaddr = importInput.startsWith("naddr"); await api.importPost( isNaddr ? { naddr: importInput } : { eventId: importInput } ); setImportInput(""); setImportPreview(null); setImportOpen(false); await loadData(); } catch (err: any) { setError(err.message); } finally { setImporting(false); } }; const openEdit = (post: any) => { setEditingPost(post); setEditForm({ title: post.title || "", slug: post.slug || "", excerpt: post.excerpt || "", categories: post.categories?.map((c: any) => c.id || c) || [], featured: post.featured || false, visible: post.visible !== false, }); }; const handleSaveEdit = async () => { if (!editingPost) return; setError(""); try { await api.updatePost(editingPost.id, editForm); setEditingPost(null); await loadData(); } catch (err: any) { setError(err.message); } }; const handleDelete = async (id: string) => { if (!confirm("Delete this post?")) return; try { await api.deletePost(id); await loadData(); } catch (err: any) { setError(err.message); } }; const toggleCategory = (catId: string) => { setEditForm((prev) => ({ ...prev, categories: prev.categories.includes(catId) ? prev.categories.filter((c) => c !== catId) : [...prev.categories, catId], })); }; if (loading) { return (
Loading posts...
); } return (

Blog Management

{error &&

{error}

} {importOpen && (

Import from Nostr

setImportInput(e.target.value)} className="bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 w-full focus:outline-none focus:ring-1 focus:ring-primary/40 flex-1" />
{importPreview && (

{importPreview.title || "Untitled"}

{importPreview.content?.slice(0, 300)}...

)}
)} {editingPost && (

Edit Post Metadata

setEditForm({ ...editForm, title: e.target.value })} className="bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 w-full focus:outline-none focus:ring-1 focus:ring-primary/40" /> setEditForm({ ...editForm, slug: e.target.value })} className="bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 w-full focus:outline-none focus:ring-1 focus:ring-primary/40" />