"use client"; import { cn } from "@/lib/utils"; import { Check, ClipboardCopy } from "lucide-react"; import { AnimatePresence, motion } from "motion/react"; import { useEffect, useState } from "react"; import PackageIcon from "./Icons"; const CodeContainer = () => { const [selectedPM, setSelectedPM] = useState<"npm" | "pnpm" | "bun">("bun"); const [copied, setCopied] = useState(false); const [, setShowCursor] = useState(true); const [step, setStep] = useState(0); useEffect(() => { const interval = setInterval(() => setShowCursor((p) => !p), 500); return () => clearInterval(interval); }, []); // biome-ignore lint/correctness/useExhaustiveDependencies: useEffect(() => { setStep(0); const initialTimer = setTimeout(() => setStep(1), 1000); return () => clearTimeout(initialTimer); }, [selectedPM]); useEffect(() => { if (step > 0 && step < 5) { const timer = setTimeout(() => setStep((s) => s + 1), 400); return () => clearTimeout(timer); } }, [step]); const commands = { npm: "npx create-better-t-stack@latest", pnpm: "pnpm create better-t-stack@latest", bun: "bun create better-t-stack@latest", }; const runCommands = { npm: "npm run dev", pnpm: "pnpm dev", bun: "bun dev", }; const copyToClipboard = async () => { if (copied) return; await navigator.clipboard.writeText(commands[selectedPM]); setCopied(true); setTimeout(() => setCopied(false), 2000); }; const packageManagers: Array<"npm" | "pnpm" | "bun"> = ["bun", "pnpm", "npm"]; return (
Choose your package manager:
{packageManagers.map((pm) => ( ))}
$ {commands[selectedPM]} {step === 0 && (
{copied ? ( ) : ( )}
{step > 0 && (
{step >= 1 && ( Creating a new Better-T-Stack project... )} {step >= 2 && (
Project: my-app
Frontend: React Web
Backend: Hono
Database: SQLite + Drizzle
)} {step >= 3 && ( Creating project structure )} {step >= 4 && ( Installing dependencies )} {step >= 5 && ( {" "} Project created successfully! Run:
cd my-app && {runCommands[selectedPM]}
)} {step >= 5 && ( $ )}
)}
); }; export default CodeContainer;