import * as React from "react";
import { SetupChecklist } from "@/components/ui/setup-checklist";
/* Shipyard, a made-up deployment tool for developers. The checklist lands
two steps in (the account exists, the CLI is installed), the Friday deploy
fails once on purpose so the error state shows, and the last step opens the
first real task. */
const settings = {
accent: "#7f72e3",
title: "Set up Shipyard",
subtitle: "Five steps to your first deploy. Two are already behind you.",
step1Title: "Create your account",
step1Description: "Done when you signed up. That was the easy part.",
step1Cta: "Open account",
step2Title: "Install the CLI",
step2Description: "One command, and you can ship from the terminal like it's 2009.",
step2Cta: "Copy the command",
step3Title: "Connect your repo",
step3Description: "Shipyard watches your main branch and builds every push.",
step3Cta: "Connect GitHub",
step4Title: "Invite a teammate",
step4Description: "Someone has to review your PR. It can't be you, we checked.",
step4Cta: "Send an invite",
step5Title: "Deploy on a Friday",
step5Description: "Optional, brave. We keep a rollback button warm, just in case.",
step5Cta: "Deploy to production",
nextTaskTitle: "Ship your first preview",
nextTaskDescription: "Push a branch and Shipyard gives it its own URL to share.",
nextTaskCta: "Open my project",
};
/* a little tugboat: the Shipyard mark */
function Tug() {
return (
<svg width="40" height="40" viewBox="0 0 40 40" aria-hidden className="block">
<rect width="40" height="40" rx="11" className="fill-muted" />
<path d="M8 24h24l-3.2 6.2a2 2 0 0 1-1.8 1.1H13a2 2 0 0 1-1.8-1.1Z" fill="currentColor" />
<rect x="13" y="15" width="12" height="9" rx="2" className="fill-foreground" />
<rect x="20" y="9" width="3.5" height="6" rx="1" fill="currentColor" />
<circle cx="17" cy="19.5" r="1.3" className="fill-background" />
<circle cx="21.5" cy="19.5" r="1.3" className="fill-background" />
<path d="M17.2 22q2.1 1.2 4.2 0" fill="none" strokeWidth="1" strokeLinecap="round" className="stroke-background" />
</svg>
);
}
const wait = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
export default function Demo(props: Partial<typeof settings>) {
const s = { ...settings, ...props };
const fridayTries = React.useRef(0);
const steps = [
{ title: s.step1Title, description: s.step1Description, cta: s.step1Cta, done: true },
{ title: s.step2Title, description: s.step2Description, cta: s.step2Cta, done: true },
{ title: s.step3Title, description: s.step3Description, cta: s.step3Cta, pendingLabel: "Connecting", onAction: () => wait(900) },
{ title: s.step4Title, description: s.step4Description, cta: s.step4Cta, pendingLabel: "Sending", onAction: () => wait(700) },
{
title: s.step5Title,
description: s.step5Description,
cta: s.step5Cta,
optional: true,
requires: 2,
pendingLabel: "Deploying",
onAction: async () => {
await wait(1100);
fridayTries.current += 1;
if (fridayTries.current === 1) throw new Error("Build failed. It's Friday, of course it did. Try again.");
},
},
];
return (
<div className="flex w-full items-center justify-center p-4 sm:p-6">
<SetupChecklist
className="max-w-4xl"
accent={s.accent}
title={s.title}
subtitle={s.subtitle}
logo={<Tug />}
steps={steps}
resettable
onComplete={() => {
fridayTries.current = 0;
}}
nextTask={{ title: s.nextTaskTitle, description: s.nextTaskDescription, cta: s.nextTaskCta }}
/>
</div>
);
}