Rip out Theia, ship P5.1 attach E2E + Justine UI work-in-progress
Theia rip-out: - Delete app/api/theia-auth/route.ts (Traefik ForwardAuth shim) - Delete app/api/projects/[projectId]/workspace/route.ts and app/api/projects/prewarm/route.ts (Cloud Run Theia provisioning) - Delete lib/cloud-run-workspace.ts and lib/coolify-workspace.ts - Strip provisionTheiaWorkspace + theiaWorkspaceUrl/theiaAppUuid/ theiaError from app/api/projects/create/route.ts response - Remove Theia callbackUrl branch in app/auth/page.tsx - Drop "Open in Theia" button + xterm/Theia PTY copy in build/page.tsx - Drop theiaWorkspaceUrl from deployment/page.tsx Project type - Strip Theia IDE line + theia-code-os from advisor + agent-chat context strings - Scrub Theia mention from lib/auth/workspace-auth.ts comment P5.1 (custom apex domains + DNS): - lib/coolify.ts + lib/opensrs.ts: nameserver normalization, OpenSRS XML auth, Cloud DNS plumbing - scripts/smoke-attach-e2e.ts: full prod GCP + sandbox OpenSRS + prod Coolify smoke covering register/zone/A/NS/PATCH/cleanup In-progress (Justine onboarding/build, MVP setup, agent telemetry): - New (justine)/stories, project (home) layouts, mvp-setup, run, tasks routes + supporting components - Project shell + sidebar + nav refactor for the Stackless palette - Agent session API hardening (sessions, events, stream, approve, retry, stop) + atlas-chat, advisor, design-surfaces refresh - New scripts/sync-db-url-from-coolify.mjs + scripts/prisma-db-push.mjs + docker-compose.local-db.yml for local Prisma workflows - lib/dev-bypass.ts, lib/chat-context-refs.ts, lib/prd-sections.ts - Misc: stories CSS, debug/prisma route, modal-theme, BuildLivePlanPanel Made-with: Cursor
This commit is contained in:
174
components/project-main/MvpSetupLayoutClient.tsx
Normal file
174
components/project-main/MvpSetupLayoutClient.tsx
Normal file
@@ -0,0 +1,174 @@
|
||||
"use client";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { JM } from "@/components/project-creation/modal-theme";
|
||||
|
||||
const BUILD_LEFT_BG = "#faf8f5";
|
||||
const BUILD_LEFT_BORDER = "#e8e4dc";
|
||||
|
||||
export function MvpSetupLayoutClient({
|
||||
workspace,
|
||||
projectId,
|
||||
children,
|
||||
}: {
|
||||
workspace: string;
|
||||
projectId: string;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const pathname = usePathname() ?? "";
|
||||
const base = `/${workspace}/project/${projectId}/mvp-setup`;
|
||||
|
||||
const steps = [
|
||||
{ href: `${base}/describe`, label: "Describe", sub: "Your idea", suffix: "/describe" },
|
||||
{ href: `${base}/architect`, label: "Architect", sub: "Discovery", suffix: "/architect" },
|
||||
{ href: `${base}/design`, label: "Design", sub: "Look & feel", suffix: "/design" },
|
||||
{ href: `${base}/website`, label: "Website", sub: "Grow", suffix: "/website" },
|
||||
{ href: `${base}/launch`, label: "Build MVP", sub: "Review & launch", suffix: "/launch" },
|
||||
] as const;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
height: "100%",
|
||||
overflow: "hidden",
|
||||
fontFamily: JM.fontSans,
|
||||
background: "linear-gradient(180deg, #FAFAFA 0%, #F5F3FF 100%)",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 200,
|
||||
flexShrink: 0,
|
||||
borderRight: `1px solid ${BUILD_LEFT_BORDER}`,
|
||||
background: "#fff",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
padding: "18px 12px",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<div style={{ padding: "0 6px", marginBottom: 20 }}>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
|
||||
<div
|
||||
style={{
|
||||
width: 26,
|
||||
height: 26,
|
||||
background: JM.primaryGradient,
|
||||
borderRadius: 6,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: 13, fontWeight: 700, color: "#fff" }}>V</span>
|
||||
</div>
|
||||
<span style={{ fontSize: 16, fontWeight: 700, color: JM.ink, letterSpacing: "-0.02em" }}>MVP setup</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 11, color: JM.muted, paddingLeft: 34 }}>New product flow</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
fontSize: 9.5,
|
||||
fontWeight: 700,
|
||||
letterSpacing: "0.08em",
|
||||
textTransform: "uppercase",
|
||||
color: JM.muted,
|
||||
padding: "0 6px",
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
Steps
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: 2, flex: 1, minHeight: 0, overflowY: "auto" }}>
|
||||
{steps.map(step => {
|
||||
const active = pathname.includes(`${base}${step.suffix}`);
|
||||
return (
|
||||
<Link
|
||||
key={step.suffix}
|
||||
href={step.href}
|
||||
scroll={false}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 9,
|
||||
padding: "9px 10px",
|
||||
borderRadius: 8,
|
||||
textDecoration: "none",
|
||||
background: active ? "#fafaff" : "transparent",
|
||||
border: active ? `1px solid rgba(99,102,241,0.2)` : "1px solid transparent",
|
||||
transition: "background 0.15s",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: "50%",
|
||||
background: active ? JM.primaryGradient : "#e5e7eb",
|
||||
color: active ? "#fff" : JM.muted,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
flexShrink: 0,
|
||||
fontSize: 9,
|
||||
fontWeight: 700,
|
||||
}}
|
||||
>
|
||||
{active ? "▲" : "○"}
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 12.5, fontWeight: active ? 600 : 500, color: JM.ink }}>{step.label}</div>
|
||||
<div style={{ fontSize: 10, color: JM.muted }}>{step.sub}</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div style={{ borderTop: `1px solid ${BUILD_LEFT_BORDER}`, marginTop: 14, paddingTop: 12, flexShrink: 0 }}>
|
||||
<Link
|
||||
href={`/${workspace}/projects`}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
background: "#eef2ff",
|
||||
border: "1px solid #e0e7ff",
|
||||
borderRadius: 8,
|
||||
padding: "9px 10px",
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
color: JM.indigo,
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
Save & go to dashboard
|
||||
</Link>
|
||||
<Link
|
||||
href={`/${workspace}/project/${projectId}/build`}
|
||||
style={{
|
||||
display: "block",
|
||||
marginTop: 10,
|
||||
textAlign: "center",
|
||||
fontSize: 11,
|
||||
fontWeight: 600,
|
||||
color: JM.muted,
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
Open Build workspace →
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: 1, minWidth: 0, minHeight: 0, overflow: "hidden", display: "flex", flexDirection: "column" }}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user