"use client";
import { useEffect, useState } from "react";
import { useRouter, useParams } from "next/navigation";
interface AnalysisResult {
decisions: string[];
ideas: string[];
openQuestions: string[];
architecture: string[];
targetUsers: string[];
}
interface ChatImportMainProps {
projectId: string;
projectName: string;
sourceData?: { chatText?: string };
analysisResult?: AnalysisResult;
}
type Stage = "intake" | "extracting" | "review";
function EditableList({
label,
items,
accent,
onChange,
}: {
label: string;
items: string[];
accent: string;
onChange: (items: string[]) => void;
}) {
const handleEdit = (i: number, value: string) => {
const next = [...items];
next[i] = value;
onChange(next);
};
const handleDelete = (i: number) => {
onChange(items.filter((_, idx) => idx !== i));
};
const handleAdd = () => {
onChange([...items, ""]);
};
return (
{label}
{items.length === 0 && (
Nothing captured.
)}
{items.map((item, i) => (
handleEdit(i, e.target.value)}
style={{
flex: 1, padding: "7px 10px", borderRadius: 6,
border: "1px solid #e0dcd4", background: "#faf8f5",
fontSize: "0.81rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif",
color: "#1a1a1a", outline: "none",
}}
onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")}
onBlur={e => (e.currentTarget.style.borderColor = "#e0dcd4")}
/>
))}
);
}
export function ChatImportMain({
projectId,
projectName,
sourceData,
analysisResult: initialResult,
}: ChatImportMainProps) {
const router = useRouter();
const params = useParams();
const workspace = params?.workspace as string;
const hasChatText = !!sourceData?.chatText;
const [stage, setStage] = useState(
initialResult ? "review" : hasChatText ? "extracting" : "intake"
);
const [chatText, setChatText] = useState(sourceData?.chatText ?? "");
const [error, setError] = useState(null);
const [result, setResult] = useState(
initialResult ?? { decisions: [], ideas: [], openQuestions: [], architecture: [], targetUsers: [] }
);
// Kick off extraction automatically if chatText is ready
useEffect(() => {
if (stage === "extracting") {
runExtraction();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [stage]);
const runExtraction = async () => {
setError(null);
try {
const res = await fetch(`/api/projects/${projectId}/analyze-chats`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ chatText }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error || "Extraction failed");
setResult(data.analysisResult);
setStage("review");
} catch (e) {
setError(e instanceof Error ? e.message : "Something went wrong");
setStage("intake");
}
};
const handlePRD = () => router.push(`/${workspace}/project/${projectId}/prd`);
const handleMVP = () => router.push(`/${workspace}/project/${projectId}/build`);
// ── Stage: intake ─────────────────────────────────────────────────────────
if (stage === "intake") {
return (
Paste your chat history
{projectName} — Atlas will extract decisions, ideas, architecture notes, and more.
{error && (
{error}
)}
);
}
// ── Stage: extracting ─────────────────────────────────────────────────────
if (stage === "extracting") {
return (
Analysing your chats…
Atlas is extracting decisions, ideas, and insights
);
}
// ── Stage: review ─────────────────────────────────────────────────────────
return (
What Atlas found
Review and edit the extracted insights for {projectName}. These will seed your PRD or MVP plan.
{/* Left column */}
setResult(r => ({ ...r, decisions: items }))}
/>
setResult(r => ({ ...r, ideas: items }))}
/>
{/* Right column */}
setResult(r => ({ ...r, openQuestions: items }))}
/>
setResult(r => ({ ...r, architecture: items }))}
/>
setResult(r => ({ ...r, targetUsers: items }))}
/>
{/* Decision buttons */}
Ready to move forward?
Choose how you want to proceed with {projectName}.
);
}