From a11caafd22bd936c2a282485787f08846fcb4c50 Mon Sep 17 00:00:00 2001 From: Mark Henderson Date: Tue, 17 Mar 2026 17:23:38 -0700 Subject: [PATCH] feat: add 'Generate architecture' CTA banner on PRD page when arch not yet generated Made-with: Cursor --- .../project/[projectId]/prd/page.tsx | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/app/[workspace]/project/[projectId]/prd/page.tsx b/app/[workspace]/project/[projectId]/prd/page.tsx index 216eba1..b33a94b 100644 --- a/app/[workspace]/project/[projectId]/prd/page.tsx +++ b/app/[workspace]/project/[projectId]/prd/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useEffect, useState } from "react"; -import { useParams } from "next/navigation"; +import { useParams, useRouter } from "next/navigation"; // Maps each PRD section to the discovery phase that populates it const PRD_SECTIONS = [ @@ -184,11 +184,14 @@ function ArchitectureView({ arch }: { arch: Architecture }) { export default function PRDPage() { const params = useParams(); const projectId = params.projectId as string; + const workspace = params.workspace as string; const [prd, setPrd] = useState(null); const [architecture, setArchitecture] = useState(null); const [savedPhases, setSavedPhases] = useState([]); const [loading, setLoading] = useState(true); const [activeTab, setActiveTab] = useState<"prd" | "architecture">("prd"); + const [archGenerating, setArchGenerating] = useState(false); + const [archError, setArchError] = useState(null); useEffect(() => { Promise.all([ @@ -202,6 +205,24 @@ export default function PRDPage() { }); }, [projectId]); + const router = useRouter(); + + const handleGenerateArchitecture = async () => { + setArchGenerating(true); + setArchError(null); + try { + const res = await fetch(`/api/projects/${projectId}/architecture`, { method: "POST" }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error ?? "Generation failed"); + setArchitecture(data.architecture); + setActiveTab("architecture"); + } catch (e) { + setArchError(e instanceof Error ? e.message : "Something went wrong"); + } finally { + setArchGenerating(false); + } + }; + const phaseMap = new Map(savedPhases.map(p => [p.phase, p])); const savedPhaseIds = new Set(savedPhases.map(p => p.phase)); @@ -257,6 +278,51 @@ export default function PRDPage() { )} + {/* Next step banner — PRD done but no architecture yet */} + {prd && !architecture && activeTab === "prd" && ( +
+
+
+ Next: Generate technical architecture +
+
+ The AI will read your PRD and recommend the apps, services, and infrastructure your product needs. Takes ~30 seconds. +
+ {archError && ( +
⚠ {archError}
+ )} +
+ +
+ )} + {/* Architecture tab */} {activeTab === "architecture" && architecture && (