import { useCallback, useEffect, useRef, useState } from "react"; import { Navigate, useNavigate, useParams, useSearchParams } from "react-router-dom"; import { artifactsApi, docsApi } from "../api/endpoints"; import type { Artifact, Doc, LaunchKitContent, Platform } from "../api/types"; import { ScheduleModal } from "../components/ScheduleModal"; import { BackArrow, ConfirmButton, CopyButton, errorMessage, formatDate, JobProgress, Loading, PageHeader, StatusPill } from "../components/ui"; import { useJob } from "../hooks/useJob"; type PostKey = keyof LaunchKitContent["posts"]; const PLATFORM_OF: Record = { x_thread: { platform: "x", label: "X thread", limit: 280, thread: true }, linkedin: { platform: "linkedin", label: "LinkedIn", limit: 3000, thread: false }, substack_notes: { platform: "substack_notes", label: "Substack Notes", limit: 2000, thread: false }, bluesky: { platform: "bluesky", label: "Bluesky", limit: 300, thread: true }, }; function PostsEditor({ kit, keyName, onSave }: { kit: Artifact; keyName: PostKey; onSave: (posts: string[]) => Promise }) { const c = kit.content as LaunchKitContent; const meta = PLATFORM_OF[keyName]; const [posts, setPosts] = useState(c.posts?.[keyName] ?? []); const [dirty, setDirty] = useState(false); const [schedule, setSchedule] = useState(null); useEffect(() => { setPosts(c.posts?.[keyName] ?? []); setDirty(false); }, [kit.id, keyName, c.posts]); const edit = (i: number, v: string) => { setPosts(posts.map((p, j) => (j === i ? v : p))); setDirty(true); }; return (

{meta.thread ? `${posts.length} posts in the thread.` : keyName === "substack_notes" ? "Each note stands alone. Schedule them on different days." : "The full post, written from the article. Edit it here, then schedule it."}

{dirty && ( )}
{posts.map((p, i) => (
{meta.thread ? `${i + 1} / ${posts.length}` : keyName === "substack_notes" ? `Note ${i + 1}` : ""} meta.limit ? "over" : "muted"}`}> {p.length} / {meta.limit}