import { useState } from "react"; import { Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Progress } from "@/components/ui/progress"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { useContentJob } from "@/hooks/useContentJob"; import { getContentJobAsset } from "@/api/contentJobs"; import { SocialPostResult } from "./SocialPostResult"; export const PLATFORM_CHAR_LIMITS: Record = { "twitter-x": 280, "linkedin": 3000, "instagram-caption": 2200, "instagram-carousel": 300, }; const PLATFORM_OPTIONS = [ { value: "twitter-x", label: "Twitter/X" }, { value: "linkedin", label: "LinkedIn" }, { value: "instagram-caption", label: "Instagram Caption" }, { value: "instagram-carousel", label: "Instagram Carousel" }, ]; export type SocialPostBundle = { type: "social-post-bundle"; platform: string; post: string; hashtags: string[]; slides?: string[]; charLimit: number; }; interface SocialPostPanelProps { companyId: string; } export function SocialPostPanel({ companyId }: SocialPostPanelProps) { const [prompt, setPrompt] = useState(""); const [platform, setPlatform] = useState("twitter-x"); const [charCount, setCharCount] = useState(0); const [bundle, setBundle] = useState(null); const job = useContentJob(companyId); const charLimit = PLATFORM_CHAR_LIMITS[platform] ?? 280; const isOverLimit = charCount > charLimit; const isGenerating = job.status === "queued" || job.status === "running"; const isIdle = job.status === "idle"; async function handleSubmit() { if (!prompt.trim() || isGenerating) return; setBundle(null); await job.submit("social-post", { prompt, platform }); } function handlePromptChange(e: React.ChangeEvent) { setPrompt(e.target.value); setCharCount(e.target.value.length); } // Fetch asset when job completes if (job.status === "done" && job.resultAssetId && !bundle) { void getContentJobAsset(companyId, job.resultAssetId).then(async (assetUrl) => { const res = await fetch(assetUrl); const text = await res.text(); try { const parsed = JSON.parse(text) as SocialPostBundle; setBundle(parsed); } catch { // ignore parse error — will show empty state } }); } return ( Generate Post