{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "onboarding-02",
  "type": "registry:block",
  "title": "Onboarding Workspace Setup",
  "description": "A onboarding workspace setup block.",
  "author": "ephraim duncan <https://ephraimduncan.com>",
  "registryDependencies": [
    "button"
  ],
  "dependencies": [
    "@tabler/icons-react"
  ],
  "files": [
    {
      "path": "content/components/onboarding/onboarding-02.tsx",
      "type": "registry:component",
      "target": "components/onboarding-02.tsx",
      "content": "'use client';\n\nimport type { Icon } from '@tabler/icons-react';\nimport {\n  IconCircleCheckFilled,\n  IconFolder,\n  IconPlug,\n  IconRocket,\n  IconUsers,\n} from '@tabler/icons-react';\nimport { useState } from 'react';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\ninterface StepData {\n  title: string;\n  description: string;\n  icon: Icon;\n  actionLabel: string;\n}\n\nconst steps: StepData[] = [\n  {\n    title: 'Create your workspace',\n    description:\n      'Name your workspace and pick a URL. This is where your team will collaborate on everything.',\n    icon: IconRocket,\n    actionLabel: 'Get started',\n  },\n  {\n    title: 'Invite your team',\n    description:\n      'Add teammates by email so everyone can collaborate in real time across projects.',\n    icon: IconUsers,\n    actionLabel: 'Send invites',\n  },\n  {\n    title: 'Set up your first project',\n    description:\n      'Create a project to organize tasks, docs, and milestones all in one place.',\n    icon: IconFolder,\n    actionLabel: 'Create project',\n  },\n  {\n    title: 'Connect your tools',\n    description:\n      'Link Slack, GitHub, or Figma to keep your workflow in sync automatically.',\n    icon: IconPlug,\n    actionLabel: 'Browse integrations',\n  },\n];\n\nfunction getIconColor(isCompleted: boolean, isActive: boolean) {\n  if (isCompleted) {\n    return 'text-muted-foreground/30';\n  }\n  if (isActive) {\n    return 'text-primary';\n  }\n  return 'text-muted-foreground/40';\n}\n\nfunction getTitleClass(isCompleted: boolean, isActive: boolean) {\n  if (isCompleted) {\n    return 'text-muted-foreground/50 line-through';\n  }\n  if (isActive) {\n    return 'text-foreground';\n  }\n  return 'text-muted-foreground';\n}\n\nfunction StepIndicator({\n  index,\n  isCompleted,\n  isActive,\n}: {\n  index: number;\n  isCompleted: boolean;\n  isActive: boolean;\n}) {\n  if (isCompleted) {\n    return (\n      <div className=\"flex size-7 items-center justify-center\">\n        <IconCircleCheckFilled\n          aria-hidden=\"true\"\n          className=\"size-7 text-emerald-500\"\n        />\n      </div>\n    );\n  }\n  return (\n    <div\n      className={cn(\n        'flex size-7 items-center justify-center rounded-full font-semibold text-xs',\n        isActive\n          ? 'bg-primary text-primary-foreground'\n          : 'bg-muted text-muted-foreground'\n      )}\n    >\n      {index + 1}\n    </div>\n  );\n}\n\nfunction StepCard({\n  step,\n  index,\n  isCompleted,\n  isActive,\n  onComplete,\n}: {\n  step: StepData;\n  index: number;\n  isCompleted: boolean;\n  isActive: boolean;\n  onComplete: () => void;\n}) {\n  const StepIcon = step.icon;\n\n  return (\n    <div\n      className={cn(\n        'rounded-lg border p-4 transition-colors',\n        isActive && 'border-primary/30 bg-muted/50',\n        !isActive && 'border-border bg-background'\n      )}\n    >\n      <div className=\"flex gap-3\">\n        <div className=\"mt-0.5 shrink-0\">\n          <StepIndicator\n            index={index}\n            isActive={isActive}\n            isCompleted={isCompleted}\n          />\n        </div>\n        <div className=\"min-w-0 flex-1\">\n          <div className=\"flex items-start gap-3\">\n            <div className=\"min-w-0 flex-1\">\n              <p\n                className={cn(\n                  'font-medium leading-6',\n                  getTitleClass(isCompleted, isActive)\n                )}\n              >\n                {step.title}\n              </p>\n              <p\n                className={cn(\n                  'mt-0.5 text-sm leading-5',\n                  isActive\n                    ? 'text-muted-foreground'\n                    : 'text-muted-foreground/60'\n                )}\n              >\n                {step.description}\n              </p>\n              {isActive && (\n                <Button className=\"mt-3\" onClick={onComplete} size=\"sm\">\n                  <StepIcon\n                    aria-hidden=\"true\"\n                    className=\"-ml-0.5 size-4 shrink-0\"\n                  />\n                  {step.actionLabel}\n                </Button>\n              )}\n            </div>\n            <StepIcon\n              aria-hidden=\"true\"\n              className={cn(\n                'mt-0.5 size-5 shrink-0',\n                getIconColor(isCompleted, isActive)\n              )}\n            />\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport function Onboarding02() {\n  const [completedSteps, setCompletedSteps] = useState<Set<number>>(\n    () => new Set([0])\n  );\n\n  const currentStep = steps.findIndex((_, i) => !completedSteps.has(i));\n  const completedCount = completedSteps.size;\n  const allDone = completedCount === steps.length;\n\n  const handleComplete = (index: number) => {\n    setCompletedSteps((prev) => {\n      const next = new Set(prev);\n      next.add(index);\n      return next;\n    });\n  };\n\n  return (\n    <div className=\"flex min-h-dvh items-center justify-center bg-background p-4\">\n      <div className=\"w-full max-w-xl\">\n        <div className=\"mb-6\">\n          <h3 className=\"font-semibold text-foreground text-lg\">\n            Set up your workspace\n          </h3>\n          <p className=\"mt-1 text-muted-foreground text-sm\">\n            Complete these steps to get your team up and running\n          </p>\n          <div className=\"mt-4\">\n            <div className=\"flex items-center justify-between text-sm\">\n              <span className=\"text-muted-foreground\">\n                {allDone ? (\n                  <span className=\"font-medium text-emerald-600\">\n                    All done 🎉\n                  </span>\n                ) : (\n                  <>\n                    <span className=\"font-medium text-foreground\">\n                      {completedCount}\n                    </span>{' '}\n                    of {steps.length} completed\n                  </>\n                )}\n              </span>\n            </div>\n            <div className=\"mt-2 h-1.5 w-full overflow-hidden rounded-full bg-muted\">\n              <div\n                className=\"h-full rounded-full bg-emerald-500 transition-all duration-500\"\n                style={{\n                  width: `${(completedCount / steps.length) * 100}%`,\n                }}\n              />\n            </div>\n          </div>\n        </div>\n\n        <div className=\"space-y-3\">\n          {steps.map((step, index) => (\n            <StepCard\n              index={index}\n              isActive={index === currentStep}\n              isCompleted={completedSteps.has(index)}\n              key={step.title}\n              onComplete={() => handleComplete(index)}\n              step={step}\n            />\n          ))}\n        </div>\n      </div>\n    </div>\n  );\n}\n"
    }
  ],
  "categories": [
    "onboarding"
  ]
}