/** * PostsList — Creator post management page. * * Shows all posts (draft + published) with edit, delete, and status controls. * Protected route at /creator/posts. */ import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { useDocumentTitle } from "../hooks/useDocumentTitle"; import { listPosts, deletePost, type PostRead } from "../api/posts"; import { useAuth } from "../context/AuthContext"; import { SidebarNav } from "./CreatorDashboard"; import styles from "./PostsList.module.css"; function formatDate(iso: string): string { return new Date(iso).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric", }); } export default function PostsList() { useDocumentTitle("My Posts — Chrysopedia"); const { user } = useAuth(); const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // Delete confirmation const [confirmDelete, setConfirmDelete] = useState(null); const [deleting, setDeleting] = useState(false); useEffect(() => { if (!user?.creator_id) return; let cancelled = false; setLoading(true); setError(null); listPosts(String(user.creator_id), 1, 100) .then((res) => { if (!cancelled) setPosts(res.items); }) .catch((err) => { if (!cancelled) setError(err instanceof Error ? err.message : "Failed to load posts"); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [user?.creator_id]); async function handleDelete() { if (!confirmDelete) return; setDeleting(true); try { await deletePost(String(confirmDelete.id)); setPosts((prev) => prev.filter((p) => p.id !== confirmDelete.id)); setConfirmDelete(null); } catch (err) { console.error("Delete failed:", err); } finally { setDeleting(false); } } return (

My Posts

+ New Post
{loading &&
Loading posts…
} {!loading && error &&
{error}
} {!loading && !error && posts.length === 0 && (

No posts yet. Create your first post to share with followers.

)} {!loading && !error && posts.length > 0 && ( <> {/* Desktop table */}
{posts.map((post) => ( ))}
Title Status Created Actions
{post.title} {post.is_published ? "Published" : "Draft"} {formatDate(post.created_at)}
Edit
{/* Mobile cards */}
{posts.map((post) => (
{post.title}
{post.is_published ? "Published" : "Draft"} {formatDate(post.created_at)}
Edit
))}
)} {/* Delete confirmation dialog */} {confirmDelete && (
!deleting && setConfirmDelete(null)}>
e.stopPropagation()}>

Delete Post

Are you sure you want to delete "{confirmDelete.title}"? This cannot be undone.

)}
); }