{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "blocks",
  "homepage": "https://blocks.so",
  "items": [
    {
      "name": "ai-01",
      "type": "registry:block",
      "title": "AI Chat with Voice Input",
      "description": "A ai chat with voice input block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dropdown-menu",
        "textarea"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/ai/ai-01.tsx",
          "type": "registry:component",
          "target": "components/ai-01.tsx",
          "content": "\"use client\";\n\nimport type React from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  IconMicrophone,\n  IconPaperclip,\n  IconPlus,\n  IconSearch,\n  IconSend,\n  IconSparkles,\n  IconWaveSine,\n} from \"@tabler/icons-react\";\nimport { useRef, useState } from \"react\";\n\nexport default function Ai01() {\n  const [message, setMessage] = useState(\"\");\n  const [isExpanded, setIsExpanded] = useState(false);\n  const textareaRef = useRef<HTMLTextAreaElement>(null);\n  const fileInputRef = useRef<HTMLInputElement>(null);\n\n  const handleSubmit = (e: React.FormEvent) => {\n    e.preventDefault();\n\n    if (message.trim()) {\n      setMessage(\"\");\n      setIsExpanded(false);\n\n      if (textareaRef.current) {\n        textareaRef.current.style.height = \"auto\";\n      }\n    }\n  };\n\n  const handleTextareaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n    setMessage(e.target.value);\n\n    if (textareaRef.current) {\n      textareaRef.current.style.height = \"auto\";\n      textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;\n    }\n\n    setIsExpanded(e.target.value.length > 100 || e.target.value.includes(\"\\n\"));\n  };\n\n  const handleKeyDown = (e: React.KeyboardEvent) => {\n    if (e.key === \"Enter\" && !e.shiftKey) {\n      e.preventDefault();\n      handleSubmit(e as any);\n    }\n  };\n\n  return (\n    <div className=\"w-full\">\n      <h1 className=\"text-balance mb-8 mx-auto max-w-2xl text-center text-2xl font-semibold leading-9 text-foreground px-1 text-pretty whitespace-pre-wrap\">\n        How can I help you today?\n      </h1>\n\n      <form onSubmit={handleSubmit} className=\"group/composer w-full\">\n        <input\n          ref={fileInputRef}\n          type=\"file\"\n          multiple\n          className=\"sr-only\"\n          onChange={(e) => {}}\n        />\n\n        <div\n          className={cn(\n            \"w-full max-w-2xl mx-auto bg-transparent dark:bg-muted/50 cursor-text overflow-clip bg-clip-padding p-2.5 shadow-lg border border-border transition-[border-radius] duration-200 ease-out\",\n            isExpanded\n              ? \"rounded-3xl grid [grid-template-columns:1fr] [grid-template-rows:auto_1fr_auto] [grid-template-areas:'header'_'primary'_'footer']\"\n              : \"rounded-3xl grid [grid-template-columns:auto_1fr_auto] [grid-template-rows:auto_1fr_auto] [grid-template-areas:'header_header_header'_'leading_primary_trailing'_'._footer_.']\"\n          )}\n        >\n          <div\n            className={cn(\n              \"flex min-h-14 items-center overflow-x-hidden px-1.5\",\n              {\n                \"px-2 py-1 mb-0\": isExpanded,\n                \"-my-2.5\": !isExpanded,\n              }\n            )}\n            style={{ gridArea: \"primary\" }}\n          >\n            <div className=\"flex-1 overflow-auto max-h-52\">\n              <Textarea\n                ref={textareaRef}\n                value={message}\n                onChange={handleTextareaChange}\n                onKeyDown={handleKeyDown}\n                placeholder=\"Ask anything\"\n                className=\"min-h-0 resize-none rounded-none border-0 p-0 text-base placeholder:text-muted-foreground focus-visible:ring-0 focus-visible:ring-offset-0 scrollbar-thin dark:bg-transparent\"\n                rows={1}\n              />\n            </div>\n          </div>\n\n          <div\n            className={cn(\"flex\", { hidden: isExpanded })}\n            style={{ gridArea: \"leading\" }}\n          >\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button\n                  type=\"button\"\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  className=\"rounded-full hover:bg-accent outline-none ring-0\"\n                  aria-label=\"Add attachments\"\n                >\n                  <IconPlus className=\"size-6 text-muted-foreground\" />\n                </Button>\n              </DropdownMenuTrigger>\n\n              <DropdownMenuContent\n                align=\"start\"\n                className=\"max-w-xs rounded-2xl p-1.5\"\n              >\n                <DropdownMenuGroup className=\"space-y-1\">\n                  <DropdownMenuItem\n                    className=\"rounded-md\"\n                    onClick={() => fileInputRef.current?.click()}\n                  >\n                    <IconPaperclip size={20} className=\"opacity-60\" />\n                    Add photos & files\n                  </DropdownMenuItem>\n                  <DropdownMenuItem\n                    className=\"rounded-md\"\n                    onClick={() => {}}\n                  >\n                    <div className=\"flex items-center gap-2\">\n                      <IconSparkles size={20} className=\"opacity-60\" />\n                      Agent mode\n                    </div>\n                  </DropdownMenuItem>\n                  <DropdownMenuItem\n                    className=\"rounded-md\"\n                    onClick={() => {}}\n                  >\n                    <IconSearch size={20} className=\"opacity-60\" />\n                    Deep Research\n                  </DropdownMenuItem>\n                </DropdownMenuGroup>\n              </DropdownMenuContent>\n            </DropdownMenu>\n          </div>\n\n          <div\n            className=\"flex items-center gap-2\"\n            style={{ gridArea: isExpanded ? \"footer\" : \"trailing\" }}\n          >\n            <div className=\"ms-auto flex items-center gap-1.5\">\n              <Button\n                type=\"button\"\n                variant=\"ghost\"\n                size=\"icon\"\n                className=\"rounded-full hover:bg-accent\"\n                aria-label=\"Record audio message\"\n              >\n                <IconMicrophone className=\"size-5 text-muted-foreground\" />\n              </Button>\n\n              <Button\n                type=\"button\"\n                variant=\"ghost\"\n                size=\"icon\"\n                className=\"h-9 w-9 rounded-full hover:bg-accent relative\"\n                aria-label=\"Audio visualization\"\n              >\n                <IconWaveSine className=\"size-5 text-muted-foreground\" />\n              </Button>\n\n              {message.trim() && (\n                <Button\n                  type=\"submit\"\n                  size=\"icon\"\n                  className=\"rounded-full\"\n                  aria-label=\"Send message\"\n                >\n                  <IconSend className=\"size-5\" />\n                </Button>\n              )}\n            </div>\n          </div>\n        </div>\n      </form>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "ai"
      ]
    },
    {
      "name": "ai-02",
      "type": "registry:block",
      "title": "AI Chat with Model Selection",
      "description": "A ai chat with model selection block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "select",
        "textarea"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/ai/ai-02.tsx",
          "type": "registry:component",
          "target": "components/ai-02.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  IconAlertTriangle,\n  IconArrowUp,\n  IconCloud,\n  IconFileSpark,\n  IconGauge,\n  IconPhotoScan,\n} from \"@tabler/icons-react\";\nimport { useRef, useState } from \"react\";\n\nconst PROMPTS = [\n  {\n    icon: IconFileSpark,\n    text: \"Write documentation\",\n    prompt:\n      \"Write comprehensive documentation for this codebase, including setup instructions, API references, and usage examples.\",\n  },\n  {\n    icon: IconGauge,\n    text: \"Optimize performance\",\n    prompt:\n      \"Analyze the codebase for performance bottlenecks and suggest optimizations to improve loading times and runtime efficiency.\",\n  },\n  {\n    icon: IconAlertTriangle,\n    text: \"Find and fix 3 bugs\",\n    prompt:\n      \"Scan through the codebase to identify and fix 3 critical bugs, providing detailed explanations for each fix.\",\n  },\n];\n\nconst MODELS = [\n  {\n    value: \"gpt-5\",\n    name: \"GPT-5\",\n    description: \"Most advanced model\",\n    max: true,\n  },\n  {\n    value: \"gpt-4o\",\n    name: \"GPT-4o\",\n    description: \"Fast and capable\",\n  },\n  {\n    value: \"gpt-4\",\n    name: \"GPT-4\",\n    description: \"Reliable and accurate\",\n  },\n  {\n    value: \"claude-3.5\",\n    name: \"Claude 3.5 Sonnet\",\n    description: \"Great for coding tasks\",\n  },\n];\n\nexport default function Ai02() {\n  const [inputValue, setInputValue] = useState(\"\");\n  const [selectedModel, setSelectedModel] = useState(MODELS[0]);\n  const inputRef = useRef<HTMLTextAreaElement>(null);\n\n  const handlePromptClick = (prompt: string) => {\n    if (inputRef.current) {\n      inputRef.current.value = prompt;\n      setInputValue(prompt);\n      inputRef.current.focus();\n    }\n  };\n\n  const handleModelChange = (value: string) => {\n    const model = MODELS.find((m) => m.value === value);\n    if (model) {\n      setSelectedModel(model);\n    }\n  };\n\n  const renderMaxBadge = () => (\n    <div className=\"flex h-[14px] items-center gap-1.5 rounded border border-border px-1 py-0\">\n      <span\n        className=\"text-[9px] font-bold uppercase\"\n        style={{\n          background:\n            \"linear-gradient(to right, rgb(129, 161, 193), rgb(125, 124, 155))\",\n          WebkitBackgroundClip: \"text\",\n          WebkitTextFillColor: \"transparent\",\n        }}\n      >\n        MAX\n      </span>\n    </div>\n  );\n\n  return (\n    <div className=\"flex flex-col gap-4 w-[calc(42rem-5rem)]\">\n      <div className=\"flex min-h-[120px] flex-col rounded-2xl cursor-text bg-card border border-border shadow-lg\">\n        <div className=\"flex-1 relative overflow-y-auto max-h-[258px]\">\n          <Textarea\n            ref={inputRef}\n            value={inputValue}\n            onChange={(e) => setInputValue(e.target.value)}\n            placeholder=\"Ask anything\"\n            className=\"w-full border-0 p-3 transition-[padding] duration-200 ease-in-out min-h-[48.4px] outline-none text-[16px] text-foreground resize-none shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 bg-transparent! whitespace-pre-wrap break-words\"\n          />\n        </div>\n\n        <div className=\"flex min-h-[40px] items-center gap-2 p-2 pb-1\">\n          <div className=\"flex aspect-1 items-center gap-1 rounded-full bg-muted p-1.5 text-xs\">\n            <IconCloud className=\"h-4 w-4 text-muted-foreground\" />\n          </div>\n\n          <div className=\"relative flex items-center\">\n            <Select\n              value={selectedModel.value}\n              onValueChange={handleModelChange}\n            >\n              <SelectTrigger className=\"w-fit border-none bg-transparent! p-0 text-sm text-muted-foreground hover:text-foreground focus:ring-0 shadow-none\">\n                <SelectValue>\n                  {selectedModel.max ? (\n                    <div className=\"flex items-center gap-1\">\n                      <span>{selectedModel.name}</span>\n                      {renderMaxBadge()}\n                    </div>\n                  ) : (\n                    <span>{selectedModel.name}</span>\n                  )}\n                </SelectValue>\n              </SelectTrigger>\n              <SelectContent>\n                {MODELS.map((model) => (\n                  <SelectItem key={model.value} value={model.value}>\n                    {model.max ? (\n                      <div className=\"flex items-center gap-1\">\n                        <span>{model.name}</span>\n                        {renderMaxBadge()}\n                      </div>\n                    ) : (\n                      <span>{model.name}</span>\n                    )}\n                    <span className=\"text-muted-foreground block text-xs\">\n                      {model.description}\n                    </span>\n                  </SelectItem>\n                ))}\n              </SelectContent>\n            </Select>\n          </div>\n\n          <div className=\"ml-auto flex items-center gap-3\">\n            <Button\n              variant=\"ghost\"\n              size=\"icon-sm\"\n              className=\"text-muted-foreground hover:text-foreground transition-colors duration-100 ease-out\"\n              title=\"Attach images\"\n              aria-label=\"Attach images\"\n            >\n              <IconPhotoScan className=\"h-5 w-5\" />\n            </Button>\n\n            <Button\n              variant=\"ghost\"\n              size=\"icon-sm\"\n              className={cn(\n                \"rounded-full transition-colors duration-100 ease-out cursor-pointer bg-primary\",\n                inputValue && \"bg-primary hover:bg-primary/90!\"\n              )}\n              disabled={!inputValue}\n              aria-label=\"Send message\"\n            >\n              <IconArrowUp className=\"h-4 w-4 text-primary-foreground\" />\n            </Button>\n          </div>\n        </div>\n      </div>\n\n      <div className=\"flex flex-wrap justify-center gap-2\">\n        {PROMPTS.map((button) => {\n          const IconComponent = button.icon;\n          return (\n            <Button\n              key={button.text}\n              variant=\"ghost\"\n              className=\"group flex items-center gap-2 rounded-full border px-3 py-2 text-sm text-foreground transition-colors duration-200 ease-out hover:bg-muted/30 h-auto bg-transparent dark:bg-muted\"\n              onClick={() => handlePromptClick(button.prompt)}\n            >\n              <IconComponent className=\"h-4 w-4 text-muted-foreground transition-colors group-hover:text-foreground\" />\n              <span>{button.text}</span>\n            </Button>\n          );\n        })}\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "ai"
      ]
    },
    {
      "name": "ai-03",
      "type": "registry:block",
      "title": "AI Chat Compact Interface",
      "description": "A ai chat compact interface block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dropdown-menu",
        "textarea"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/ai/ai-03.tsx",
          "type": "registry:component",
          "target": "components/ai-03.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  IconBolt,\n  IconChevronDown,\n  IconCircle,\n  IconCircleDashed,\n  IconCloud,\n  IconCode,\n  IconDeviceLaptop,\n  IconHistory,\n  IconPaperclip,\n  IconPlus,\n  IconProgress,\n  IconRobot,\n  IconSend,\n  IconUser,\n  IconWand,\n  IconWorld,\n} from \"@tabler/icons-react\";\nimport { useRef, useState } from \"react\";\n\nexport default function Ai03() {\n  const [input, setInput] = useState(\"\");\n  const [selectedModel, setSelectedModel] = useState(\"Local\");\n  const [selectedAgent, setSelectedAgent] = useState(\"Agent\");\n  const [selectedPerformance, setSelectedPerformance] = useState(\"High\");\n  const [autoMode, setAutoMode] = useState(false);\n  const fileInputRef = useRef<HTMLInputElement>(null);\n\n  const handleSubmit = (e: React.FormEvent) => {\n    e.preventDefault();\n    if (input.trim()) {\n    }\n  };\n\n  return (\n    <div className=\"w-xl\">\n      <div className=\"bg-background border border-border rounded-2xl overflow-hidden\">\n        <input\n          ref={fileInputRef}\n          type=\"file\"\n          multiple\n          className=\"sr-only\"\n          onChange={(e) => {}}\n        />\n\n        <div className=\"px-3 pt-3 pb-2 grow\">\n          <form onSubmit={handleSubmit}>\n            <Textarea\n              value={input}\n              onChange={(e) => setInput(e.target.value)}\n              placeholder=\"Ask anything\"\n              className=\"w-full bg-transparent! p-0 border-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 text-foreground placeholder-muted-foreground resize-none border-none outline-none text-sm min-h-10 max-h-[25vh]\"\n              rows={1}\n              onInput={(e) => {\n                const target = e.target as HTMLTextAreaElement;\n                target.style.height = \"auto\";\n                target.style.height = target.scrollHeight + \"px\";\n              }}\n            />\n          </form>\n        </div>\n\n        <div className=\"mb-2 px-2 flex items-center justify-between\">\n          <div className=\"flex items-center gap-1\">\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"h-7 w-7 p-0 rounded-full border border-border hover:bg-accent\"\n                >\n                  <IconPlus className=\"size-3\" />\n                </Button>\n              </DropdownMenuTrigger>\n\n              <DropdownMenuContent\n                align=\"start\"\n                className=\"max-w-xs rounded-2xl p-1.5\"\n              >\n                <DropdownMenuGroup className=\"space-y-1\">\n                  <DropdownMenuItem\n                    className=\"rounded-[calc(1rem-6px)] text-xs\"\n                    onClick={() => fileInputRef.current?.click()}\n                  >\n                    <IconPaperclip size={16} className=\"opacity-60\" />\n                    Attach Files\n                  </DropdownMenuItem>\n                  <DropdownMenuItem\n                    className=\"rounded-[calc(1rem-6px)] text-xs\"\n                    onClick={() => {}}\n                  >\n                    <IconCode size={16} className=\"opacity-60\" />\n                    Code Interpreter\n                  </DropdownMenuItem>\n                  <DropdownMenuItem\n                    className=\"rounded-[calc(1rem-6px)] text-xs\"\n                    onClick={() => {}}\n                  >\n                    <IconWorld size={16} className=\"opacity-60\" />\n                    Web Search\n                  </DropdownMenuItem>\n                  <DropdownMenuItem\n                    className=\"rounded-[calc(1rem-6px)] text-xs\"\n                    onClick={() => {}}\n                  >\n                    <IconHistory size={16} className=\"opacity-60\" />\n                    Chat History\n                  </DropdownMenuItem>\n                </DropdownMenuGroup>\n              </DropdownMenuContent>\n            </DropdownMenu>\n\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              onClick={() => setAutoMode(!autoMode)}\n              className={cn(\n                \"h-7 px-2 rounded-full border border-border hover:bg-accent \",\n                {\n                  \"bg-primary/10 text-primary border-primary/30\": autoMode,\n                  \"text-muted-foreground\": !autoMode,\n                }\n              )}\n            >\n              <IconWand className=\"size-3\" />\n              <span className=\"text-xs\">Auto</span>\n            </Button>\n          </div>\n\n          <div>\n            <Button\n              type=\"submit\"\n              disabled={!input.trim()}\n              className=\"size-7 p-0 rounded-full bg-primary disabled:opacity-50 disabled:cursor-not-allowed\"\n              onClick={handleSubmit}\n            >\n              <IconSend className=\"size-3 fill-primary\" />\n            </Button>\n          </div>\n        </div>\n      </div>\n\n      <div className=\"flex items-center gap-0 pt-2\">\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className=\"h-6 px-2 rounded-full border border-transparent hover:bg-accent text-muted-foreground text-xs\"\n            >\n              <IconDeviceLaptop className=\"size-3\" />\n              <span>{selectedModel}</span>\n              <IconChevronDown className=\"size-3\" />\n            </Button>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            align=\"start\"\n            className=\"max-w-xs rounded-2xl p-1.5 bg-popover border-border\"\n          >\n            <DropdownMenuGroup className=\"space-y-1\">\n              <DropdownMenuItem\n                className=\"rounded-[calc(1rem-6px)] text-xs\"\n                onClick={() => setSelectedModel(\"Local\")}\n              >\n                <IconDeviceLaptop size={16} className=\"opacity-60\" />\n                Local\n              </DropdownMenuItem>\n              <DropdownMenuItem\n                className=\"rounded-[calc(1rem-6px)] text-xs\"\n                onClick={() => setSelectedModel(\"Cloud\")}\n              >\n                <IconCloud size={16} className=\"opacity-60\" />\n                Cloud\n              </DropdownMenuItem>\n            </DropdownMenuGroup>\n          </DropdownMenuContent>\n        </DropdownMenu>\n\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className=\"h-6 px-2 rounded-full border border-transparent hover:bg-accent text-muted-foreground text-xs\"\n            >\n              <IconUser className=\"size-3\" />\n              <span>{selectedAgent}</span>\n              <IconChevronDown className=\"size-3\" />\n            </Button>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            align=\"start\"\n            className=\"max-w-xs rounded-2xl p-1.5 bg-popover border-border\"\n          >\n            <DropdownMenuGroup className=\"space-y-1\">\n              <DropdownMenuItem\n                className=\"rounded-[calc(1rem-6px)] text-xs\"\n                onClick={() => setSelectedAgent(\"Agent\")}\n              >\n                <IconUser size={16} className=\"opacity-60\" />\n                Agent\n              </DropdownMenuItem>\n              <DropdownMenuItem\n                className=\"rounded-[calc(1rem-6px)] text-xs\"\n                onClick={() => setSelectedAgent(\"Assistant\")}\n              >\n                <IconRobot size={16} className=\"opacity-60\" />\n                Assistant\n              </DropdownMenuItem>\n            </DropdownMenuGroup>\n          </DropdownMenuContent>\n        </DropdownMenu>\n\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className=\"h-6 px-2 rounded-full border border-transparent hover:bg-accent text-muted-foreground text-xs\"\n            >\n              <IconBolt className=\"size-3\" />\n              <span>{selectedPerformance}</span>\n              <IconChevronDown className=\"size-3\" />\n            </Button>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            align=\"start\"\n            className=\"max-w-xs rounded-2xl p-1.5 bg-popover border-border\"\n          >\n            <DropdownMenuGroup className=\"space-y-1\">\n              <DropdownMenuItem\n                className=\"rounded-[calc(1rem-6px)] text-xs\"\n                onClick={() => setSelectedPerformance(\"High\")}\n              >\n                <IconCircle size={16} className=\"opacity-60\" />\n                High\n              </DropdownMenuItem>\n              <DropdownMenuItem\n                className=\"rounded-[calc(1rem-6px)] text-xs\"\n                onClick={() => setSelectedPerformance(\"Medium\")}\n              >\n                <IconProgress size={16} className=\"opacity-60\" />\n                Medium\n              </DropdownMenuItem>\n              <DropdownMenuItem\n                className=\"rounded-[calc(1rem-6px)] text-xs\"\n                onClick={() => setSelectedPerformance(\"Low\")}\n              >\n                <IconCircleDashed size={16} className=\"opacity-60\" />\n                Low\n              </DropdownMenuItem>\n            </DropdownMenuGroup>\n          </DropdownMenuContent>\n        </DropdownMenu>\n\n        <div className=\"flex-1\" />\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "ai"
      ]
    },
    {
      "name": "ai-04",
      "type": "registry:block",
      "title": "AI Chat with File Attachments",
      "description": "A ai chat with file attachments block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "button",
        "dropdown-menu",
        "label",
        "switch",
        "textarea"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/ai/ai-04.tsx",
          "type": "registry:component",
          "target": "components/ai-04.tsx",
          "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Label } from \"@/components/ui/label\";\nimport { Switch } from \"@/components/ui/switch\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  IconAdjustmentsHorizontal,\n  IconArrowUp,\n  IconBrandFigma,\n  IconCamera,\n  IconCirclePlus,\n  IconClipboard,\n  IconFileUpload,\n  IconHistory,\n  IconLayoutDashboard,\n  IconLink,\n  IconPaperclip,\n  IconPlayerPlay,\n  IconPlus,\n  IconSparkles,\n  IconTemplate,\n  IconX,\n} from \"@tabler/icons-react\";\nimport Image from \"next/image\";\nimport { useRef, useState } from \"react\";\n\ninterface AttachedFile {\n  id: string;\n  name: string;\n  file: File;\n  preview?: string;\n}\n\nconst ACTIONS = [\n  { id: \"clone-screenshot\", icon: IconCamera, label: \"Clone a Screenshot\" },\n  { id: \"import-figma\", icon: IconBrandFigma, label: \"Import from Figma\" },\n  { id: \"upload-project\", icon: IconFileUpload, label: \"Upload a Project\" },\n  { id: \"landing-page\", icon: IconLayoutDashboard, label: \"Landing Page\" },\n];\n\nexport default function Ai04({\n  onSubmit,\n}: {\n  onSubmit?: (prompt: string) => void;\n}) {\n  const [prompt, setPrompt] = useState(\"\");\n  const [isDragOver, setIsDragOver] = useState(false);\n  const [attachedFiles, setAttachedFiles] = useState<AttachedFile[]>([]);\n  const fileInputRef = useRef<HTMLInputElement>(null);\n\n  const [settings, setSettings] = useState({\n    autoComplete: true,\n    streaming: false,\n    showHistory: false,\n  });\n\n  const generateFileId = () => Math.random().toString(36).substring(7);\n  const processFiles = (files: File[]) => {\n    for (const file of files) {\n      const fileId = generateFileId();\n      const attachedFile: AttachedFile = {\n        id: fileId,\n        name: file.name,\n        file,\n      };\n\n      if (file.type.startsWith(\"image/\")) {\n        const reader = new FileReader();\n        reader.onload = () => {\n          setAttachedFiles((prev) =>\n            prev.map((f) =>\n              f.id === fileId ? { ...f, preview: reader.result as string } : f\n            )\n          );\n        };\n        reader.readAsDataURL(file);\n      }\n\n      setAttachedFiles((prev) => [...prev, attachedFile]);\n    }\n  };\n  const submitPrompt = () => {\n    if (prompt.trim() && onSubmit) {\n      onSubmit(prompt.trim());\n      setPrompt(\"\");\n    }\n  };\n  const updateSetting = (key: keyof typeof settings, value: boolean) => {\n    setSettings((prev) => ({ ...prev, [key]: value }));\n  };\n  const handleSubmit = (e: React.FormEvent) => {\n    e.preventDefault();\n    submitPrompt();\n  };\n  const handleDragOver = (e: React.DragEvent) => {\n    e.preventDefault();\n    setIsDragOver(true);\n  };\n  const handleDragLeave = (e: React.DragEvent) => {\n    e.preventDefault();\n    setIsDragOver(false);\n  };\n  const handleDrop = (e: React.DragEvent) => {\n    e.preventDefault();\n    setIsDragOver(false);\n\n    const files = Array.from(e.dataTransfer.files);\n    if (files.length > 0) {\n      processFiles(files);\n    }\n  };\n  const handleTextareaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n    setPrompt(e.target.value);\n  };\n  const handleKeyDown = (e: React.KeyboardEvent) => {\n    if (e.key === \"Enter\" && !e.shiftKey) {\n      e.preventDefault();\n      submitPrompt();\n    }\n  };\n\n  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const files = Array.from(e.target.files || []);\n    processFiles(files);\n\n    if (fileInputRef.current) {\n      fileInputRef.current.value = \"\";\n    }\n  };\n\n  const handleRemoveFile = (fileId: string) => {\n    setAttachedFiles((prev) => prev.filter((file) => file.id !== fileId));\n  };\n\n  return (\n    <div className=\"mx-auto flex w-full flex-col gap-4\">\n      <h1 className=\"text-balance text-pretty text-center font-heading font-semibold text-[29px] text-foreground tracking-tighter sm:text-[32px] md:text-[46px]\">\n        Prompt. Refine. Ship.\n      </h1>\n      <h2 className=\"text-balance -my-5 pb-4 text-center text-xl text-muted-foreground\">\n        Build real, working software just by describing it\n      </h2>\n\n      <div className=\"relative z-10 flex flex-col w-full mx-auto max-w-2xl content-center\">\n        <form\n          className=\"overflow-visible rounded-xl border p-2 transition-colors duration-200 focus-within:border-ring\"\n          onDragLeave={handleDragLeave}\n          onDragOver={handleDragOver}\n          onDrop={handleDrop}\n          onSubmit={handleSubmit}\n        >\n          {attachedFiles.length > 0 && (\n            <div className=\"relative flex w-fit items-center gap-2 mb-2 overflow-hidden\">\n              {attachedFiles.map((file) => (\n                <Badge\n                  variant=\"outline\"\n                  className=\"group relative h-6 max-w-30 cursor-pointer overflow-hidden text-[13px] transition-colors hover:bg-accent px-0\"\n                  key={file.id}\n                >\n                  <span className=\"flex h-full items-center gap-1.5 overflow-hidden pl-1 font-normal\">\n                    <div className=\"relative flex h-4 min-w-4 items-center justify-center\">\n                      {file.preview ? (\n                        <Image\n                          alt={file.name}\n                          className=\"absolute inset-0 h-4 w-4 rounded border object-cover\"\n                          src={file.preview}\n                          width={16}\n                          height={16}\n                        />\n                      ) : (\n                        <IconPaperclip className=\"opacity-60\" size={12} />\n                      )}\n                    </div>\n                    <span className=\"inline overflow-hidden truncate pr-1.5\">\n                      {file.name}\n                    </span>\n                  </span>\n                  <button\n                    className=\"absolute right-1 z-10 rounded-sm p-0.5 text-muted-foreground opacity-0 focus-visible:bg-accent focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-background group-hover:opacity-100\"\n                    onClick={() => handleRemoveFile(file.id)}\n                    type=\"button\"\n                  >\n                    <IconX size={12} />\n                  </button>\n                </Badge>\n              ))}\n            </div>\n          )}\n          <Textarea\n            className=\"max-h-50 min-h-12 resize-none rounded-none border-none bg-transparent! p-0 text-sm shadow-none focus-visible:border-transparent focus-visible:ring-0\"\n            onChange={handleTextareaChange}\n            onKeyDown={handleKeyDown}\n            placeholder=\"Ask anything\"\n            value={prompt}\n          />\n\n          <div className=\"flex items-center gap-1\">\n            <div className=\"flex items-end gap-0.5 sm:gap-1\">\n              <input\n                className=\"sr-only\"\n                multiple\n                onChange={handleFileSelect}\n                ref={fileInputRef}\n                type=\"file\"\n              />\n\n              <DropdownMenu>\n                <DropdownMenuTrigger asChild>\n                  <Button\n                    className=\"ml-[-2px] rounded-md\"\n                    size=\"icon-sm\"\n                    type=\"button\"\n                    variant=\"ghost\"\n                    aria-label=\"Add attachments\"\n                  >\n                    <IconPlus size={16} />\n                  </Button>\n                </DropdownMenuTrigger>\n                <DropdownMenuContent\n                  align=\"start\"\n                  className=\"max-w-xs rounded-2xl p-1.5\"\n                >\n                  <DropdownMenuGroup className=\"space-y-1\">\n                    <DropdownMenuItem\n                      className=\"rounded-md text-xs\"\n                      onClick={() => fileInputRef.current?.click()}\n                    >\n                      <div className=\"flex items-center gap-2\">\n                        <IconPaperclip className=\"text-muted-foreground\" size={16} />\n                        <span>Attach Files</span>\n                      </div>\n                    </DropdownMenuItem>\n                    <DropdownMenuItem className=\"rounded-md text-xs\">\n                      <div className=\"flex items-center gap-2\">\n                        <IconLink className=\"text-muted-foreground\" size={16} />\n                        <span>Import from URL</span>\n                      </div>\n                    </DropdownMenuItem>\n                    <DropdownMenuItem className=\"rounded-md text-xs\">\n                      <div className=\"flex items-center gap-2\">\n                        <IconClipboard className=\"text-muted-foreground\" size={16} />\n                        <span>Paste from Clipboard</span>\n                      </div>\n                    </DropdownMenuItem>\n                    <DropdownMenuItem className=\"rounded-md text-xs\">\n                      <div className=\"flex items-center gap-2\">\n                        <IconTemplate className=\"text-muted-foreground\" size={16} />\n                        <span>Use Template</span>\n                      </div>\n                    </DropdownMenuItem>\n                  </DropdownMenuGroup>\n                </DropdownMenuContent>\n              </DropdownMenu>\n\n              <DropdownMenu>\n                <DropdownMenuTrigger asChild>\n                  <Button\n                    className=\"rounded-md\"\n                    size=\"icon-sm\"\n                    type=\"button\"\n                    variant=\"ghost\"\n                    aria-label=\"Adjust settings\"\n                  >\n                    <IconAdjustmentsHorizontal size={16} />\n                  </Button>\n                </DropdownMenuTrigger>\n                <DropdownMenuContent\n                  align=\"start\"\n                  className=\"w-48 rounded-2xl p-3\"\n                >\n                  <DropdownMenuGroup className=\"space-y-3\">\n                    <div className=\"flex items-center justify-between\">\n                      <div className=\"flex items-center gap-2\">\n                        <IconSparkles className=\"text-muted-foreground\" size={16} />\n                        <Label className=\"text-xs\">Auto-complete</Label>\n                      </div>\n                      <Switch\n                        checked={settings.autoComplete}\n                        className=\"scale-75\"\n                        onCheckedChange={(value) =>\n                          updateSetting(\"autoComplete\", value)\n                        }\n                      />\n                    </div>\n\n                    <div className=\"flex items-center justify-between\">\n                      <div className=\"flex items-center gap-2\">\n                        <IconPlayerPlay className=\"text-muted-foreground\" size={16} />\n                        <Label className=\"text-xs\">Streaming</Label>\n                      </div>\n                      <Switch\n                        checked={settings.streaming}\n                        className=\"scale-75\"\n                        onCheckedChange={(value) =>\n                          updateSetting(\"streaming\", value)\n                        }\n                      />\n                    </div>\n\n                    <div className=\"flex items-center justify-between\">\n                      <div className=\"flex items-center gap-2\">\n                        <IconHistory className=\"text-muted-foreground\" size={16} />\n                        <Label className=\"text-xs\">Show History</Label>\n                      </div>\n                      <Switch\n                        checked={settings.showHistory}\n                        className=\"scale-75\"\n                        onCheckedChange={(value) =>\n                          updateSetting(\"showHistory\", value)\n                        }\n                      />\n                    </div>\n                  </DropdownMenuGroup>\n                </DropdownMenuContent>\n              </DropdownMenu>\n            </div>\n\n            <div className=\"ml-auto flex items-center gap-0.5 sm:gap-1\">\n              <Button\n                className=\"rounded-md\"\n                disabled={!prompt.trim()}\n                size=\"icon-sm\"\n                type=\"submit\"\n                variant=\"default\"\n                aria-label=\"Send message\"\n              >\n                <IconArrowUp size={16} />\n              </Button>\n            </div>\n          </div>\n\n          <div\n            className={cn(\n              \"absolute inset-0 flex items-center justify-center pointer-events-none z-20 rounded-[inherit] border border-border border-dashed bg-muted text-foreground text-sm transition-opacity duration-200\",\n              isDragOver ? \"opacity-100\" : \"opacity-0\"\n            )}\n          >\n            <span className=\"flex w-full items-center justify-center gap-1 font-medium\">\n              <IconCirclePlus className=\"min-w-4\" size={16} />\n              Drop files here to add as attachments\n            </span>\n          </div>\n        </form>\n      </div>\n\n      <div className=\"max-w-250 mx-auto flex-wrap gap-3 flex min-h-0 shrink-0 items-center justify-center\">\n        {ACTIONS.map((action) => (\n          <Button\n            className=\"gap-2 rounded-full\"\n            key={action.id}\n            size=\"sm\"\n            variant=\"outline\"\n          >\n            <action.icon size={16} />\n            {action.label}\n          </Button>\n        ))}\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "ai"
      ]
    },
    {
      "name": "ai-05",
      "type": "registry:block",
      "title": "AI Elements Chat",
      "description": "A ai elements chat block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "button"
      ],
      "dependencies": [
        "@tabler/icons-react",
        "ai"
      ],
      "files": [
        {
          "path": "content/components/ai/ai-05.tsx",
          "type": "registry:component",
          "target": "components/ai-05.tsx",
          "content": "\"use client\";\n\n// Install AI Elements components:\n// npx ai-elements@latest add conversation message prompt-input\n\nimport { useEffect, useRef, useState } from \"react\";\nimport type { ChatStatus } from \"ai\";\nimport {\n  Conversation,\n  ConversationContent,\n  ConversationScrollButton,\n} from \"@/components/ai-elements/conversation\";\nimport {\n  Message,\n  MessageContent,\n  MessageResponse,\n} from \"@/components/ai-elements/message\";\nimport {\n  PromptInput,\n  PromptInputButton,\n  PromptInputFooter,\n  PromptInputSubmit,\n  PromptInputTextarea,\n  PromptInputTools,\n} from \"@/components/ai-elements/prompt-input\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  IconAdjustmentsHorizontal,\n  IconBolt,\n  IconMessageCircle,\n  IconPaperclip,\n  IconRefresh,\n  IconSparkles,\n} from \"@tabler/icons-react\";\n\ninterface DemoMessage {\n  id: string;\n  role: \"user\" | \"assistant\";\n  content: string;\n}\n\nconst INITIAL_MESSAGES: DemoMessage[] = [\n  {\n    id: \"intro\",\n    role: \"assistant\",\n    content:\n      \"**Welcome back.** I can help you explore this chat block.\\n\\n- Draft UI copy\\n- Summarize docs\\n- Turn notes into tasks\\n\\nAsk me anything and I will respond with a demo reply.\",\n  },\n  {\n    id: \"question\",\n    role: \"user\",\n    content: \"What makes this chat block reusable?\",\n  },\n  {\n    id: \"answer\",\n    role: \"assistant\",\n    content:\n      \"It is built with **AI Elements** for conversation layout and input, plus shadcn/ui for the chrome. That means you can drop it into other screens and wire it up to a real AI backend later.\",\n  },\n];\n\nconst RESPONSES = [\n  \"Here is a quick outline you can reuse:\\n\\n1. Swap the mock response with a real API call.\\n2. Stream tokens into `MessageResponse`.\\n3. Keep the layout exactly as-is for a consistent UI.\",\n  \"If you want multi-model support, add a small model selector next to the status badge and pass the selection to your backend.\",\n  \"You can also inject tools like file upload or voice input by adding buttons to the prompt footer.\",\n];\n\nconst pickResponse = (index: number) =>\n  RESPONSES[index % RESPONSES.length];\n\nexport default function Ai05() {\n  const [messages, setMessages] = useState<DemoMessage[]>(INITIAL_MESSAGES);\n  const [inputValue, setInputValue] = useState(\"\");\n  const [status, setStatus] = useState<ChatStatus>(\"ready\");\n  const replyTimeoutRef = useRef<number | null>(null);\n\n  useEffect(() => {\n    return () => {\n      if (replyTimeoutRef.current) {\n        window.clearTimeout(replyTimeoutRef.current);\n      }\n    };\n  }, []);\n\n  const handleSend = (text: string) => {\n    const trimmed = text.trim();\n    if (!trimmed) {\n      return;\n    }\n\n    const newMessage: DemoMessage = {\n      id: `user-${Date.now()}`,\n      role: \"user\",\n      content: trimmed,\n    };\n\n    setMessages((prev) => [...prev, newMessage]);\n    setInputValue(\"\");\n    setStatus(\"submitted\");\n\n    replyTimeoutRef.current = window.setTimeout(() => {\n      const response: DemoMessage = {\n        id: `assistant-${Date.now()}`,\n        role: \"assistant\",\n        content: pickResponse(messages.length),\n      };\n\n      setMessages((prev) => [...prev, response]);\n      setStatus(\"ready\");\n    }, 900);\n  };\n\n  return (\n    <div className=\"w-full px-4\">\n      <div className=\"mx-auto flex h-96 w-full max-w-2xl flex-col overflow-hidden rounded-2xl border border-border bg-card shadow-lg sm:w-3/5\">\n        <header className=\"flex items-center justify-between gap-4 border-b border-border/80 px-4 py-3\">\n          <div className=\"flex items-center gap-3\">\n            \n            <div className=\"space-y-1\">\n              <div className=\"flex items-center gap-2 text-balance text-sm font-semibold\">\n                Documenso Chat\n              </div>\n              <div className=\"flex items-center gap-2 text-pretty text-xs text-muted-foreground\">\n                <span className=\"inline-flex items-center gap-1\">\n                  <span className=\"size-1.5 rounded-full bg-emerald-500\" />\n                  Live preview\n                </span>\n                <span className=\"hidden sm:inline\">- Powered by shadcn/ui</span>\n              </div>\n            </div>\n          </div>\n          <div className=\"flex items-center gap-1\">\n            <Button\n              size=\"icon\"\n              variant=\"ghost\"\n              className=\"size-8\"\n              aria-label=\"Refresh\"\n              title=\"Refresh\"\n            >\n              <IconRefresh className=\"size-4\" />\n            </Button>\n            <Button\n              size=\"icon\"\n              variant=\"ghost\"\n              className=\"size-8\"\n              aria-label=\"Settings\"\n              title=\"Settings\"\n            >\n              <IconAdjustmentsHorizontal className=\"size-4\" />\n            </Button>\n          </div>\n        </header>\n\n        <Conversation className=\"bg-muted/30\">\n          <ConversationContent className=\"gap-6 pl-1\">\n            {messages.map((message) => (\n              <Message key={message.id} from={message.role}>\n                <MessageContent\n                  className={cn(\n                    \"leading-relaxed\",\n                    message.role === \"assistant\" && \"max-w-prose\"\n                  )}\n                >\n                  {message.role === \"assistant\" ? (\n                    <MessageResponse>{message.content}</MessageResponse>\n                  ) : (\n                    <p className=\"whitespace-pre-wrap text-pretty\">\n                      {message.content}\n                    </p>\n                  )}\n                </MessageContent>\n              </Message>\n            ))}\n          </ConversationContent>\n          <ConversationScrollButton />\n        </Conversation>\n\n        <div className=\"bg-background\">\n          <PromptInput\n            onSubmit={(message) => handleSend(message.text)}\n            className=\"w-full [&>[data-slot=input-group]]:rounded-none [&>[data-slot=input-group]]:shadow-none [&>[data-slot=input-group]]:border-t [&>[data-slot=input-group]]:border-x-0 [&>[data-slot=input-group]]:border-b-0 [&>[data-slot=input-group]]:border-border/80 [&>[data-slot=input-group]]:focus-within:ring-0 [&>[data-slot=input-group]]:focus-within:ring-transparent [&>[data-slot=input-group]]:focus-within:ring-offset-0 [&>[data-slot=input-group]]:focus-within:border-border/80 [&>[data-slot=input-group]]:focus-within:outline-none\"\n          >\n            <PromptInputTextarea\n              placeholder=\"Ask about the block, UI patterns, or an AI workflow\"\n              value={inputValue}\n              onChange={(event) => setInputValue(event.currentTarget.value)}\n            />\n            <PromptInputFooter>\n              <PromptInputTools>\n                <PromptInputButton aria-label=\"Attach\">\n                  <IconPaperclip className=\"size-4\" />\n                </PromptInputButton>\n                <PromptInputButton aria-label=\"Quick prompt\">\n                  <IconBolt className=\"size-4\" />\n                </PromptInputButton>\n                <PromptInputButton aria-label=\"New chat\">\n                  <IconMessageCircle className=\"size-4\" />\n                </PromptInputButton>\n              </PromptInputTools>\n              <PromptInputSubmit\n                status={status}\n                disabled={!inputValue.trim() || status !== \"ready\"}\n              />\n            </PromptInputFooter>\n          </PromptInput>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "ai"
      ]
    },
    {
      "name": "command-menu-01",
      "type": "registry:block",
      "title": "Command Menu with Groups",
      "description": "A command menu with groups block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "command",
        "kbd"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/command-menu/command-menu-01.tsx",
          "type": "registry:component",
          "target": "components/command-menu-01.tsx",
          "content": "\"use client\";\n\nimport {\n  IconBell,\n  IconBolt,\n  IconCalendar,\n  IconChartBar,\n  IconChartPie,\n  IconClock,\n  IconFileText,\n  IconHelp,\n  IconKeyboard,\n  IconLayoutDashboard,\n  IconLayoutKanban,\n  IconLogout,\n  IconMessage,\n  IconPalette,\n  IconSettings,\n  IconSquareCheck,\n  IconTarget,\n  IconTrendingUp,\n  IconUsers,\n} from \"@tabler/icons-react\";\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/components/ui/command\";\nimport { Kbd } from \"@/components/ui/kbd\";\n\nconst workspaceItems = [\n  { icon: IconLayoutDashboard, label: \"Dashboard\" },\n  { icon: IconLayoutKanban, label: \"Projects\" },\n  { icon: IconSquareCheck, label: \"Tasks\" },\n  { icon: IconCalendar, label: \"Calendar\" },\n  { icon: IconUsers, label: \"Team members\" },\n  { icon: IconMessage, label: \"Messages\" },\n  { icon: IconFileText, label: \"Documents\" },\n  { icon: IconBell, label: \"Notifications\" },\n  { icon: IconClock, label: \"Time tracking\" },\n  { icon: IconTarget, label: \"Goals\" },\n];\n\nconst analyticsItems = [\n  { icon: IconChartBar, label: \"Overview\" },\n  { icon: IconTrendingUp, label: \"Performance\" },\n  { icon: IconChartPie, label: \"Reports\" },\n  { icon: IconBolt, label: \"Insights\" },\n];\n\nconst settingsItems = [\n  { icon: IconSettings, label: \"Preferences\" },\n  { icon: IconPalette, label: \"Appearance\" },\n  { icon: IconKeyboard, label: \"Keyboard shortcuts\" },\n  { icon: IconHelp, label: \"Help & support\" },\n  { icon: IconLogout, label: \"Sign out\" },\n];\n\nexport function CommandMenu01() {\n  const [open, setOpen] = useState(true);\n\n  useEffect(() => {\n    const down = (e: KeyboardEvent) => {\n      if (e.key === \"k\" && (e.metaKey || e.ctrlKey)) {\n        e.preventDefault();\n        setOpen((prev) => !prev);\n      }\n    };\n\n    document.addEventListener(\"keydown\", down);\n    return () => document.removeEventListener(\"keydown\", down);\n  }, []);\n\n  return (\n    <>\n      <Button onClick={() => setOpen(true)} variant=\"outline\">\n        Open Command Menu\n      </Button>\n\n      <CommandDialog onOpenChange={setOpen} open={open} showCloseButton={false}>\n        <CommandInput\n          className=\"h-12\"\n          placeholder=\"Type a command or search...\"\n        />\n        <CommandList className=\"h-[320px] max-h-[320px]\">\n          <CommandEmpty>No results found.</CommandEmpty>\n          <CommandGroup heading=\"Workspace\">\n            {workspaceItems.map((item) => (\n              <CommandItem key={item.label}>\n                <item.icon className=\"mr-2 h-5 w-5\" />\n                <span>{item.label}</span>\n              </CommandItem>\n            ))}\n          </CommandGroup>\n          <CommandGroup heading=\"Analytics\">\n            {analyticsItems.map((item) => (\n              <CommandItem key={item.label}>\n                <item.icon className=\"mr-2 h-5 w-5\" />\n                <span>{item.label}</span>\n              </CommandItem>\n            ))}\n          </CommandGroup>\n          <CommandGroup heading=\"Settings\">\n            {settingsItems.map((item) => (\n              <CommandItem key={item.label}>\n                <item.icon className=\"mr-2 h-5 w-5\" />\n                <span>{item.label}</span>\n              </CommandItem>\n            ))}\n          </CommandGroup>\n        </CommandList>\n        <div className=\"flex h-12 items-center justify-end border-t px-3\">\n          <button\n            className=\"flex items-center gap-1 text-muted-foreground text-sm hover:text-foreground\"\n            onClick={() => setOpen(false)}\n            type=\"button\"\n          >\n            <span>Close</span>\n            <Kbd className=\"ml-1\">Esc</Kbd>\n          </button>\n        </div>\n      </CommandDialog>\n    </>\n  );\n}\n"
        }
      ],
      "categories": [
        "command-menu"
      ]
    },
    {
      "name": "command-menu-02",
      "type": "registry:block",
      "title": "Command Menu with Keyboard Shortcuts",
      "description": "A command menu with keyboard shortcuts block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "command",
        "dialog",
        "kbd"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/command-menu/command-menu-02.tsx",
          "type": "registry:component",
          "target": "components/command-menu-02.tsx",
          "content": "\"use client\";\n\nimport {\n  IconArrowRight,\n  IconAt,\n  IconCopy,\n  IconDeviceDesktop,\n  IconDownload,\n  IconFile,\n  IconFileSearch,\n  IconKeyboard,\n  IconLink,\n  IconLogout,\n  IconMessage,\n  IconPencil,\n  IconPlus,\n  IconSend,\n  IconSettings,\n  IconTemplate,\n  IconUser,\n  IconUsers,\n} from \"@tabler/icons-react\";\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/components/ui/command\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ui/dialog\";\nimport { Kbd, KbdGroup } from \"@/components/ui/kbd\";\n\nexport function CommandMenu02() {\n  const [open, setOpen] = useState(true);\n  const [inputValue, setInputValue] = useState(\"\");\n\n  useEffect(() => {\n    const down = (e: KeyboardEvent) => {\n      if (e.key === \"k\" && (e.metaKey || e.ctrlKey)) {\n        e.preventDefault();\n        setOpen((prev) => !prev);\n      }\n    };\n\n    document.addEventListener(\"keydown\", down);\n    return () => document.removeEventListener(\"keydown\", down);\n  }, []);\n\n  return (\n    <>\n      <Button onClick={() => setOpen(true)} variant=\"outline\">\n        Open Command Menu\n      </Button>\n\n      <Dialog onOpenChange={setOpen} open={open}>\n        <DialogHeader className=\"sr-only\">\n          <DialogTitle>Command Menu</DialogTitle>\n          <DialogDescription>\n            Use the command menu to navigate through the app.\n          </DialogDescription>\n        </DialogHeader>\n        <DialogContent\n          className=\"gap-0 overflow-hidden rounded-xl border-border/50 p-0 shadow-lg sm:max-w-lg\"\n          showCloseButton={false}\n        >\n          <Command className=\"flex h-full w-full flex-col overflow-hidden bg-popover **:data-[slot=command-input-wrapper]:h-auto **:data-[slot=command-input-wrapper]:grow **:data-[slot=command-input-wrapper]:border-0 **:data-[slot=command-input-wrapper]:px-0\">\n            <div className=\"flex h-12 items-center gap-2 border-border/50 border-b px-4\">\n              <CommandInput\n                className=\"h-10 text-[15px]\"\n                onValueChange={setInputValue}\n                placeholder=\"What do you need?\"\n                value={inputValue}\n              />\n              <button\n                className=\"flex shrink-0 items-center\"\n                onClick={() => setOpen(false)}\n                type=\"button\"\n              >\n                <Kbd>Esc</Kbd>\n              </button>\n            </div>\n\n            <CommandList className=\"max-h-[400px] py-2\">\n              <CommandEmpty>No results found.</CommandEmpty>\n\n              <CommandGroup>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconSettings aria-hidden />\n                  Account Settings...\n                  <KbdGroup className=\"ml-auto\">\n                    <Kbd>⌘</Kbd>\n                    <Kbd>,</Kbd>\n                  </KbdGroup>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconUser aria-hidden />\n                  Switch Workspace...\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconLogout aria-hidden />\n                  Log Out\n                  <KbdGroup className=\"ml-auto\">\n                    <Kbd>⌘</Kbd>\n                    <Kbd>Q</Kbd>\n                  </KbdGroup>\n                </CommandItem>\n              </CommandGroup>\n\n              <CommandGroup heading=\"Documents\">\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconFile aria-hidden />\n                  Search Documents...\n                  <KbdGroup className=\"ml-auto\">\n                    <Kbd>⌘</Kbd>\n                    <Kbd>F</Kbd>\n                  </KbdGroup>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconPlus aria-hidden />\n                  Create New Document...\n                  <KbdGroup className=\"ml-auto\">\n                    <Kbd>⌘</Kbd>\n                    <Kbd>N</Kbd>\n                  </KbdGroup>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconFile aria-hidden />\n                  Upload Document...\n                  <KbdGroup className=\"ml-auto\">\n                    <Kbd>⌘</Kbd>\n                    <Kbd>U</Kbd>\n                  </KbdGroup>\n                </CommandItem>\n              </CommandGroup>\n\n              <CommandGroup heading=\"Signing\">\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconSend aria-hidden />\n                  Request Signature...\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconPencil aria-hidden />\n                  Sign a Document...\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconUsers aria-hidden />\n                  Bulk Send for Signature...\n                </CommandItem>\n              </CommandGroup>\n\n              <CommandGroup heading=\"Templates\">\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconTemplate aria-hidden />\n                  Search Templates...\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconPlus aria-hidden />\n                  Create New Template...\n                </CommandItem>\n              </CommandGroup>\n\n              <CommandGroup heading=\"General\">\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconDeviceDesktop aria-hidden />\n                  Change Theme...\n                  <KbdGroup className=\"ml-auto\">\n                    <Kbd>⌘</Kbd>\n                    <Kbd>T</Kbd>\n                  </KbdGroup>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconCopy aria-hidden />\n                  Copy Current URL\n                  <KbdGroup className=\"ml-auto\">\n                    <Kbd>⌘</Kbd>\n                    <Kbd>⇧</Kbd>\n                    <Kbd>C</Kbd>\n                  </KbdGroup>\n                </CommandItem>\n              </CommandGroup>\n\n              <CommandGroup heading=\"Navigation\">\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;<strong className=\"font-semibold\">Inbox</strong>\n                  </span>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;\n                    <strong className=\"font-semibold\">Action Required</strong>\n                  </span>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;\n                    <strong className=\"font-semibold\">\n                      Waiting for Others\n                    </strong>\n                  </span>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;\n                    <strong className=\"font-semibold\">Completed</strong>\n                  </span>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;<strong className=\"font-semibold\">Drafts</strong>\n                  </span>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;\n                    <strong className=\"font-semibold\">Templates</strong>\n                  </span>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;\n                    <strong className=\"font-semibold\">Archive</strong>\n                  </span>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;<strong className=\"font-semibold\">Trash</strong>\n                  </span>\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconArrowRight aria-hidden />\n                  <span>\n                    Go to&nbsp;\n                    <strong className=\"font-semibold\">Settings</strong>\n                  </span>\n                </CommandItem>\n              </CommandGroup>\n\n              <CommandGroup heading=\"Quick Actions\">\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconLink aria-hidden />\n                  Copy Signing Link\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconDownload aria-hidden />\n                  Download Document\n                </CommandItem>\n              </CommandGroup>\n\n              <CommandGroup heading=\"Help\">\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconFileSearch aria-hidden />\n                  Search Help Center...\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconMessage aria-hidden />\n                  Send Feedback...\n                </CommandItem>\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconAt aria-hidden />\n                  Contact Support\n                </CommandItem>\n              </CommandGroup>\n\n              <CommandGroup heading=\"Keyboard Shortcuts\">\n                <CommandItem\n                  className=\"mx-2 rounded-lg py-2.5\"\n                  onSelect={() => setOpen(false)}\n                >\n                  <IconKeyboard aria-hidden />\n                  View Keyboard Shortcuts\n                  <KbdGroup className=\"ml-auto\">\n                    <Kbd>⌘</Kbd>\n                    <Kbd>/</Kbd>\n                  </KbdGroup>\n                </CommandItem>\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </DialogContent>\n      </Dialog>\n    </>\n  );\n}\n"
        }
      ],
      "categories": [
        "command-menu"
      ]
    },
    {
      "name": "command-menu-03",
      "type": "registry:block",
      "title": "Command Menu with Documentation Search",
      "description": "A command menu with documentation search block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "command",
        "dialog",
        "kbd"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/command-menu/command-menu-03.tsx",
          "type": "registry:component",
          "target": "components/command-menu-03.tsx",
          "content": "\"use client\";\n\nimport { IconArrowRight, IconCornerDownLeft } from \"@tabler/icons-react\";\nimport { useRouter } from \"next/navigation\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/components/ui/command\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ui/dialog\";\nimport { Kbd } from \"@/components/ui/kbd\";\n\nconst navItems = [\n  { href: \"/\", label: \"Home\", keywords: [\"home\", \"main\", \"index\"] },\n  {\n    href: \"/dashboard\",\n    label: \"Dashboard\",\n    keywords: [\"dashboard\", \"overview\"],\n  },\n  {\n    href: \"/settings\",\n    label: \"Settings\",\n    keywords: [\"settings\", \"preferences\"],\n  },\n];\n\nconst pageGroups = [\n  {\n    name: \"Getting Started\",\n    pages: [\n      {\n        name: \"Introduction\",\n        href: \"/docs/introduction\",\n        keywords: [\"intro\", \"start\"],\n      },\n      {\n        name: \"Installation\",\n        href: \"/docs/installation\",\n        keywords: [\"install\", \"setup\"],\n      },\n      {\n        name: \"Quick Start\",\n        href: \"/docs/quick-start\",\n        keywords: [\"quick\", \"begin\"],\n      },\n    ],\n  },\n  {\n    name: \"Utilities\",\n    pages: [\n      {\n        name: \"Typography\",\n        href: \"/docs/utilities/typography\",\n        keywords: [\"text\", \"font\"],\n      },\n      {\n        name: \"Colors\",\n        href: \"/docs/utilities/colors\",\n        keywords: [\"color\", \"theme\"],\n      },\n      {\n        name: \"Spacing\",\n        href: \"/docs/utilities/spacing\",\n        keywords: [\"margin\", \"padding\"],\n      },\n    ],\n  },\n];\n\nconst colorGroups = [\n  {\n    name: \"Neutral\",\n    colors: [\n      {\n        name: \"Neutral 50\",\n        className: \"neutral-50\",\n        value: \"oklch(0.985 0 0)\",\n      },\n      {\n        name: \"Neutral 100\",\n        className: \"neutral-100\",\n        value: \"oklch(0.97 0 0)\",\n      },\n      {\n        name: \"Neutral 200\",\n        className: \"neutral-200\",\n        value: \"oklch(0.922 0 0)\",\n      },\n      {\n        name: \"Neutral 500\",\n        className: \"neutral-500\",\n        value: \"oklch(0.556 0 0)\",\n      },\n      {\n        name: \"Neutral 900\",\n        className: \"neutral-900\",\n        value: \"oklch(0.205 0 0)\",\n      },\n    ],\n  },\n  {\n    name: \"Blue\",\n    colors: [\n      {\n        name: \"Blue 50\",\n        className: \"blue-50\",\n        value: \"oklch(0.97 0.014 254.604)\",\n      },\n      {\n        name: \"Blue 500\",\n        className: \"blue-500\",\n        value: \"oklch(0.623 0.214 259.815)\",\n      },\n      {\n        name: \"Blue 600\",\n        className: \"blue-600\",\n        value: \"oklch(0.546 0.245 262.881)\",\n      },\n    ],\n  },\n];\n\nexport function CommandMenu03() {\n  const router = useRouter();\n  const [open, setOpen] = useState(true);\n\n  const copyToClipboard = useCallback((text: string) => {\n    navigator.clipboard.writeText(text);\n  }, []);\n\n  const runCommand = useCallback((command: () => unknown) => {\n    setOpen(false);\n    command();\n  }, []);\n\n  useEffect(() => {\n    const down = (e: KeyboardEvent) => {\n      if ((e.key === \"k\" && (e.metaKey || e.ctrlKey)) || e.key === \"/\") {\n        if (\n          (e.target instanceof HTMLElement && e.target.isContentEditable) ||\n          e.target instanceof HTMLInputElement ||\n          e.target instanceof HTMLTextAreaElement ||\n          e.target instanceof HTMLSelectElement\n        ) {\n          return;\n        }\n        e.preventDefault();\n        setOpen((prev) => !prev);\n      }\n    };\n\n    document.addEventListener(\"keydown\", down);\n    return () => document.removeEventListener(\"keydown\", down);\n  }, []);\n\n  return (\n    <>\n      <Button onClick={() => setOpen(true)} variant=\"outline\">\n        Open Command Menu\n      </Button>\n\n      <Dialog onOpenChange={setOpen} open={open}>\n        <DialogContent className=\"rounded-xl border-none bg-clip-padding p-2 pb-11 shadow-2xl ring-4 ring-neutral-200/80 dark:bg-neutral-900 dark:ring-neutral-800\">\n          <DialogHeader className=\"sr-only\">\n            <DialogTitle>Search documentation...</DialogTitle>\n            <DialogDescription>\n              Search for a command to run...\n            </DialogDescription>\n          </DialogHeader>\n\n          <Command className=\"rounded-none bg-transparent **:data-[slot=command-input-wrapper]:mb-0 **:data-[slot=command-input-wrapper]:h-9! **:data-[slot=command-input]:h-9! **:data-[slot=command-input-wrapper]:rounded-md **:data-[slot=command-input-wrapper]:border **:data-[slot=command-input-wrapper]:border-input **:data-[slot=command-input-wrapper]:bg-input/50 **:data-[slot=command-input]:py-0\">\n            <CommandInput placeholder=\"Search documentation...\" />\n            <CommandList className=\"no-scrollbar min-h-80 scroll-pt-2 scroll-pb-1.5\">\n              <CommandEmpty className=\"py-12 text-center text-muted-foreground text-sm\">\n                No results found.\n              </CommandEmpty>\n\n              {navItems.length > 0 && (\n                <CommandGroup\n                  className=\"p-0! **:[[cmdk-group-heading]]:scroll-mt-16 **:[[cmdk-group-heading]]:p-3! **:[[cmdk-group-heading]]:pb-1!\"\n                  heading=\"Pages\"\n                >\n                  {navItems.map((item) => (\n                    <CommandItem\n                      className=\"px-3! h-9 rounded-md border border-transparent font-medium hover:border-input hover:bg-input/50\"\n                      key={item.href}\n                      keywords={item.keywords}\n                      onSelect={() => {\n                        runCommand(() => router.push(item.href));\n                      }}\n                      value={`Navigation ${item.label}`}\n                    >\n                      <IconArrowRight aria-hidden=\"true\" className=\"size-4\" />\n                      {item.label}\n                    </CommandItem>\n                  ))}\n                </CommandGroup>\n              )}\n\n              {pageGroups.map((group) => (\n                <CommandGroup\n                  className=\"p-0! **:[[cmdk-group-heading]]:scroll-mt-16 **:[[cmdk-group-heading]]:p-3! **:[[cmdk-group-heading]]:pb-1!\"\n                  heading={group.name}\n                  key={group.name}\n                >\n                  {group.pages.map((page) => {\n                    const isComponent = page.href.includes(\"/components/\");\n                    return (\n                      <CommandItem\n                        className=\"px-3! h-9 rounded-md border border-transparent font-medium hover:border-input hover:bg-input/50\"\n                        key={page.href}\n                        keywords={page.keywords}\n                        onSelect={() => {\n                          runCommand(() => router.push(page.href));\n                        }}\n                        value={`${group.name} ${page.name}`}\n                      >\n                        {isComponent ? (\n                          <div className=\"aspect-square size-4 rounded-full border border-muted-foreground border-dashed\" />\n                        ) : (\n                          <IconArrowRight\n                            aria-hidden=\"true\"\n                            className=\"size-4\"\n                          />\n                        )}\n                        {page.name}\n                      </CommandItem>\n                    );\n                  })}\n                </CommandGroup>\n              ))}\n\n              {colorGroups.map((colorGroup) => (\n                <CommandGroup\n                  className=\"p-0! **:[[cmdk-group-heading]]:p-3!\"\n                  heading={colorGroup.name}\n                  key={colorGroup.name}\n                >\n                  {colorGroup.colors.map((color) => (\n                    <CommandItem\n                      className=\"px-3! h-9 rounded-md border border-transparent font-medium hover:border-input hover:bg-input/50\"\n                      key={color.className}\n                      keywords={[\"color\", color.name, color.className]}\n                      onSelect={() => {\n                        runCommand(() => copyToClipboard(color.value));\n                      }}\n                      value={color.className}\n                    >\n                      <div\n                        className=\"aspect-square size-4 rounded-sm border\"\n                        style={{ backgroundColor: color.value }}\n                      />\n                      {color.className}\n                      <span className=\"ml-auto font-mono font-normal text-muted-foreground text-xs tabular-nums\">\n                        {color.value}\n                      </span>\n                    </CommandItem>\n                  ))}\n                </CommandGroup>\n              ))}\n            </CommandList>\n          </Command>\n\n          <div className=\"absolute inset-x-0 bottom-0 z-20 flex h-10 items-center gap-2 rounded-b-xl border-t border-t-neutral-100 bg-neutral-50 px-4 font-medium text-muted-foreground text-xs dark:border-t-neutral-700 dark:bg-neutral-800\">\n            <Kbd>\n              <IconCornerDownLeft aria-hidden=\"true\" className=\"size-3\" />\n            </Kbd>\n            Select\n          </div>\n        </DialogContent>\n      </Dialog>\n    </>\n  );\n}\n"
        }
      ],
      "categories": [
        "command-menu"
      ]
    },
    {
      "name": "dialog-01",
      "type": "registry:block",
      "title": "Dialog Confirmation",
      "description": "A dialog confirmation block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dialog"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-01.tsx",
          "type": "registry:component",
          "target": "components/dialog-01.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Check } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport default function Dialog01() {\n  const [open, setOpen] = useState(true);\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Show Dialog</Button>\n      </DialogTrigger>\n\n      <DialogContent className=\"sm:max-w-sm flex flex-col items-center\">\n        <div className=\"flex justify-center\">\n          <div className=\"mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100\">\n            <Check className=\"h-6 w-6 text-green-600\" />\n          </div>\n        </div>\n\n        <DialogHeader className=\"text-center gap-0\">\n          <DialogTitle className=\"text-balance text-center\">Payment successful</DialogTitle>\n          <DialogDescription className=\"text-pretty mt-2 text-center mx-auto sm:max-w-[90%]\">\n            Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur\n            amet labore.\n          </DialogDescription>\n        </DialogHeader>\n        <DialogFooter className=\"sm:justify-center w-full\">\n          <DialogClose asChild>\n            <Button className=\"w-full\">Go back to dashboard</Button>\n          </DialogClose>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-02",
      "type": "registry:block",
      "title": "Dialog with Warning Icon",
      "description": "A dialog with warning icon block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dialog"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-02.tsx",
          "type": "registry:component",
          "target": "components/dialog-02.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Check } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport default function Dialog04() {\n  const [open, setOpen] = useState(true);\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Show Dialog</Button>\n      </DialogTrigger>\n\n      <DialogContent className=\"sm:max-w-sm flex flex-col items-center\">\n        <div className=\"flex justify-center\">\n          <div className=\"mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100\">\n            <Check className=\"h-6 w-6 text-green-600\" />\n          </div>\n        </div>\n\n        <DialogHeader className=\"text-center gap-0\">\n          <DialogTitle className=\"text-balance text-center\">Payment successful</DialogTitle>\n          <DialogDescription className=\"text-pretty mt-2 text-center mx-auto sm:max-w-[90%]\">\n            Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur\n            amet labore.\n          </DialogDescription>\n        </DialogHeader>\n        <DialogFooter className=\"flex flex-col sm:flex-row sm:gap-3 w-full gap-2\">\n          <DialogClose asChild>\n            <Button variant=\"default\" className=\"w-full sm:w-1/2\">\n              Deactivate\n            </Button>\n          </DialogClose>\n          <DialogClose asChild>\n            <Button variant=\"outline\" className=\"w-full sm:w-1/2\">\n              Cancel\n            </Button>\n          </DialogClose>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-03",
      "type": "registry:block",
      "title": "Dialog with Input Field",
      "description": "A dialog with input field block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dialog"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-03.tsx",
          "type": "registry:component",
          "target": "components/dialog-03.tsx",
          "content": "\"use client\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { AlertTriangleIcon } from \"lucide-react\";\nimport { useState } from \"react\";\n\nexport default function Dialog02() {\n  const [open, setOpen] = useState(true);\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button variant=\"destructive\">Deactivate</Button>\n      </DialogTrigger>\n      <DialogContent className=\"sm:max-w-lg\">\n        <div className=\"flex items-start space-x-4\">\n          <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-red-100\">\n            <AlertTriangleIcon className=\"h-6 w-6 text-red-600\" />\n          </div>\n          <DialogHeader>\n            <DialogTitle>Deactivate account</DialogTitle>\n            <DialogDescription>\n              Are you sure you want to deactivate your account? All of your data\n              will be permanently removed. This action cannot be undone.\n            </DialogDescription>\n          </DialogHeader>\n        </div>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button variant=\"outline\">Cancel</Button>\n          </DialogClose>\n          <Button variant=\"destructive\" onClick={() => setOpen(false)}>\n            Deactivate\n          </Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-04",
      "type": "registry:block",
      "title": "Dialog with Two Buttons",
      "description": "A dialog with two buttons block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dialog",
        "input",
        "label"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/dialogs/dialog-04.tsx",
          "type": "registry:component",
          "target": "components/dialog-04.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { useState } from \"react\";\n\nexport default function Dialog03() {\n  const [isOpen, setIsOpen] = useState(true);\n\n  return (\n    <Dialog open={isOpen} onOpenChange={setIsOpen}>\n      <div className=\"flex items-center justify-center py-36\">\n        <DialogTrigger asChild>\n          <Button>Edit Profile</Button>\n        </DialogTrigger>\n      </div>\n\n      <DialogContent className=\"sm:max-w-md\">\n        <DialogHeader>\n          <DialogTitle>Edit Profile</DialogTitle>\n          <DialogDescription>\n            Make changes to your profile here. Click save when you&apos;re done.\n          </DialogDescription>\n        </DialogHeader>\n        <div className=\"space-y-2\">\n          <Label htmlFor=\"username\" className=\"text-sm font-medium\">\n            Username\n          </Label>\n          <Input\n            id=\"username\"\n            name=\"username\"\n            type=\"text\"\n            placeholder=\"Your username\"\n          />\n        </div>\n        <DialogFooter>\n          <Button type=\"submit\" className=\"w-full\">\n            Save Changes\n          </Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-05",
      "type": "registry:block",
      "title": "Dialog with Password Confirmation",
      "description": "A dialog with password confirmation block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "alert-dialog",
        "button",
        "input",
        "label"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-05.tsx",
          "type": "registry:component",
          "target": "components/dialog-05.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  AlertDialog,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { EyeIcon, EyeOffIcon } from \"lucide-react\";\nimport { useState, type FormEvent } from \"react\";\n\nexport default function Dialog05() {\n  const [isOpen, setIsOpen] = useState(true);\n  const [isVisible, setIsVisible] = useState<boolean>(false);\n\n  const toggleVisibility = () => setIsVisible((prevState) => !prevState);\n  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n    event.preventDefault();\n    setIsOpen(false);\n  };\n\n  return (\n    <AlertDialog open={isOpen} onOpenChange={setIsOpen}>\n      <AlertDialogTrigger asChild>\n        <Button variant=\"destructive\">Delete Workspace</Button>\n      </AlertDialogTrigger>\n      <AlertDialogContent className=\"sm:max-w-md\">\n        <AlertDialogHeader>\n          <AlertDialogTitle className=\"text-balance\">Delete workspace</AlertDialogTitle>\n          <AlertDialogDescription className=\"text-pretty\">\n            All workspace data will be permanently deleted. There is no coming\n            back after you press delete.\n          </AlertDialogDescription>\n        </AlertDialogHeader>\n        <form onSubmit={handleSubmit}>\n          <div>\n            <Label htmlFor=\"delete-workspace\" className=\"text-sm font-medium\">\n              Confirm password\n            </Label>\n            <div className=\"relative mt-2\">\n              <Input\n                id=\"delete-workspace\"\n                name=\"delete-workspace\"\n                type={isVisible ? \"text\" : \"password\"}\n                placeholder=\"Password\"\n                className=\"pe-9\"\n                required\n              />\n              <button\n                className=\"absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md\"\n                type=\"button\"\n                onClick={toggleVisibility}\n                aria-label={isVisible ? \"Hide password\" : \"Show password\"}\n                aria-pressed={isVisible}\n                aria-controls=\"delete-workspace\"\n              >\n                {isVisible ? (\n                  <EyeOffIcon size={16} aria-hidden=\"true\" />\n                ) : (\n                  <EyeIcon size={16} aria-hidden=\"true\" />\n                )}\n              </button>\n            </div>\n          </div>\n          <AlertDialogFooter className=\"mt-4\">\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <Button type=\"submit\" variant=\"destructive\">\n              Delete workspace permanently\n            </Button>\n          </AlertDialogFooter>\n        </form>\n      </AlertDialogContent>\n    </AlertDialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-06",
      "type": "registry:block",
      "title": "Dialog with Privacy Toggle",
      "description": "A dialog with privacy toggle block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dialog",
        "input",
        "label",
        "switch"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/dialogs/dialog-06.tsx",
          "type": "registry:component",
          "target": "components/dialog-06.tsx",
          "content": "\"use client\";\n\nimport { useState } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Switch } from \"@/components/ui/switch\";\n\nexport default function Dialog06() {\n  const [open, setOpen] = useState(true);\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button onClick={() => setOpen(true)}>Create Workspace</Button>\n      </DialogTrigger>\n      <DialogContent className=\"p-0 sm:max-w-lg\">\n        <DialogHeader className=\"px-6 pt-4\">\n          <DialogTitle className=\"text-balance text-lg font-semibold text-foreground\">\n            Create workspace\n          </DialogTitle>\n          <DialogDescription className=\"text-pretty mt-2 text-sm leading-6 text-muted-foreground\">\n            Workspaces are shared environments where teams can connect to data\n            sources, run queries and create reports.\n          </DialogDescription>\n        </DialogHeader>\n\n        <form action=\"#\" method=\"POST\">\n          <div className=\"px-6 pb-4\">\n            <Label htmlFor=\"workspace-name\" className=\"text-sm font-medium\">\n              Workspace Name<span className=\"text-destructive\">*</span>\n            </Label>\n            <Input\n              type=\"text\"\n              id=\"workspace-name\"\n              name=\"workspace-name\"\n              placeholder=\"My workspace\"\n              className=\"mt-2\"\n              required\n            />\n            <Button type=\"submit\" className=\"mt-4 w-full\">\n              Create workspace\n            </Button>\n          </div>\n          <div className=\"border-t bg-muted rounded-b-md px-6 py-4\">\n            <div className=\"flex items-start space-x-3\">\n              <div className=\"mt-1 pt-0.5\">\n                <Switch\n                  id=\"enable-private-workspace\"\n                  name=\"enable-private-workspace\"\n                />\n              </div>\n              <div>\n                <Label\n                  htmlFor=\"enable-private-workspace\"\n                  className=\"text-sm font-medium\"\n                >\n                  Set workspace to private\n                </Label>\n                <p className=\"text-pretty text-sm text-muted-foreground\">\n                  Only those invited can access or view\n                </p>\n              </div>\n            </div>\n          </div>\n        </form>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-07",
      "type": "registry:block",
      "title": "Dialog with Member List",
      "description": "A dialog with member list block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "alert-dialog",
        "button",
        "input",
        "label"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-07.tsx",
          "type": "registry:component",
          "target": "components/dialog-07.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  AlertDialog,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { EyeIcon, EyeOffIcon } from \"lucide-react\";\nimport { useState, type FormEvent } from \"react\";\n\nexport default function Dialog08() {\n  const [open, setOpen] = useState(true);\n  const [isVisible, setIsVisible] = useState<boolean>(false);\n\n  const toggleVisibility = () => setIsVisible((prevState) => !prevState);\n  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n    event.preventDefault();\n    setOpen(false);\n  };\n\n  return (\n    <AlertDialog open={open} onOpenChange={setOpen}>\n      <AlertDialogTrigger asChild>\n        <Button variant=\"destructive\">Deactivate 2FA</Button>\n      </AlertDialogTrigger>\n      <AlertDialogContent className=\"sm:max-w-lg\">\n        <AlertDialogHeader>\n          <AlertDialogTitle className=\"text-balance\">Deactivate two-step authentication</AlertDialogTitle>\n          <AlertDialogDescription className=\"text-pretty\">\n            Enter your password to deactivate the two-step authentication login.\n            Make sure to have your smartphone ready.\n          </AlertDialogDescription>\n        </AlertDialogHeader>\n        <form className=\"space-y-4\" onSubmit={handleSubmit}>\n          <div>\n            <Label htmlFor=\"email\" className=\"text-sm font-medium\">\n              Email\n            </Label>\n            <Input\n              id=\"email\"\n              name=\"email\"\n              type=\"email\"\n              placeholder=\"ephraim@blocks.so\"\n              className=\"mt-2\"\n              disabled\n            />\n          </div>\n          <div>\n            <Label htmlFor=\"password\" className=\"text-sm font-medium\">\n              Confirm password\n            </Label>\n            <div className=\"relative mt-2\">\n              <Input\n                id=\"password\"\n                name=\"password\"\n                type={isVisible ? \"text\" : \"password\"}\n                placeholder=\"Password\"\n                className=\"pe-9\"\n                required\n              />\n              <button\n                className=\"absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md\"\n                type=\"button\"\n                onClick={toggleVisibility}\n                aria-label={isVisible ? \"Hide password\" : \"Show password\"}\n                aria-pressed={isVisible}\n                aria-controls=\"password\"\n              >\n                {isVisible ? (\n                  <EyeOffIcon size={16} aria-hidden=\"true\" />\n                ) : (\n                  <EyeIcon size={16} aria-hidden=\"true\" />\n                )}\n              </button>\n            </div>\n          </div>\n\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <Button type=\"submit\" variant=\"destructive\">\n              Deactivate\n            </Button>\n          </AlertDialogFooter>\n        </form>\n      </AlertDialogContent>\n    </AlertDialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-08",
      "type": "registry:block",
      "title": "Dialog with Email and Password Fields",
      "description": "A dialog with email and password fields block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "badge",
        "button",
        "dialog",
        "input"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-08.tsx",
          "type": "registry:component",
          "target": "components/dialog-08.tsx",
          "content": "\"use client\";\n\nimport { UserPlus } from \"lucide-react\";\nimport { useState } from \"react\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\n\nconst members = [\n  {\n    name: \"Ephraim Duncan\",\n    email: \"ephraim@documenso.com\",\n    avatarUrl: \"https://blocks.so/avatar-01.png\",\n    initials: \"ED\",\n    status: \"member\",\n  },\n  {\n    name: \"Lucas Smith\",\n    email: \"lucas@documenso.com\",\n    avatarUrl: \"https://blocks.so/avatar-03.png\",\n    initials: \"LS\",\n    status: \"member\",\n  },\n  {\n    name: \"Timur Ercan\",\n    email: \"timur@documenso.com\",\n    avatarUrl: \"https://blocks.so/avatar-02.jpg\",\n    initials: \"TE\",\n    status: \"member\",\n  },\n  {\n    name: \"Catalin Pit\",\n    email: \"catalin@documenso.com\",\n    avatarUrl: \"https://blocks.so/avatar-04.jpg\",\n    initials: \"CP\",\n    status: \"member\",\n  },\n];\n\nexport default function Dialog07() {\n  const [open, setOpen] = useState(true);\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button onClick={() => setOpen(true)}>Invite members</Button>\n      </DialogTrigger>\n      <DialogContent className=\"sm:max-w-2xl\">\n        <DialogHeader>\n          <DialogTitle className=\"text-balance font-semibold text-foreground\">\n            Invite members\n          </DialogTitle>\n          <DialogDescription className=\"text-pretty text-sm leading-6 text-muted-foreground\">\n            Add new team members to your workspace. Please consider your\n            organization&apos;s policies when adding external people.\n          </DialogDescription>\n        </DialogHeader>\n        <form>\n          <div className=\"flex w-full items-center space-x-2\">\n            <div className=\"relative flex-1\">\n              <UserPlus className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n              <Input\n                id=\"inviteEmail\"\n                className=\"h-10 pl-9\"\n                placeholder=\"Add email...\"\n                type=\"email\"\n              />\n            </div>\n            <Button type=\"submit\" className=\"h-10\">\n              Invite\n            </Button>\n          </div>\n        </form>\n        <h4 className=\"text-balance mt-4 text-sm font-medium text-foreground\">\n          People with existing access\n        </h4>\n        <ul className=\"divide-y\">\n          {members.map((member) => (\n            <li\n              key={member.name}\n              className=\"flex items-center justify-between py-2.5\"\n            >\n              <div className=\"flex items-center space-x-3\">\n                <Avatar className=\"h-9 w-9\">\n                  <AvatarImage src={member.avatarUrl} alt={member.name} />\n                  <AvatarFallback>{member.initials}</AvatarFallback>\n                </Avatar>\n                <span className=\"font-medium text-foreground\">\n                  {member.name}\n                </span>\n              </div>\n              <Badge\n                variant=\"outline\"\n                className=\"bg-background text-xs font-medium\"\n              >\n                {member.status}\n              </Badge>\n            </li>\n          ))}\n        </ul>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-09",
      "type": "registry:block",
      "title": "Dialog with Link Share and Toggles",
      "description": "A dialog with link share and toggles block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dialog",
        "input",
        "label",
        "switch",
        "tooltip"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-09.tsx",
          "type": "registry:component",
          "target": "components/dialog-09.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Switch } from \"@/components/ui/switch\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\nimport { CheckIcon, CopyIcon, ExternalLink, Link, Share2 } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\n\nexport default function Dialog09() {\n  const [open, setOpen] = useState<boolean>(true);\n  const [copied, setCopied] = useState<boolean>(false);\n  const inputRef = useRef<HTMLInputElement>(null);\n\n  const handleCopy = () => {\n    if (inputRef.current) {\n      navigator.clipboard.writeText(inputRef.current.value);\n      setCopied(true);\n      setTimeout(() => setCopied(false), 1500);\n    }\n  };\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button>\n          <Share2 className=\"mr-2 h-4 w-4\" />\n          Share\n        </Button>\n      </DialogTrigger>\n      <DialogContent className=\"sm:max-w-md\">\n        <DialogHeader>\n          <DialogTitle>Share & Collaborate</DialogTitle>\n          <p className=\"text-pretty text-sm text-muted-foreground\">\n            Share this project with your team to collaborate on it.\n          </p>\n        </DialogHeader>\n        <div className=\"space-y-4 py-4\">\n          <div className=\"flex items-center justify-between space-x-2\">\n            <div className=\"flex items-center space-x-2\">\n              <span>Enable comments and suggestions</span>\n            </div>\n            <Switch id=\"comments\" />\n          </div>\n\n          <div className=\"space-y-1.5\">\n            <Label htmlFor=\"share-link\" className=\"sr-only\">\n              Share Link\n            </Label>\n            <div className=\"relative\">\n              <Input\n                ref={inputRef}\n                id=\"share-link\"\n                readOnly\n                value=\"https://writer.so/app/projects/123?share=true\"\n                className=\"pe-9\"\n              />\n              <TooltipProvider delayDuration={0}>\n                <Tooltip>\n                  <TooltipTrigger asChild>\n                    <button\n                      onClick={handleCopy}\n                      className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed\"\n                      aria-label={copied ? \"Copied\" : \"Copy to clipboard\"}\n                      disabled={copied}\n                    >\n                      <div\n                        className={cn(\n                          \"transition-[transform,opacity] duration-200 ease-out\",\n                          copied ? \"scale-100 opacity-100\" : \"scale-0 opacity-0\"\n                        )}\n                      >\n                        <CheckIcon\n                          className=\"text-primary\"\n                          size={16}\n                          aria-hidden=\"true\"\n                        />\n                      </div>\n                      <div\n                        className={cn(\n                          \"absolute transition-[transform,opacity] duration-200 ease-out\",\n                          copied ? \"scale-0 opacity-0\" : \"scale-100 opacity-100\"\n                        )}\n                      >\n                        <CopyIcon size={16} aria-hidden=\"true\" />\n                      </div>\n                    </button>\n                  </TooltipTrigger>\n                  <TooltipContent className=\"px-2 py-1 text-xs\">\n                    {copied ? \"Copied!\" : \"Copy to clipboard\"}\n                  </TooltipContent>\n                </Tooltip>\n              </TooltipProvider>\n            </div>\n          </div>\n\n          <div className=\"flex space-x-2\">\n            <Button className=\"flex-1 gap-2\" onClick={handleCopy}>\n              <Link className=\"h-4 w-4\" />\n              Copy Link\n            </Button>\n            <Button variant=\"outline\" className=\"flex-1 gap-2\">\n              <ExternalLink className=\"h-4 w-4\" />\n              Preview\n            </Button>\n          </div>\n        </div>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-10",
      "type": "registry:block",
      "title": "Dialog with Calendar and Time Picker",
      "description": "A dialog with calendar and time picker block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "calendar",
        "dialog",
        "input",
        "label",
        "popover",
        "select",
        "textarea"
      ],
      "dependencies": [
        "date-fns",
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-10.tsx",
          "type": "registry:component",
          "target": "components/dialog-10.tsx",
          "content": "\"use client\";\n\nimport { format } from \"date-fns\";\nimport { CalendarIcon } from \"lucide-react\";\nimport { useMemo, useState } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Calendar } from \"@/components/ui/calendar\";\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { cn } from \"@/lib/utils\";\n\nexport default function Dialog10() {\n  const [open, setOpen] = useState(true);\n  const [date, setDate] = useState<Date | undefined>(new Date());\n  const [startTime, setStartTime] = useState(\"09:00\");\n\n  const timeOptions = useMemo(() => {\n    const options = [];\n    for (let hour = 0; hour <= 23; hour++) {\n      for (let minute = 0; minute < 60; minute += 30) {\n        const formattedHour = hour.toString().padStart(2, \"0\");\n        const formattedMinute = minute.toString().padStart(2, \"0\");\n        const value = `${formattedHour}:${formattedMinute}`;\n        const tempDate = new Date(2000, 0, 1, hour, minute);\n        const label = format(tempDate, \"h:mm a\");\n        options.push({ value, label });\n      }\n    }\n\n    if (!options.find((opt) => opt.value === \"23:59\")) {\n      const endOfDay = new Date(2000, 0, 1, 23, 59);\n      options.push({ value: \"23:59\", label: format(endOfDay, \"h:mm a\") });\n    }\n\n    return options;\n  }, []);\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button>Show dialog</Button>\n      </DialogTrigger>\n      <DialogContent className=\"p-0 sm:max-w-lg gap-0\">\n        <DialogHeader className=\"border-b px-6 py-4 pt-5\">\n          <DialogTitle>Schedule a Meeting</DialogTitle>\n        </DialogHeader>\n\n        <form action=\"#\" method=\"POST\">\n          <div className=\"space-y-6 p-6\">\n            <div className=\"space-y-2\">\n              <Label htmlFor=\"title\">Meeting Title</Label>\n              <Input\n                id=\"title\"\n                name=\"title\"\n                placeholder=\"e.g., Project Kickoff\"\n              />\n            </div>\n\n            <div className=\"space-y-2\">\n              <Label htmlFor=\"attendees\">Attendees</Label>\n              <Input\n                id=\"attendees\"\n                name=\"attendees\"\n                placeholder=\"user1@example.com, user2@example.com\"\n              />\n              <p className=\"text-pretty text-xs text-muted-foreground\">\n                Enter email addresses separated by commas.\n              </p>\n            </div>\n\n            <div className=\"grid grid-cols-3 gap-4\">\n              <div className=\"space-y-2 col-span-2\">\n                <Label htmlFor=\"date\">Date</Label>\n                <Popover>\n                  <PopoverTrigger asChild>\n                    <Button\n                      id=\"date\"\n                      variant={\"outline\"}\n                      className={cn(\n                        \"w-full justify-start text-left font-normal\",\n                        !date && \"text-muted-foreground\"\n                      )}\n                    >\n                      <CalendarIcon className=\"mr-1 h-4 w-4 shrink-0\" />{\" \"}\n                      {date ? format(date, \"PPP\") : <span>Pick a date</span>}\n                    </Button>\n                  </PopoverTrigger>\n                  <PopoverContent className=\"w-auto p-0\" align=\"start\">\n                    <Calendar\n                      mode=\"single\"\n                      selected={date}\n                      onSelect={setDate}\n                      initialFocus\n                    />\n                  </PopoverContent>\n                </Popover>\n              </div>\n\n              <div className=\"space-y-2\">\n                <Label htmlFor=\"time\">Time</Label>\n                <Select value={startTime} onValueChange={setStartTime}>\n                  <SelectTrigger id=\"time\" className=\"w-full\">\n                    <SelectValue placeholder=\"Select time\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    {timeOptions.map((option) => (\n                      <SelectItem key={option.value} value={option.value}>\n                        {option.label}\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n\n            <div className=\"space-y-2\">\n              <Label htmlFor=\"location\">Location / Conference Link</Label>\n              <Input\n                id=\"location\"\n                name=\"location\"\n                placeholder=\"e.g., Conference Room B or https://meet.example.com/...\"\n              />\n            </div>\n\n            <div className=\"space-y-2\">\n              <Label htmlFor=\"description\">Description</Label>\n              <Textarea\n                id=\"description\"\n                name=\"description\"\n                placeholder=\"Optional: Add an agenda or notes...\"\n                className=\"min-h-[100px]\"\n              />\n            </div>\n          </div>\n\n          <div className=\"flex items-center justify-end border-t p-4 space-x-2\">\n            <DialogClose asChild>\n              <Button type=\"button\" variant=\"ghost\">\n                Cancel\n              </Button>\n            </DialogClose>\n            <Button type=\"submit\" size=\"sm\">\n              Schedule\n            </Button>\n          </div>\n        </form>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-11",
      "type": "registry:block",
      "title": "Dialog Multi-Step Wizard",
      "description": "A dialog multi-step wizard block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "dialog",
        "label",
        "select",
        "separator"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-11.tsx",
          "type": "registry:component",
          "target": "components/dialog-11.tsx",
          "content": "\"use client\";\n\nimport { AppWindowIcon as Apps } from \"lucide-react\";\nimport { useState } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { Separator } from \"@/components/ui/separator\";\n\nexport default function Dialog11() {\n  const [open, setOpen] = useState(true);\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button>Initialize New Project</Button>\n      </DialogTrigger>\n      <DialogContent className=\"overflow-visible p-0 sm:max-w-2xl gap-0\">\n        <DialogHeader className=\"border-b px-6 py-4 mb-0\">\n          <DialogTitle>Initialize New Project</DialogTitle>\n        </DialogHeader>\n\n        <form action=\"#\" method=\"POST\">\n          <div className=\"flex flex-col-reverse md:flex-row\">\n            <div className=\"flex flex-col justify-between md:w-80 md:border-r\">\n              <div className=\"flex-1 grow\">\n                <div className=\"border-t p-6 md:border-none\">\n                  <div className=\"flex items-center space-x-3\">\n                    <div className=\"inline-flex shrink-0 items-center justify-center rounded-sm bg-muted p-3\">\n                      <Apps\n                        className=\"size-5 text-foreground\"\n                        aria-hidden={true}\n                      />\n                    </div>\n                    <div className=\"space-y-0.5\">\n                      <h3 className=\"text-balance text-sm font-medium text-foreground\">\n                        Project Starter\n                      </h3>\n                      <p className=\"text-pretty text-sm text-muted-foreground\">\n                        Configure your new codebase\n                      </p>\n                    </div>\n                  </div>\n                  <Separator className=\"my-4\" />\n                  <h4 className=\"text-balance text-sm font-medium text-foreground\">\n                    Description\n                  </h4>\n                  <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground\">\n                    Quickly set up the foundational tools for your project.\n                  </p>\n                  <h4 className=\"text-balance mt-6 text-sm font-medium text-foreground\">\n                    Info\n                  </h4>\n                  <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground\">\n                    Select your preferred stack and configurations.\n                  </p>\n                </div>\n              </div>\n              <div className=\"flex items-center justify-between border-t p-4\">\n                <DialogClose asChild>\n                  <Button type=\"button\" variant=\"ghost\">\n                    Cancel\n                  </Button>\n                </DialogClose>\n                <Button type=\"submit\" size=\"sm\">\n                  Initialize\n                </Button>\n              </div>\n            </div>\n\n            <div className=\"flex-1 space-y-6 p-6 md:px-6 md:pb-8 md:pt-6\">\n              <div className=\"space-y-2\">\n                <div className=\"flex items-center space-x-3\">\n                  <div className=\"inline-flex size-6 items-center justify-center rounded-sm bg-muted text-sm text-foreground\">\n                    1\n                  </div>\n                  <Label\n                    htmlFor=\"framework\"\n                    className=\"text-sm font-medium text-foreground\"\n                  >\n                    Select Framework\n                  </Label>\n                </div>\n                <Select defaultValue=\"react\">\n                  <SelectTrigger\n                    id=\"framework\"\n                    name=\"framework\"\n                    className=\"w-full\"\n                  >\n                    <SelectValue placeholder=\"Select framework\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"react\">Next.js</SelectItem>\n                    <SelectItem value=\"vue\">React Router</SelectItem>\n                    <SelectItem value=\"angular\">Tanstack Start</SelectItem>\n                    <SelectItem value=\"svelte\">SvelteKit</SelectItem>\n                    <SelectItem value=\"vanilla\">SolidStart</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n              <div className=\"space-y-2\">\n                <div className=\"flex items-center space-x-3\">\n                  <div className=\"inline-flex size-6 items-center justify-center rounded-sm bg-muted text-sm text-foreground\">\n                    2\n                  </div>\n                  <Label\n                    htmlFor=\"package-manager\"\n                    className=\"text-sm font-medium text-foreground\"\n                  >\n                    Choose Package Manager\n                  </Label>\n                </div>\n                <Select defaultValue=\"npm\">\n                  <SelectTrigger\n                    id=\"package-manager\"\n                    name=\"package-manager\"\n                    className=\"w-full\"\n                  >\n                    <SelectValue placeholder=\"Select manager\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"npm\">npm</SelectItem>\n                    <SelectItem value=\"yarn\">yarn</SelectItem>\n                    <SelectItem value=\"pnpm\">pnpm</SelectItem>\n                    <SelectItem value=\"bun\">bun</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n              <div>\n                <div className=\"flex items-center space-x-3\">\n                  <div className=\"inline-flex size-6 items-center justify-center rounded-sm bg-muted text-sm text-foreground\">\n                    3\n                  </div>\n                  <Label\n                    htmlFor=\"linter\"\n                    className=\"text-sm font-medium text-foreground\"\n                  >\n                    Configure Linter/Formatter\n                  </Label>\n                </div>\n                <p className=\"text-pretty mt-1 text-xs text-muted-foreground\">\n                  Ensure code quality and consistency.\n                </p>\n                <Select defaultValue=\"eslint-prettier\">\n                  <SelectTrigger\n                    id=\"linter\"\n                    name=\"linter\"\n                    className=\"mt-4 w-full\"\n                  >\n                    <SelectValue placeholder=\"Select tools\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"eslint-prettier\">\n                      ESLint + Prettier\n                    </SelectItem>\n                    <SelectItem value=\"eslint\">ESLint Only</SelectItem>\n                    <SelectItem value=\"prettier\">Prettier Only</SelectItem>\n                    <SelectItem value=\"biome\">Biome</SelectItem>\n                    <SelectItem value=\"oxlint\">Oxlint</SelectItem>\n                    <SelectItem value=\"none\">None</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n              <div>\n                <div className=\"flex items-center space-x-3\">\n                  <div className=\"inline-flex size-6 items-center justify-center rounded-sm bg-muted text-sm text-foreground\">\n                    4\n                  </div>\n                  <Label\n                    htmlFor=\"testing-tool\"\n                    className=\"text-sm font-medium text-foreground\"\n                  >\n                    Select Testing Tool\n                  </Label>\n                </div>\n                <p className=\"text-pretty mt-1 text-xs text-muted-foreground\">\n                  Choose a framework for unit/integration tests.\n                </p>\n                <Select defaultValue=\"jest\">\n                  <SelectTrigger\n                    id=\"testing-tool\"\n                    name=\"testing-tool\"\n                    className=\"mt-4 w-full\"\n                  >\n                    <SelectValue placeholder=\"Select tool\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"jest\">Jest</SelectItem>\n                    <SelectItem value=\"vitest\">Vitest</SelectItem>\n                    <SelectItem value=\"cypress\">Cypress</SelectItem>\n                    <SelectItem value=\"none\">None</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n          </div>\n        </form>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "dialog-12",
      "type": "registry:block",
      "title": "Dialog with Avatar Upload",
      "description": "A dialog with avatar upload block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "button",
        "dialog",
        "input",
        "label"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/dialogs/dialog-12.tsx",
          "type": "registry:component",
          "target": "components/dialog-12.tsx",
          "content": "\"use client\";\n\nimport { Plus, UserRoundIcon, X } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\n\nexport default function Dialog12() {\n  const [open, setOpen] = useState(true);\n  const [authorName, setAuthorName] = useState(\"Ephraim Duncan\");\n  const [title, setTitle] = useState(\"Design Engineer\");\n  const [image, setImage] = useState<string | null>(null);\n  const fileInputRef = useRef<HTMLInputElement>(null);\n\n  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const file = e.target.files?.[0];\n    if (file) {\n      if (file.size > 1048576) {\n        alert(\"File size exceeds 1MB limit\");\n        return;\n      }\n\n      const reader = new FileReader();\n      reader.onload = (event) => {\n        setImage(event.target?.result as string);\n      };\n      reader.readAsDataURL(file);\n    }\n  };\n\n  const triggerFileInput = () => {\n    fileInputRef.current?.click();\n  };\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button>Open Dialog</Button>\n      </DialogTrigger>\n      <DialogContent className=\"sm:max-w-lg p-0 rounded-3xl gap-0\">\n        <DialogHeader className=\"border-b px-6 py-4\">\n          <DialogTitle className=\"text-balance font-medium\">Add a writer</DialogTitle>\n        </DialogHeader>\n\n        <div className=\"grid grid-cols-1 md:grid-cols-5 px-6 pt-4 pb-6\">\n          <div className=\"flex flex-col items-center justify-center  md:col-span-2\">\n            <div className=\"relative mb-2\">\n              <Avatar className=\"h-24 w-24 border-2 border-muted\">\n                <AvatarImage src={image || undefined} alt=\"Profile\" />\n                <AvatarFallback>\n                  <UserRoundIcon\n                    size={52}\n                    className=\"text-muted-foreground\"\n                    aria-hidden=\"true\"\n                  />\n                </AvatarFallback>\n              </Avatar>\n              <Button\n                variant=\"ghost\"\n                size=\"icon-sm\"\n                className=\"absolute -top-0.5 -right-0.5 bg-accent rounded-full border-[3px] border-background hover:bg-accent\"\n                onClick={() => {\n                  if (image) {\n                    setImage(null);\n                    if (fileInputRef.current) {\n                      fileInputRef.current.value = \"\";\n                    }\n                  } else {\n                    triggerFileInput();\n                  }\n                }}\n              >\n                {image ? (\n                  <X className=\"h-4 w-4 text-muted-foreground\" />\n                ) : (\n                  <Plus className=\"h-3 w-3 text-muted-foreground\" />\n                )}\n                <span className=\"sr-only\">\n                  {image ? \"Remove image\" : \"Upload image\"}\n                </span>\n              </Button>\n            </div>\n\n            <p className=\"text-pretty text-center font-medium\">Upload Image</p>\n            <p className=\"text-pretty text-center text-sm text-muted-foreground\">\n              Max file size: 1MB\n            </p>\n            <input\n              type=\"file\"\n              ref={fileInputRef}\n              onChange={handleFileChange}\n              accept=\"image/*\"\n              className=\"hidden\"\n            />\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              className=\"mt-2\"\n              onClick={triggerFileInput}\n            >\n              Add Image\n            </Button>\n          </div>\n\n          <div className=\"flex flex-col justify-between md:col-span-3\">\n            <div className=\"space-y-4\">\n              <div className=\"space-y-1\">\n                <Label htmlFor=\"author-name\" className=\"flex items-center\">\n                  Author name <span className=\"text-primary\">*</span>\n                </Label>\n                <Input\n                  id=\"author-name\"\n                  value={authorName}\n                  onChange={(e) => setAuthorName(e.target.value)}\n                  required\n                />\n              </div>\n\n              <div className=\"space-y-1\">\n                <div className=\"flex items-center\">\n                  <Label htmlFor=\"title\">Title</Label>\n                </div>\n                <Input\n                  id=\"title\"\n                  value={title}\n                  onChange={(e) => setTitle(e.target.value)}\n                />\n              </div>\n            </div>\n\n            <div className=\"flex justify-end gap-2\">\n              <Button variant=\"outline\" onClick={() => setOpen(false)}>\n                Cancel\n              </Button>\n              <Button className=\"bg-foreground text-background hover:bg-foreground/90\">\n                Save Changes\n              </Button>\n            </div>\n          </div>\n        </div>\n      </DialogContent>\n    </Dialog>\n  );\n}\n"
        }
      ],
      "categories": [
        "dialogs"
      ]
    },
    {
      "name": "file-upload-01",
      "type": "registry:block",
      "title": "File Upload with Preview",
      "description": "A file upload with preview block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "input",
        "label",
        "select",
        "tooltip"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/file-upload/file-upload-01/dropzone.tsx",
          "type": "registry:component",
          "target": "components/file-upload-01/dropzone.tsx",
          "content": "import { Upload } from \"lucide-react\";\nimport React, { RefObject } from \"react\";\n\ninterface FileDropzoneProps {\n  fileInputRef: RefObject<HTMLInputElement | null>;\n  handleBoxClick: () => void;\n  handleDragOver: (e: React.DragEvent) => void;\n  handleDrop: (e: React.DragEvent) => void;\n  handleFileSelect: (files: FileList | null) => void;\n}\n\nexport function FileDropzone({\n  fileInputRef,\n  handleBoxClick,\n  handleDragOver,\n  handleDrop,\n  handleFileSelect,\n}: FileDropzoneProps) {\n  return (\n    <div className=\"px-6\">\n      <div\n        className=\"border-2 border-dashed border-border rounded-md p-8 flex flex-col items-center justify-center text-center cursor-pointer\"\n        onClick={handleBoxClick}\n        onDragOver={handleDragOver}\n        onDrop={handleDrop}\n      >\n        <div className=\"mb-2 bg-muted rounded-full p-3\">\n          <Upload className=\"h-5 w-5 text-muted-foreground\" />\n        </div>\n        <p className=\"text-sm font-medium text-foreground\">\n          Upload a project image\n        </p>\n        <p className=\"text-sm text-muted-foreground mt-1\">\n          or,{\" \"}\n          <label\n            htmlFor=\"fileUpload\"\n            className=\"text-primary hover:text-primary/90 font-medium cursor-pointer\"\n            onClick={(e) => e.stopPropagation()} // Prevent triggering handleBoxClick\n          >\n            click to browse\n          </label>{\" \"}\n          (4MB max)\n        </p>\n        <input\n          type=\"file\"\n          id=\"fileUpload\"\n          ref={fileInputRef}\n          className=\"hidden\"\n          accept=\"image/*\"\n          onChange={(e) => handleFileSelect(e.target.files)}\n        />\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "content/components/file-upload/file-upload-01/form.tsx",
          "type": "registry:component",
          "target": "components/file-upload-01/form.tsx",
          "content": "import { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\n\nexport function Form() {\n  return (\n    <div className=\"px-6 pb-4 mt-2\">\n      <div className=\"grid grid-cols-2 gap-4\">\n        <div>\n          <Label htmlFor=\"projectName\" className=\"mb-2\">\n            Project name\n          </Label>\n          <Input\n            id=\"projectName\"\n            type=\"text\"\n            defaultValue=\"Open Source Stripe\"\n          />\n        </div>\n\n        <div>\n          <Label htmlFor=\"projectLead\" className=\"mb-2\">\n            Project lead\n          </Label>\n          <Select defaultValue=\"1\">\n            <SelectTrigger id=\"projectLead\" className=\"ps-2\">\n              <SelectValue placeholder=\"Select framework\" />\n            </SelectTrigger>\n            <SelectContent>\n              <SelectGroup>\n                <SelectItem value=\"1\">\n                  <img\n                    className=\"size-5 rounded\"\n                    src=\"https://blocks.so/avatar-01.png\"\n                    alt=\"Ephraim Duncan\"\n                    width={20}\n                    height={20}\n                  />\n                  <span className=\"truncate\">Ephraim Duncan</span>\n                </SelectItem>\n                <SelectItem value=\"2\">\n                  <img\n                    className=\"size-5 rounded\"\n                    src=\"https://blocks.so/avatar-03.png\"\n                    alt=\"Lucas Smith\"\n                    width={20}\n                    height={20}\n                  />\n                  <span className=\"truncate\">Lucas Smith</span>\n                </SelectItem>\n                <SelectItem value=\"3\">\n                  <img\n                    className=\"size-5 rounded\"\n                    src=\"https://blocks.so/avatar-02.jpg\"\n                    alt=\"Timur Ercan\"\n                    width={20}\n                    height={20}\n                  />\n                  <span className=\"truncate\">Timur Ercan</span>\n                </SelectItem>\n              </SelectGroup>\n            </SelectContent>\n          </Select>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "content/components/file-upload/file-upload-01/index.tsx",
          "type": "registry:component",
          "target": "components/file-upload-01/index.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { HelpCircle } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\nimport { FileDropzone } from \"@/components/file-upload-01/dropzone\";\nimport { FileList } from \"@/components/file-upload-01/file-list\";\nimport { Form } from \"@/components/file-upload-01/form\";\n\nexport default function FileUpload01() {\n  const fileInputRef = useRef<HTMLInputElement>(null);\n  const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);\n  const [fileProgresses, setFileProgresses] = useState<Record<string, number>>(\n    {}\n  );\n\n  const handleFileSelect = (files: FileList | null) => {\n    if (!files) return;\n\n    const newFiles = Array.from(files);\n    setUploadedFiles((prev) => [...prev, ...newFiles]);\n\n    newFiles.forEach((file) => {\n      let progress = 0;\n      const interval = setInterval(() => {\n        progress += Math.random() * 10;\n        if (progress >= 100) {\n          progress = 100;\n          clearInterval(interval);\n        }\n        setFileProgresses((prev) => ({\n          ...prev,\n          [file.name]: Math.min(progress, 100),\n        }));\n      }, 300);\n    });\n  };\n\n  const handleBoxClick = () => {\n    fileInputRef.current?.click();\n  };\n\n  const handleDragOver = (e: React.DragEvent) => {\n    e.preventDefault();\n  };\n\n  const handleDrop = (e: React.DragEvent) => {\n    e.preventDefault();\n    handleFileSelect(e.dataTransfer.files);\n  };\n\n  const removeFile = (filename: string) => {\n    setUploadedFiles((prev) => prev.filter((file) => file.name !== filename));\n    setFileProgresses((prev) => {\n      const newProgresses = { ...prev };\n      delete newProgresses[filename];\n      return newProgresses;\n    });\n  };\n\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <Card className=\"w-full mx-auto max-w-lg bg-background rounded-lg p-0 shadow-md\">\n        <CardContent className=\"p-0\">\n          <div className=\"p-6 pb-4\">\n            <div className=\"flex justify-between items-start\">\n              <div>\n                <h2 className=\"text-lg font-medium text-foreground\">\n                  Create a new project\n                </h2>\n                <p className=\"text-sm text-muted-foreground mt-1\">\n                  Drag and drop files to create a new project.\n                </p>\n              </div>\n            </div>\n          </div>\n          <Form />\n          <FileDropzone\n            fileInputRef={fileInputRef}\n            handleBoxClick={handleBoxClick}\n            handleDragOver={handleDragOver}\n            handleDrop={handleDrop}\n            handleFileSelect={handleFileSelect}\n          />\n          <FileList\n            uploadedFiles={uploadedFiles}\n            fileProgresses={fileProgresses}\n            removeFile={removeFile}\n          />\n          <div className=\"px-6 py-3 border-t border-border bg-muted rounded-b-lg flex justify-between items-center\">\n            <TooltipProvider delayDuration={0}>\n              <Tooltip>\n                <TooltipTrigger asChild>\n                  <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    className=\"flex items-center text-muted-foreground hover:text-foreground\"\n                  >\n                    <HelpCircle className=\"h-4 w-4 mr-1\" />\n                    Need help?\n                  </Button>\n                </TooltipTrigger>\n                <TooltipContent className=\"py-3 bg-background text-foreground border\">\n                  <div className=\"space-y-1\">\n                    <p className=\"text-[13px] font-medium\">Need assistance?</p>\n                    <p className=\"text-muted-foreground dark:text-muted-background text-xs max-w-[200px]\">\n                      Upload project images by dragging and dropping files or\n                      using the file browser. Supported formats: JPG, PNG, SVG.\n                      Maximum file size: 4MB.\n                    </p>\n                  </div>\n                </TooltipContent>\n              </Tooltip>\n            </TooltipProvider>\n\n            <div className=\"flex gap-2\">\n              <Button\n                variant=\"outline\"\n                className=\"h-9 px-4 text-sm font-medium\"\n              >\n                Cancel\n              </Button>\n              <Button className=\"h-9 px-4 text-sm font-medium\">Continue</Button>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  );\n}\n"
        },
        {
          "path": "content/components/file-upload/file-upload-01/file-list.tsx",
          "type": "registry:component",
          "target": "components/file-upload-01/file-list.tsx",
          "content": "import { cn } from \"@/lib/utils\";\nimport { UploadedFileItem } from \"@/components/file-upload-01/file-item\";\n\ninterface UploadedFileListProps {\n  uploadedFiles: File[];\n  fileProgresses: Record<string, number>;\n  removeFile: (filename: string) => void;\n}\n\nexport function FileList({\n  uploadedFiles,\n  fileProgresses,\n  removeFile,\n}: UploadedFileListProps) {\n  if (uploadedFiles.length === 0) {\n    return null;\n  }\n\n  return (\n    <div className={cn(\"px-6 pb-5 space-y-3 mt-4\")}>\n      {uploadedFiles.map((file, index) => (\n        <UploadedFileItem\n          key={file.name + index}\n          file={file}\n          progress={fileProgresses[file.name] || 0}\n          onRemove={removeFile}\n        />\n      ))}\n    </div>\n  );\n}\n"
        },
        {
          "path": "content/components/file-upload/file-upload-01/file-item.tsx",
          "type": "registry:component",
          "target": "components/file-upload-01/file-item.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Trash2 } from \"lucide-react\";\nimport { useEffect } from \"react\";\n\ninterface UploadedFileItemProps {\n  file: File;\n  progress: number;\n  onRemove: (filename: string) => void;\n}\n\nexport function UploadedFileItem({\n  file,\n  progress,\n  onRemove,\n}: UploadedFileItemProps) {\n  const imageUrl = URL.createObjectURL(file);\n\n  useEffect(() => {\n    return () => URL.revokeObjectURL(imageUrl);\n  }, [imageUrl]);\n\n  return (\n    <div\n      className=\"border border-border rounded-lg p-2 flex flex-col\"\n      key={file.name}\n    >\n      <div className=\"flex items-center gap-2\">\n        <div className=\"w-18 h-14 bg-muted rounded-sm flex items-center justify-center self-start row-span-2 overflow-hidden\">\n          <img\n            src={imageUrl}\n            alt={file.name}\n            className=\"w-full h-full object-cover\"\n          />\n        </div>\n\n        <div className=\"flex-1 pr-1\">\n          <div className=\"flex justify-between items-center\">\n            <div className=\"flex items-center gap-2\">\n              <span className=\"text-sm text-foreground truncate max-w-[250px]\">\n                {file.name}\n              </span>\n              <span className=\"text-sm text-muted-foreground whitespace-nowrap\">\n                {Math.round(file.size / 1024)} KB\n              </span>\n            </div>\n            <Button\n              variant=\"ghost\"\n              size=\"icon-sm\"\n              className=\"bg-transparent! hover:text-red-500\"\n              onClick={() => onRemove(file.name)}\n            >\n              <Trash2 className=\"h-4 w-4\" />\n            </Button>\n          </div>\n\n          <div className=\"flex items-center gap-2\">\n            <div className=\"h-2 bg-muted rounded-full overflow-hidden flex-1\">\n              <div\n                className=\"h-full bg-primary\"\n                style={{\n                  width: `${progress || 0}%`,\n                }}\n              ></div>\n            </div>\n            <span className=\"text-xs text-muted-foreground whitespace-nowrap\">\n              {Math.round(progress || 0)}%\n            </span>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-01",
      "type": "registry:block",
      "title": "File Upload with Preview",
      "description": "A file upload with preview block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "input",
        "label",
        "select",
        "tooltip"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/file-upload/file-upload-01.tsx",
          "type": "registry:component",
          "target": "components/file-upload-01.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\nimport { HelpCircle, Trash2, Upload } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\n\nexport default function FileUpload01() {\n  const fileInputRef = useRef<HTMLInputElement>(null);\n  const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);\n  const [fileProgresses, setFileProgresses] = useState<Record<string, number>>(\n    {}\n  );\n\n  const handleFileSelect = (files: FileList | null) => {\n    if (!files) return;\n\n    const newFiles = Array.from(files);\n    setUploadedFiles((prev) => [...prev, ...newFiles]);\n\n    // Simulate upload progress for each file\n    newFiles.forEach((file) => {\n      let progress = 0;\n      const interval = setInterval(() => {\n        progress += Math.random() * 10;\n        if (progress >= 100) {\n          progress = 100;\n          clearInterval(interval);\n        }\n        setFileProgresses((prev) => ({\n          ...prev,\n          [file.name]: Math.min(progress, 100),\n        }));\n      }, 300);\n    });\n  };\n\n  const handleBoxClick = () => {\n    fileInputRef.current?.click();\n  };\n\n  const handleDragOver = (e: React.DragEvent) => {\n    e.preventDefault();\n  };\n\n  const handleDrop = (e: React.DragEvent) => {\n    e.preventDefault();\n    handleFileSelect(e.dataTransfer.files);\n  };\n\n  const removeFile = (filename: string) => {\n    setUploadedFiles((prev) => prev.filter((file) => file.name !== filename));\n    setFileProgresses((prev) => {\n      const newProgresses = { ...prev };\n      delete newProgresses[filename];\n      return newProgresses;\n    });\n  };\n\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <Card className=\"w-full mx-auto max-w-lg bg-background rounded-lg p-0 shadow-md\">\n        <CardContent className=\"p-0\">\n          <div className=\"p-6 pb-4\">\n            <div className=\"flex justify-between items-start\">\n              <div>\n                <h2 className=\"text-balance text-lg font-medium text-foreground\">\n                  Create a new project\n                </h2>\n                <p className=\"text-pretty text-sm text-muted-foreground mt-1\">\n                  Drag and drop files to create a new project.\n                </p>\n              </div>\n            </div>\n          </div>\n\n          <div className=\"px-6 pb-4 mt-2\">\n            <div className=\"grid grid-cols-2 gap-4\">\n              <div>\n                <Label htmlFor=\"projectName\" className=\"mb-2\">\n                  Project name\n                </Label>\n                <Input\n                  id=\"projectName\"\n                  type=\"text\"\n                  defaultValue=\"Open Source Stripe\"\n                />\n              </div>\n\n              <div>\n                <Label htmlFor=\"projectLead\" className=\"mb-2\">\n                  Project lead\n                </Label>\n                <Select defaultValue=\"1\">\n                  <SelectTrigger id=\"projectLead\" className=\"ps-2 w-full\">\n                    <SelectValue placeholder=\"Select project lead\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectGroup>\n                      <SelectItem value=\"1\">\n                        <img\n                          className=\"size-5 rounded\"\n                          src=\"https://blocks.so/avatar-01.png\"\n                          alt=\"Ephraim Duncan\"\n                          width={20}\n                          height={20}\n                        />\n                        <span className=\"truncate\">Ephraim Duncan</span>\n                      </SelectItem>\n                      <SelectItem value=\"2\">\n                        <img\n                          className=\"size-5 rounded\"\n                          src=\"https://blocks.so/avatar-03.png\"\n                          alt=\"Lucas Smith\"\n                          width={20}\n                          height={20}\n                        />\n                        <span className=\"truncate\">Lucas Smith</span>\n                      </SelectItem>\n                      <SelectItem value=\"3\">\n                        <img\n                          className=\"size-5 rounded\"\n                          src=\"https://blocks.so/avatar-02.jpg\"\n                          alt=\"Timur Ercan\"\n                          width={20}\n                          height={20}\n                        />\n                        <span className=\"truncate\">Timur Ercan</span>\n                      </SelectItem>\n                    </SelectGroup>\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n          </div>\n\n          <div className=\"px-6\">\n            <div\n              className=\"border-2 border-dashed border-border rounded-md p-8 flex flex-col items-center justify-center text-center cursor-pointer\"\n              onClick={handleBoxClick}\n              onDragOver={handleDragOver}\n              onDrop={handleDrop}\n            >\n              <div className=\"mb-2 bg-muted rounded-full p-3\">\n                <Upload className=\"h-5 w-5 text-muted-foreground\" />\n              </div>\n              <p className=\"text-pretty text-sm font-medium text-foreground\">\n                Upload a project image\n              </p>\n              <p className=\"text-pretty text-sm text-muted-foreground mt-1\">\n                or,{\" \"}\n                <label\n                  htmlFor=\"fileUpload\"\n                  className=\"text-primary hover:text-primary/90 font-medium cursor-pointer\"\n                  onClick={(e) => e.stopPropagation()}\n                >\n                  click to browse\n                </label>{\" \"}\n                (4MB max)\n              </p>\n              <input\n                type=\"file\"\n                id=\"fileUpload\"\n                ref={fileInputRef}\n                className=\"hidden\"\n                accept=\"image/*\"\n                onChange={(e) => handleFileSelect(e.target.files)}\n              />\n            </div>\n          </div>\n\n          <div\n            className={cn(\n              \"px-6 pb-5 space-y-3\",\n              uploadedFiles.length > 0 ? \"mt-4\" : \"\"\n            )}\n          >\n            {uploadedFiles.map((file, index) => {\n              const imageUrl = URL.createObjectURL(file);\n\n              return (\n                <div\n                  className=\"border border-border rounded-lg p-2 flex flex-col\"\n                  key={file.name + index}\n                  onLoad={() => {\n                    return () => URL.revokeObjectURL(imageUrl);\n                  }}\n                >\n                  <div className=\"flex items-center gap-2\">\n                    <div className=\"w-18 h-14 bg-muted rounded-sm flex items-center justify-center self-start row-span-2 overflow-hidden\">\n                      <img\n                        src={imageUrl}\n                        alt={file.name}\n                        className=\"w-full h-full object-cover\"\n                      />\n                    </div>\n\n                    <div className=\"flex-1 pr-1\">\n                      <div className=\"flex justify-between items-center\">\n                        <div className=\"flex items-center gap-2\">\n                          <span className=\"text-sm text-foreground truncate max-w-[250px]\">\n                            {file.name}\n                          </span>\n                          <span className=\"text-sm text-muted-foreground whitespace-nowrap\">\n                            {Math.round(file.size / 1024)} KB\n                          </span>\n                        </div>\n                        <Button\n                          variant=\"ghost\"\n                          size=\"icon-sm\"\n                          className=\"bg-transparent! hover:text-red-500\"\n                          onClick={() => removeFile(file.name)}\n                        >\n                          <Trash2 className=\"h-4 w-4\" />\n                        </Button>\n                      </div>\n\n                      <div className=\"flex items-center gap-2\">\n                        <div className=\"h-2 bg-muted rounded-full overflow-hidden flex-1\">\n                          <div\n                            className=\"h-full bg-primary\"\n                            style={{\n                              width: `${fileProgresses[file.name] || 0}%`,\n                            }}\n                          ></div>\n                        </div>\n                        <span className=\"text-xs text-muted-foreground whitespace-nowrap\">\n                          {Math.round(fileProgresses[file.name] || 0)}%\n                        </span>\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              );\n            })}\n          </div>\n\n          <div className=\"px-6 py-3 border-t border-border bg-muted rounded-b-lg flex justify-between items-center\">\n            <TooltipProvider delayDuration={0}>\n              <Tooltip>\n                <TooltipTrigger asChild>\n                  <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    className=\"flex items-center text-muted-foreground hover:text-foreground\"\n                  >\n                    <HelpCircle className=\"h-4 w-4 mr-1\" />\n                    Need help?\n                  </Button>\n                </TooltipTrigger>\n                <TooltipContent className=\"py-3 bg-background text-foreground border\">\n                  <div className=\"space-y-1\">\n                    <p className=\"text-pretty text-[13px] font-medium\">Need assistance?</p>\n                    <p className=\"text-pretty text-muted-foreground dark:text-muted-background text-xs max-w-[200px]\">\n                      Upload project images by dragging and dropping files or\n                      using the file browser. Supported formats: JPG, PNG, SVG.\n                      Maximum file size: 4MB.\n                    </p>\n                  </div>\n                </TooltipContent>\n              </Tooltip>\n            </TooltipProvider>\n\n            <div className=\"flex gap-2\">\n              <Button\n                variant=\"outline\"\n                className=\"h-9 px-4 text-sm font-medium\"\n              >\n                Cancel\n              </Button>\n              <Button className=\"h-9 px-4 text-sm font-medium\">Continue</Button>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-02",
      "type": "registry:block",
      "title": "File Upload Simple",
      "description": "A file upload simple block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "input",
        "label"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/file-upload/file-upload-02.tsx",
          "type": "registry:component",
          "target": "components/file-upload-02.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\n\nexport default function FileUpload02() {\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <Card className=\"shadow-none\">\n        <CardHeader>\n          <CardTitle>Set up your first workspace</CardTitle>\n          <CardDescription>\n            Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\n          </CardDescription>\n        </CardHeader>\n        <CardContent>\n          <form action=\"#\" method=\"POST\">\n            <div className=\"space-y-6\">\n              <div className=\"space-y-2\">\n                <Label htmlFor=\"workspace-name\">\n                  Workspace <span className=\"text-destructive\">*</span>\n                </Label>\n                <Input\n                  type=\"text\"\n                  id=\"workspace-name\"\n                  name=\"workspace-name\"\n                  autoComplete=\"workspace-name\"\n                  placeholder=\"Workspace name\"\n                  required\n                />\n              </div>\n              <div className=\"space-y-2\">\n                <Label htmlFor=\"file-1\">\n                  Upload file <span className=\"text-destructive\">*</span>\n                </Label>\n                <Input id=\"file-1\" name=\"file-1\" type=\"file\" accept=\".csv, .xlsx, .xls\" />\n                <p className=\"text-pretty text-sm text-muted-foreground\">\n                  You are only allowed to upload CSV, XLSX or XLS files.\n                </p>\n              </div>\n            </div>\n            <div className=\"flex justify-end space-x-3 mt-8\">\n              <Button type=\"button\" variant=\"outline\">\n                Cancel\n              </Button>\n              <Button type=\"submit\">Submit</Button>\n            </div>\n          </form>\n        </CardContent>\n      </Card>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-03",
      "type": "registry:block",
      "title": "File Upload Multi-File Dropzone",
      "description": "A file upload multi-file dropzone block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "input",
        "label",
        "select",
        "separator"
      ],
      "dependencies": [
        "lucide-react",
        "react-dropzone"
      ],
      "files": [
        {
          "path": "content/components/file-upload/file-upload-03.tsx",
          "type": "registry:component",
          "target": "components/file-upload-03.tsx",
          "content": "\"use client\";\n\nimport { File, Trash } from \"lucide-react\";\nimport React from \"react\";\nimport { useDropzone } from \"react-dropzone\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { cn } from \"@/lib/utils\";\n\nexport default function FileUpload03() {\n  const [files, setFiles] = React.useState<File[]>([]);\n  const { getRootProps, getInputProps, isDragActive } = useDropzone({\n    onDrop: (acceptedFiles) => setFiles(acceptedFiles),\n  });\n\n  const filesList = files.map((file) => (\n    <li key={file.name} className=\"relative\">\n      <Card className=\"relative p-4 shadow-none\">\n        <div className=\"absolute right-4 top-1/2 -translate-y-1/2\">\n          <Button\n            type=\"button\"\n            variant=\"ghost\"\n            size=\"icon\"\n            aria-label=\"Remove file\"\n            onClick={() =>\n              setFiles((prevFiles) =>\n                prevFiles.filter((prevFile) => prevFile.name !== file.name)\n              )\n            }\n          >\n            <Trash className=\"h-5 w-5\" aria-hidden={true} />\n          </Button>\n        </div>\n        <CardContent className=\"flex items-center space-x-3 p-0\">\n          <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted\">\n            <File className=\"h-5 w-5 text-foreground\" aria-hidden={true} />\n          </span>\n          <div>\n            <p className=\"text-pretty font-medium text-foreground\">{file.name}</p>\n            <p className=\"text-pretty mt-0.5 text-sm text-muted-foreground\">\n              {file.size} bytes\n            </p>\n          </div>\n        </CardContent>\n      </Card>\n    </li>\n  ));\n\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <Card className=\"sm:mx-auto sm:max-w-xl shadow-none\">\n        <CardHeader>\n          <CardTitle>Set up your first cloud storage</CardTitle>\n          <CardDescription>\n            Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\n          </CardDescription>\n        </CardHeader>\n        <CardContent>\n          <form action=\"#\" method=\"post\">\n            <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-6\">\n              <div className=\"col-span-full sm:col-span-3\">\n                <Label htmlFor=\"bucket-name\" className=\"font-medium\">\n                  Bucket name\n                </Label>\n                <Input\n                  type=\"text\"\n                  id=\"bucket-name\"\n                  name=\"bucket-name\"\n                  placeholder=\"Bucket name\"\n                  className=\"mt-2\"\n                />\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Label htmlFor=\"visibility\" className=\"font-medium\">\n                  Visibility\n                </Label>\n                <Select defaultValue=\"private\" disabled>\n                  <SelectTrigger\n                    id=\"visibility\"\n                    name=\"visibility\"\n                    className=\"mt-2 w-full\"\n                  >\n                    <SelectValue placeholder=\"Select visibility\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"private\">Private</SelectItem>\n                    <SelectItem value=\"public\">Public</SelectItem>\n                  </SelectContent>\n                </Select>\n                <p className=\"text-pretty mt-2 text-sm text-muted-foreground\">\n                  Only admins can change visibility.\n                </p>\n              </div>\n              <div className=\"col-span-full\">\n                <Label htmlFor=\"file-upload-2\" className=\"font-medium\">\n                  File(s) upload\n                </Label>\n                <div\n                  {...getRootProps()}\n                  className={cn(\n                    isDragActive\n                      ? \"border-primary bg-primary/10 ring-2 ring-primary/20\"\n                      : \"border-border\",\n                    \"mt-2 flex justify-center rounded-md border border-dashed px-6 py-20 transition-colors duration-200\"\n                  )}\n                >\n                  <div>\n                    <File\n                      className=\"mx-auto h-12 w-12 text-muted-foreground/80\"\n                      aria-hidden={true}\n                    />\n                    <div className=\"mt-4 flex text-muted-foreground\">\n                      <p>Drag and drop or</p>\n                      <label\n                        htmlFor=\"file\"\n                        className=\"relative cursor-pointer rounded-sm pl-1 font-medium text-primary hover:text-primary/80 hover:underline hover:underline-offset-4\"\n                      >\n                        <span>choose file(s)</span>\n                        <input\n                          {...getInputProps()}\n                          id=\"file-upload-2\"\n                          name=\"file-upload-2\"\n                          type=\"file\"\n                          className=\"sr-only\"\n                        />\n                      </label>\n                      <p className=\"text-pretty pl-1\">to upload</p>\n                    </div>\n                  </div>\n                </div>\n                <p className=\"text-pretty mt-2 text-sm leading-5 text-muted-foreground sm:flex sm:items-center sm:justify-between\">\n                  <span>All file types are allowed to upload.</span>\n                  <span className=\"pl-1 sm:pl-0\">Max. size per file: 50MB</span>\n                </p>\n                {filesList.length > 0 && (\n                  <>\n                    <h4 className=\"text-balance mt-6 font-medium text-foreground\">\n                      File(s) to upload\n                    </h4>\n                    <ul role=\"list\" className=\"mt-4 space-y-4\">\n                      {filesList}\n                    </ul>\n                  </>\n                )}\n              </div>\n            </div>\n            <Separator className=\"my-6\" />\n            <div className=\"flex items-center justify-end space-x-3\">\n              <Button type=\"button\" variant=\"outline\">\n                Cancel\n              </Button>\n              <Button type=\"submit\">Upload</Button>\n            </div>\n          </form>\n        </CardContent>\n      </Card>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-04",
      "type": "registry:block",
      "title": "File Upload Drag & Drop",
      "description": "A file upload drag & drop block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "progress"
      ],
      "dependencies": [
        "lucide-react",
        "sonner"
      ],
      "files": [
        {
          "path": "content/components/file-upload/file-upload-04.tsx",
          "type": "registry:component",
          "target": "components/file-upload-04.tsx",
          "content": "\"use client\";\n\nimport { File, FileSpreadsheet, X } from \"lucide-react\";\nimport { ChangeEvent, DragEvent, useRef, useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card } from \"@/components/ui/card\";\nimport { Progress } from \"@/components/ui/progress\";\n\nexport default function FileUpload04() {\n  const [uploadState, setUploadState] = useState<{\n    file: File | null;\n    progress: number;\n    uploading: boolean;\n  }>({\n    file: null,\n    progress: 0,\n    uploading: false,\n  });\n  const [showDummy, setShowDummy] = useState(true);\n  const fileInputRef = useRef<HTMLInputElement>(null);\n\n  const validFileTypes = [\n    \"text/csv\",\n    \"application/vnd.ms-excel\",\n    \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n  ];\n\n  const handleFile = (file: File | undefined) => {\n    if (!file) return;\n\n    if (validFileTypes.includes(file.type)) {\n      setUploadState({ file, progress: 0, uploading: true });\n\n      const interval = setInterval(() => {\n        setUploadState((prev) => {\n          const newProgress = prev.progress + 5;\n          if (newProgress >= 100) {\n            clearInterval(interval);\n            return { ...prev, progress: 100, uploading: false };\n          }\n          return { ...prev, progress: newProgress };\n        });\n      }, 200);\n    } else {\n      toast.error(\"Please upload a CSV, XLSX, or XLS file.\", {\n        position: \"bottom-right\",\n        duration: 3000,\n      });\n    }\n  };\n\n  const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {\n    handleFile(event.target.files?.[0]);\n  };\n\n  const handleDrop = (event: DragEvent<HTMLDivElement>) => {\n    event.preventDefault();\n    handleFile(event.dataTransfer.files?.[0]);\n  };\n\n  const resetFile = () => {\n    setUploadState({ file: null, progress: 0, uploading: false });\n    if (fileInputRef.current) {\n      fileInputRef.current.value = \"\";\n    }\n  };\n\n  const getFileIcon = () => {\n    if (!uploadState.file) return <File />;\n\n    const fileExt = uploadState.file.name.split(\".\").pop()?.toLowerCase() || \"\";\n    return [\"csv\", \"xlsx\", \"xls\"].includes(fileExt) ? (\n      <FileSpreadsheet className=\"h-5 w-5 text-foreground\" />\n    ) : (\n      <File className=\"h-5 w-5 text-foreground\" />\n    );\n  };\n\n  const formatFileSize = (bytes: number) => {\n    if (bytes === 0) return \"0 Bytes\";\n    const k = 1024;\n    const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"];\n    const i = Math.floor(Math.log(bytes) / Math.log(k));\n    return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + \" \" + sizes[i];\n  };\n\n  const { file, progress, uploading } = uploadState;\n\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full max-w-lg\">\n      <form className=\"w-full\" onSubmit={(e) => e.preventDefault()}>\n        <h3 className=\"text-balance text-lg font-semibold text-foreground\">File Upload</h3>\n\n        <div\n          className=\"flex justify-center rounded-md border mt-2 border-dashed border-input px-6 py-12\"\n          onDragOver={(e) => e.preventDefault()}\n          onDrop={handleDrop}\n        >\n          <div>\n            <File\n              className=\"mx-auto h-12 w-12 text-muted-foreground\"\n              aria-hidden={true}\n            />\n            <div className=\"flex text-sm leading-6 text-muted-foreground\">\n              <p>Drag and drop or</p>\n              <label\n                htmlFor=\"file-upload-03\"\n                className=\"relative cursor-pointer rounded-sm pl-1 font-medium text-primary hover:underline hover:underline-offset-4\"\n              >\n                <span>choose file</span>\n                <input\n                  id=\"file-upload-03\"\n                  name=\"file-upload-03\"\n                  type=\"file\"\n                  className=\"sr-only\"\n                  accept=\".csv, .xlsx, .xls\"\n                  onChange={handleFileChange}\n                  ref={fileInputRef}\n                />\n              </label>\n              <p className=\"text-pretty pl-1\">to upload</p>\n            </div>\n          </div>\n        </div>\n\n        <p className=\"text-pretty mt-2 text-xs leading-5 text-muted-foreground sm:flex sm:items-center sm:justify-between\">\n          <span>Accepted file types: CSV, XLSX or XLS files.</span>\n          <span className=\"pl-1 sm:pl-0\">Max. size: 10MB</span>\n        </p>\n\n        {!file && showDummy && (\n          <Card className=\"relative mt-8 bg-muted p-4 gap-4 shadow-none\">\n            <Button\n              type=\"button\"\n              variant=\"ghost\"\n              size=\"icon-sm\"\n              className=\"absolute right-1 top-1 text-muted-foreground hover:text-foreground\"\n              aria-label=\"Remove\"\n              onClick={() => setShowDummy(false)}\n            >\n              <X className=\"h-5 w-5 shrink-0\" aria-hidden={true} />\n            </Button>\n\n            <div className=\"flex items-center space-x-2.5\">\n              <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-sm bg-background shadow-sm ring-1 ring-inset ring-border\">\n                <FileSpreadsheet\n                  className=\"h-5 w-5 text-foreground\"\n                  aria-hidden={true}\n                />\n              </span>\n              <div>\n                <p className=\"text-pretty text-xs font-medium text-foreground\">\n                  Revenue_Q1_2024.xlsx\n                </p>\n                <p className=\"text-pretty mt-0.5 text-xs text-muted-foreground\">3.1 MB</p>\n              </div>\n            </div>\n\n            <div className=\"flex items-center space-x-3\">\n              <Progress value={45} className=\"h-1.5\" />\n              <span className=\"text-xs text-muted-foreground\">45%</span>\n            </div>\n          </Card>\n        )}\n\n        {file && (\n          <Card className=\"relative mt-8 bg-muted p-4 gap-4 shadow-none\">\n            <Button\n              type=\"button\"\n              variant=\"ghost\"\n              size=\"icon-sm\"\n              className=\"absolute right-1 top-1 text-muted-foreground hover:text-foreground\"\n              aria-label=\"Remove\"\n              onClick={resetFile}\n            >\n              <X className=\"h-5 w-5 shrink-0\" aria-hidden={true} />\n            </Button>\n\n            <div className=\"flex items-center space-x-2.5\">\n              <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-sm bg-background shadow-sm ring-1 ring-inset ring-border\">\n                {getFileIcon()}\n              </span>\n              <div>\n                <p className=\"text-pretty text-xs font-medium text-foreground\">\n                  {file?.name}\n                </p>\n                <p className=\"text-pretty mt-0.5 text-xs text-muted-foreground\">\n                  {file && formatFileSize(file.size)}\n                </p>\n              </div>\n            </div>\n\n            <div className=\"flex items-center space-x-3\">\n              <Progress value={progress} className=\"h-1.5\" />\n              <span className=\"text-xs text-muted-foreground\">{progress}%</span>\n            </div>\n          </Card>\n        )}\n\n        <div className=\"mt-8 flex items-center justify-end space-x-3\">\n          <Button\n            type=\"button\"\n            variant=\"outline\"\n            className=\"whitespace-nowrap\"\n            onClick={resetFile}\n            disabled={!file}\n          >\n            Cancel\n          </Button>\n          <Button\n            type=\"submit\"\n            className=\"whitespace-nowrap\"\n            disabled={!file || uploading || progress < 100}\n          >\n            Upload\n          </Button>\n        </div>\n      </form>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-05",
      "type": "registry:block",
      "title": "File Upload with Progress",
      "description": "A file upload with progress block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "label"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/file-upload/file-upload-05.tsx",
          "type": "registry:component",
          "target": "components/file-upload-05.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Label } from \"@/components/ui/label\";\nimport { FileSpreadsheet, Upload, X } from \"lucide-react\";\n\nexport default function FileUpload05() {\n  return (\n    <div className=\"sm:mx-auto sm:max-w-lg flex items-center justify-center p-10 w-full max-w-lg\">\n      <form>\n        <h3 className=\"text-balance text-lg font-semibold text-foreground\">File Upload</h3>\n        <div className=\"mt-4 flex justify-center space-x-4 rounded-md border border-dashed border-input px-6 py-10\">\n          <div className=\"sm:flex sm:items-center sm:gap-x-3\">\n            <Upload\n              className=\"mx-auto h-8 w-8 text-muted-foreground sm:mx-0 sm:h-6 sm:w-6\"\n              aria-hidden={true}\n            />\n            <div className=\"mt-4 flex text-sm leading-6 text-foreground sm:mt-0\">\n              <p>Drag and drop or</p>\n              <Label\n                htmlFor=\"file-upload-4\"\n                className=\"relative cursor-pointer rounded-sm pl-1 font-medium text-primary hover:underline hover:underline-offset-4\"\n              >\n                <span>choose file</span>\n                <input\n                  id=\"file-upload-4\"\n                  name=\"file-upload-4\"\n                  type=\"file\"\n                  className=\"sr-only\"\n                />\n              </Label>\n              <p className=\"text-pretty pl-1\">to upload</p>\n            </div>\n          </div>\n        </div>\n        <p className=\"text-pretty mt-2 flex items-center justify-between text-xs leading-5 text-muted-foreground\">\n          Recommended max. size: 10 MB, Accepted file types: XLSX, XLS, CSV.\n        </p>\n        <div className=\"relative mt-8 rounded-lg bg-muted p-3\">\n          <div className=\"absolute right-1 top-1\">\n            <Button\n              type=\"button\"\n              variant=\"ghost\"\n              size=\"sm\"\n              className=\"rounded-sm p-2 text-muted-foreground hover:text-foreground\"\n              aria-label=\"Remove\"\n            >\n              <X className=\"size-4 shrink-0\" aria-hidden={true} />\n            </Button>\n          </div>\n          <div className=\"flex items-center space-x-2.5\">\n            <span className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-sm bg-background shadow-sm ring-1 ring-inset ring-input\">\n              <FileSpreadsheet\n                className=\"size-5 text-foreground\"\n                aria-hidden={true}\n              />\n            </span>\n            <div className=\"w-full\">\n              <p className=\"text-pretty text-xs font-medium text-foreground\">\n                Revenue_Q1_2024.xlsx\n              </p>\n              <p className=\"text-pretty mt-0.5 flex justify-between text-xs text-muted-foreground\">\n                <span>3.1 MB</span>\n                <span>Completed</span>\n              </p>\n            </div>\n          </div>\n        </div>\n        <div className=\"mt-8 flex items-center justify-end space-x-3\">\n          <Button\n            type=\"button\"\n            variant=\"outline\"\n            className=\"whitespace-nowrap rounded-sm border border-input px-4 py-2 text-sm font-medium text-foreground shadow-sm hover:bg-accent hover:text-foreground\"\n          >\n            Cancel\n          </Button>\n          <Button\n            type=\"submit\"\n            variant=\"default\"\n            className=\"whitespace-nowrap rounded-sm bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm hover:bg-primary/90\"\n          >\n            Upload\n          </Button>\n        </div>\n      </form>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "file-upload-06",
      "type": "registry:block",
      "title": "File Upload with Status Sections",
      "description": "A file upload with status sections block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "progress",
        "separator"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/file-upload/file-upload-06.tsx",
          "type": "registry:component",
          "target": "components/file-upload-06.tsx",
          "content": "\"use client\";\n\nimport type React from \"react\";\nimport { useState, useRef } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Progress } from \"@/components/ui/progress\";\nimport { Card } from \"@/components/ui/card\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { Upload, FileText, X, CheckCircle, Loader2 } from \"lucide-react\";\n\ninterface UploadItem {\n  id: string;\n  name: string;\n  progress: number;\n  status: \"uploading\" | \"completed\";\n}\n\nexport default function FileUpload06() {\n  const [uploads, setUploads] = useState<UploadItem[]>([\n    {\n      id: \"a1\",\n      name: \"design-mock-landing.png\",\n      progress: 62,\n      status: \"uploading\",\n    },\n    {\n      id: \"b2\",\n      name: \"team-headshot-2025-01-09.jpg\",\n      progress: 28,\n      status: \"uploading\",\n    },\n    {\n      id: \"c3\",\n      name: \"logo-v3-final.gif\",\n      progress: 100,\n      status: \"completed\",\n    },\n  ]);\n  const filePickerRef = useRef<HTMLInputElement>(null);\n\n  const openFilePicker = () => {\n    filePickerRef.current?.click();\n  };\n\n  const onFileInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n    const selectedFiles = event.target.files;\n    if (selectedFiles) {\n      console.log(\"Files selected:\", selectedFiles);\n    }\n  };\n\n  const onDragOver = (event: React.DragEvent) => {\n    event.preventDefault();\n  };\n\n  const onDropFiles = (event: React.DragEvent) => {\n    event.preventDefault();\n    const droppedFiles = event.dataTransfer.files;\n    if (droppedFiles) {\n      console.log(\"Files dropped:\", droppedFiles);\n    }\n  };\n\n  const removeUploadById = (id: string) => {\n    setUploads(uploads.filter((file) => file.id !== id));\n  };\n\n  const activeUploads = uploads.filter((file) => file.status === \"uploading\");\n  const completedUploads = uploads.filter(\n    (file) => file.status === \"completed\"\n  );\n\n  return (\n    <div className=\"mx-auto flex w-full max-w-sm flex-col gap-y-6\">\n      <Card\n        className=\"group flex max-h-[200px] w-full flex-col items-center justify-center gap-4 py-8 border-dashed text-sm shadow-none cursor-pointer hover:bg-muted/50 transition-colors\"\n        onDragOver={onDragOver}\n        onDrop={onDropFiles}\n        onClick={openFilePicker}\n      >\n        <div className=\"grid space-y-3\">\n          <div className=\"flex items-center gap-x-2 text-muted-foreground\">\n            <Upload className=\"size-5\" />\n            <div>\n              Drop files here or{\" \"}\n              <Button\n                variant=\"link\"\n                className=\"text-primary p-0 h-auto font-normal\"\n                onClick={openFilePicker}\n              >\n                browse files\n              </Button>{\" \"}\n              to add\n            </div>\n          </div>\n        </div>\n        <input\n          ref={filePickerRef}\n          type=\"file\"\n          className=\"hidden\"\n          accept=\"image/png,image/jpeg,image/gif\"\n          multiple\n          onChange={onFileInputChange}\n        />\n        <span className=\"text-base/6 text-muted-foreground group-disabled:opacity-50 mt-2 block sm:text-xs\">\n          Supported: JPG, PNG, GIF (max 10 MB)\n        </span>\n      </Card>\n\n      <div className=\"flex flex-col gap-y-4\">\n        {activeUploads.length > 0 && (\n          <div>\n            <h2 className=\"text-balance text-foreground text-lg flex items-center font-mono font-normal uppercase sm:text-xs mb-4\">\n              <Loader2 className=\"size-4 mr-1 animate-spin\" />\n              Uploading\n            </h2>\n            <div className=\"-mt-2 divide-y\">\n              {activeUploads.map((file) => (\n                <div key={file.id} className=\"group flex items-center py-4\">\n                  <div className=\"mr-3 grid size-10 shrink-0 place-content-center rounded border bg-muted\">\n                    <FileText className=\"inline size-4 group-hover:hidden\" />\n                    <Button\n                      variant=\"ghost\"\n                      size=\"icon\"\n                      className=\"hidden size-4 group-hover:inline p-0 h-auto\"\n                      onClick={() => removeUploadById(file.id)}\n                      aria-label=\"Cancel\"\n                    >\n                      <X className=\"size-4\" />\n                    </Button>\n                  </div>\n                  <div className=\"flex flex-col w-full mb-1\">\n                    <div className=\"flex justify-between gap-2\">\n                      <span className=\"select-none text-base/6 text-foreground group-disabled:opacity-50 sm:text-sm/6\">\n                        {file.name}\n                      </span>\n                      <span className=\"text-muted-foreground text-sm tabular-nums\">\n                        {file.progress}%\n                      </span>\n                    </div>\n                    <Progress\n                      value={file.progress}\n                      className=\"mt-1 h-2 min-w-64\"\n                    />\n                  </div>\n                </div>\n              ))}\n            </div>\n          </div>\n        )}\n\n        {activeUploads.length > 0 && completedUploads.length > 0 && (\n          <Separator className=\"my-0\" />\n        )}\n\n        {completedUploads.length > 0 && (\n          <div>\n            <h2 className=\"text-balance text-foreground text-lg flex items-center font-mono font-normal uppercase sm:text-xs mb-4\">\n              <CheckCircle className=\"mr-1 size-4\" />\n              Finished\n            </h2>\n            <div className=\"-mt-2 divide-y\">\n              {completedUploads.map((file) => (\n                <div key={file.id} className=\"group flex items-center py-4\">\n                  <div className=\"mr-3 grid size-10 shrink-0 place-content-center rounded border bg-muted\">\n                    <FileText className=\"inline size-4 group-hover:hidden\" />\n                    <Button\n                      variant=\"ghost\"\n                      size=\"icon\"\n                      className=\"hidden size-4 group-hover:inline p-0 h-auto\"\n                      onClick={() => removeUploadById(file.id)}\n                      aria-label=\"Remove\"\n                    >\n                      <X className=\"size-4\" />\n                    </Button>\n                  </div>\n                  <div className=\"flex flex-col w-full mb-1\">\n                    <div className=\"flex justify-between gap-2\">\n                      <span className=\"select-none text-base/6 text-foreground group-disabled:opacity-50 sm:text-sm/6\">\n                        {file.name}\n                      </span>\n                      <span className=\"text-muted-foreground text-sm tabular-nums\">\n                        {file.progress}%\n                      </span>\n                    </div>\n                    <Progress\n                      value={file.progress}\n                      className=\"mt-1 h-2 min-w-64\"\n                    />\n                  </div>\n                </div>\n              ))}\n            </div>\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "file-upload"
      ]
    },
    {
      "name": "form-layout-01",
      "type": "registry:block",
      "title": "Form with Workspace Fields",
      "description": "A form with workspace fields block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "field",
        "input",
        "separator"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/form-layout/form-layout-01.tsx",
          "type": "registry:component",
          "target": "components/form-layout-01.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Field, FieldLabel } from \"@/components/ui/field\";\nimport { Input } from \"@/components/ui/input\";\nimport { Separator } from \"@/components/ui/separator\";\n\nexport default function FormLayout01() {\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <div className=\"sm:mx-auto sm:max-w-2xl\">\n        <h3 className=\"text-balance text-2xl font-semibold text-foreground dark:text-foreground\">\n          Register to workspace\n        </h3>\n        <p className=\"text-pretty mt-1 text-sm text-muted-foreground dark:text-muted-foreground\">\n          Take a few moments to register for your company&apos;s workspace\n        </p>\n        <form action=\"#\" method=\"post\" className=\"mt-8\">\n          <div className=\"grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-6\">\n            <div className=\"col-span-full sm:col-span-3\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"first-name\">\n                  First name\n                  <span className=\"text-red-500\">*</span>\n                </FieldLabel>\n                <Input\n                  type=\"text\"\n                  id=\"first-name\"\n                  name=\"first-name\"\n                  autoComplete=\"first-name\"\n                  placeholder=\"First name\"\n                  required\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full sm:col-span-3\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"last-name\">\n                  Last name\n                  <span className=\"text-red-500\">*</span>\n                </FieldLabel>\n                <Input\n                  type=\"text\"\n                  id=\"last-name\"\n                  name=\"last-name\"\n                  autoComplete=\"last-name\"\n                  placeholder=\"Last name\"\n                  required\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"email\">\n                  Email\n                  <span className=\"text-red-500\">*</span>\n                </FieldLabel>\n                <Input\n                  type=\"email\"\n                  id=\"email\"\n                  name=\"email\"\n                  autoComplete=\"email\"\n                  placeholder=\"Email\"\n                  required\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"address\">Address</FieldLabel>\n                <Input\n                  type=\"text\"\n                  id=\"address\"\n                  name=\"address\"\n                  autoComplete=\"street-address\"\n                  placeholder=\"Address\"\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full sm:col-span-2\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"city\">City</FieldLabel>\n                <Input\n                  type=\"text\"\n                  id=\"city\"\n                  name=\"city\"\n                  autoComplete=\"address-level2\"\n                  placeholder=\"City\"\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full sm:col-span-2\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"state\">State</FieldLabel>\n                <Input\n                  type=\"text\"\n                  id=\"state\"\n                  name=\"state\"\n                  autoComplete=\"address-level1\"\n                  placeholder=\"State\"\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full sm:col-span-2\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"postal-code\">Postal code</FieldLabel>\n                <Input\n                  id=\"postal-code\"\n                  name=\"postal-code\"\n                  autoComplete=\"postal-code\"\n                  placeholder=\"Postal code\"\n                />\n              </Field>\n            </div>\n          </div>\n          <Separator className=\"my-6\" />\n          <div className=\"flex items-center justify-end space-x-4\">\n            <Button\n              type=\"button\"\n              variant=\"outline\"\n              className=\"whitespace-nowrap\"\n            >\n              Cancel\n            </Button>\n            <Button type=\"submit\" className=\"whitespace-nowrap\">\n              Submit\n            </Button>\n          </div>\n        </form>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "form-layout"
      ]
    },
    {
      "name": "form-layout-02",
      "type": "registry:block",
      "title": "Form with Side Labels",
      "description": "A form with side labels block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "field",
        "input",
        "radio-group",
        "select",
        "separator",
        "textarea"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/form-layout/form-layout-02.tsx",
          "type": "registry:component",
          "target": "components/form-layout-02.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\";\nimport { Input } from \"@/components/ui/input\";\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { Textarea } from \"@/components/ui/textarea\";\n\nexport default function FormLayout02() {\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <form>\n        <div className=\"grid grid-cols-1 gap-10 md:grid-cols-3\">\n          <div>\n            <h2 className=\"text-balance font-semibold text-foreground dark:text-foreground\">\n              Personal information\n            </h2>\n            <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground dark:text-muted-foreground\">\n              Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\n            </p>\n          </div>\n          <div className=\"sm:max-w-3xl md:col-span-2\">\n            <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-6\">\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"first-name\">First name</FieldLabel>\n                  <Input\n                    type=\"text\"\n                    id=\"first-name\"\n                    name=\"first-name\"\n                    autoComplete=\"given-name\"\n                    placeholder=\"Emma\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"last-name\">Last name</FieldLabel>\n                  <Input\n                    type=\"text\"\n                    id=\"last-name\"\n                    name=\"last-name\"\n                    autoComplete=\"family-name\"\n                    placeholder=\"Crown\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"email\">Email</FieldLabel>\n                  <Input\n                    type=\"email\"\n                    id=\"email\"\n                    name=\"email\"\n                    autoComplete=\"email\"\n                    placeholder=\"emma@company.com\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"birthyear\">Birth year</FieldLabel>\n                  <Input\n                    type=\"number\"\n                    id=\"birthyear\"\n                    name=\"year\"\n                    placeholder=\"1990\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"role\">Role</FieldLabel>\n                  <Input\n                    type=\"text\"\n                    id=\"role\"\n                    name=\"role\"\n                    placeholder=\"Senior Manager\"\n                    disabled\n                  />\n                  <FieldDescription>\n                    Roles can only be changed by system admin.\n                  </FieldDescription>\n                </Field>\n              </div>\n            </div>\n          </div>\n        </div>\n        <Separator className=\"my-8\" />\n        <div className=\"grid grid-cols-1 gap-10 md:grid-cols-3\">\n          <div>\n            <h2 className=\"text-balance font-semibold text-foreground dark:text-foreground\">\n              Workspace settings\n            </h2>\n            <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground dark:text-muted-foreground\">\n              Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\n            </p>\n          </div>\n          <div className=\"sm:max-w-3xl md:col-span-2\">\n            <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-6\">\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"workspace-name\">Workspace name</FieldLabel>\n                  <Input\n                    type=\"text\"\n                    id=\"workspace-name\"\n                    name=\"workspace-name\"\n                    placeholder=\"Test workspace\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"visibility\">Visibility</FieldLabel>\n                  <Select name=\"visibility\" defaultValue=\"private\">\n                    <SelectTrigger id=\"visibility\">\n                      <SelectValue placeholder=\"Select visibility\" />\n                    </SelectTrigger>\n                    <SelectContent>\n                      <SelectItem value=\"public\">Public</SelectItem>\n                      <SelectItem value=\"private\">Private</SelectItem>\n                    </SelectContent>\n                  </Select>\n                </Field>\n              </div>\n              <div className=\"col-span-full\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"workspace-description\">\n                    Workspace description\n                  </FieldLabel>\n                  <Textarea\n                    id=\"workspace-description\"\n                    name=\"workspace-description\"\n                    rows={4}\n                  />\n                  <FieldDescription>\n                    Note: description provided will not be displayed externally.\n                  </FieldDescription>\n                </Field>\n              </div>\n            </div>\n          </div>\n        </div>\n        <Separator className=\"my-8\" />\n        <div className=\"grid grid-cols-1 gap-10 md:grid-cols-3\">\n          <div>\n            <h2 className=\"text-balance font-semibold text-foreground dark:text-foreground\">\n              Notification settings\n            </h2>\n            <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground dark:text-muted-foreground\">\n              Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\n            </p>\n          </div>\n          <div className=\"sm:max-w-3xl md:col-span-2\">\n            <fieldset>\n              <legend className=\"text-sm font-medium text-foreground dark:text-foreground\">\n                Newsletter\n              </legend>\n              <FieldDescription\n                id=\"newsletter-description\"\n                className=\"mt-2 leading-6\"\n              >\n                Change how often you want to receive updates from our\n                newsletter.\n              </FieldDescription>\n              <RadioGroup defaultValue=\"never\" className=\"mt-6\">\n                <div className=\"flex items-center gap-x-3\">\n                  <RadioGroupItem\n                    id=\"every-week\"\n                    value=\"every-week\"\n                    aria-describedby=\"newsletter-description\"\n                  />\n                  <FieldLabel htmlFor=\"every-week\" className=\"font-normal\">\n                    Every week\n                  </FieldLabel>\n                </div>\n                <div className=\"flex items-center gap-x-3\">\n                  <RadioGroupItem\n                    id=\"every-month\"\n                    value=\"every-month\"\n                    aria-describedby=\"newsletter-description\"\n                  />\n                  <FieldLabel htmlFor=\"every-month\" className=\"font-normal\">\n                    Every month\n                  </FieldLabel>\n                </div>\n                <div className=\"flex items-center gap-x-3\">\n                  <RadioGroupItem\n                    id=\"never\"\n                    value=\"never\"\n                    aria-describedby=\"newsletter-description\"\n                  />\n                  <FieldLabel htmlFor=\"never\" className=\"font-normal\">\n                    Never\n                  </FieldLabel>\n                </div>\n              </RadioGroup>\n            </fieldset>\n          </div>\n        </div>\n        <Separator className=\"my-8\" />\n        <div className=\"flex items-center justify-end space-x-4\">\n          <Button type=\"button\" variant=\"outline\" className=\"whitespace-nowrap\">\n            Go back\n          </Button>\n          <Button type=\"submit\" className=\"whitespace-nowrap\">\n            Save settings\n          </Button>\n        </div>\n      </form>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "form-layout"
      ]
    },
    {
      "name": "form-layout-03",
      "type": "registry:block",
      "title": "Form with Checkbox Settings",
      "description": "A form with checkbox settings block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "checkbox",
        "field",
        "input",
        "select",
        "separator",
        "textarea"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/form-layout/form-layout-03.tsx",
          "type": "registry:component",
          "target": "components/form-layout-03.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { Textarea } from \"@/components/ui/textarea\";\n\nexport default function FormLayout03() {\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <form>\n        <div className=\"grid grid-cols-1 gap-10 md:grid-cols-3\">\n          <div>\n            <h2 className=\"text-balance font-semibold text-foreground dark:text-foreground\">\n              Personal information\n            </h2>\n            <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground dark:text-muted-foreground\">\n              Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\n            </p>\n          </div>\n          <div className=\"sm:max-w-3xl md:col-span-2\">\n            <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-6\">\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"first-name\">First name</FieldLabel>\n                  <Input\n                    type=\"text\"\n                    id=\"first-name\"\n                    name=\"first-name\"\n                    autoComplete=\"given-name\"\n                    placeholder=\"Emma\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"last-name\">Last name</FieldLabel>\n                  <Input\n                    type=\"text\"\n                    id=\"last-name\"\n                    name=\"last-name\"\n                    autoComplete=\"family-name\"\n                    placeholder=\"Crown\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"email\">Email</FieldLabel>\n                  <Input\n                    type=\"email\"\n                    id=\"email\"\n                    name=\"email\"\n                    autoComplete=\"email\"\n                    placeholder=\"emma@company.com\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"birthyear\">Birth year</FieldLabel>\n                  <Input\n                    type=\"number\"\n                    id=\"birthyear\"\n                    name=\"year\"\n                    placeholder=\"1990\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"role\">Role</FieldLabel>\n                  <Input\n                    type=\"text\"\n                    id=\"role\"\n                    name=\"role\"\n                    placeholder=\"Senior Manager\"\n                    disabled\n                  />\n                  <FieldDescription>\n                    Roles can only be changed by system admin.\n                  </FieldDescription>\n                </Field>\n              </div>\n            </div>\n          </div>\n        </div>\n        <Separator className=\"my-8\" />\n        <div className=\"grid grid-cols-1 gap-10 md:grid-cols-3\">\n          <div>\n            <h2 className=\"text-balance font-semibold text-foreground dark:text-foreground\">\n              Workspace settings\n            </h2>\n            <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground dark:text-muted-foreground\">\n              Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\n            </p>\n          </div>\n          <div className=\"sm:max-w-3xl md:col-span-2\">\n            <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-6\">\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"workspace-name\">Workspace name</FieldLabel>\n                  <Input\n                    type=\"text\"\n                    id=\"workspace-name\"\n                    name=\"workspace-name\"\n                    placeholder=\"Test workspace\"\n                  />\n                </Field>\n              </div>\n              <div className=\"col-span-full sm:col-span-3\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"visibility\">Visibility</FieldLabel>\n                  <Select name=\"visibility\" defaultValue=\"private\">\n                    <SelectTrigger id=\"visibility\">\n                      <SelectValue placeholder=\"Select visibility\" />\n                    </SelectTrigger>\n                    <SelectContent>\n                      <SelectItem value=\"public\">Public</SelectItem>\n                      <SelectItem value=\"private\">Private</SelectItem>\n                    </SelectContent>\n                  </Select>\n                </Field>\n              </div>\n              <div className=\"col-span-full\">\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"workspace-description\">\n                    Workspace description\n                  </FieldLabel>\n                  <Textarea\n                    id=\"workspace-description\"\n                    name=\"workspace-description\"\n                    rows={4}\n                  />\n                  <FieldDescription>\n                    Note: description provided will not be displayed externally.\n                  </FieldDescription>\n                </Field>\n              </div>\n            </div>\n          </div>\n        </div>\n        <Separator className=\"my-8\" />\n        <div className=\"grid grid-cols-1 gap-10 md:grid-cols-3\">\n          <div>\n            <h2 className=\"text-balance font-semibold text-foreground dark:text-foreground\">\n              Notification settings\n            </h2>\n            <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground dark:text-muted-foreground\">\n              Lorem ipsum dolor sit amet, consetetur sadipscing elitr.\n            </p>\n          </div>\n          <div className=\"sm:max-w-3xl md:col-span-2\">\n            <fieldset>\n              <legend className=\"text-sm font-medium text-foreground dark:text-foreground\">\n                Team\n              </legend>\n              <FieldDescription className=\"mt-1 leading-6\">\n                Configure the types of team alerts you want to receive.\n              </FieldDescription>\n              <div className=\"mt-2\">\n                <div className=\"flex items-center gap-x-3 py-1\">\n                  <Checkbox\n                    id=\"team-requests\"\n                    name=\"team-requests\"\n                    defaultChecked\n                  />\n                  <FieldLabel htmlFor=\"team-requests\" className=\"font-normal\">\n                    Team join requests\n                  </FieldLabel>\n                </div>\n                <div className=\"flex items-center gap-x-3 py-1\">\n                  <Checkbox\n                    id=\"team-activity-digest\"\n                    name=\"team-activity-digest\"\n                  />\n                  <FieldLabel\n                    htmlFor=\"team-activity-digest\"\n                    className=\"font-normal\"\n                  >\n                    Weekly team activity digest\n                  </FieldLabel>\n                </div>\n              </div>\n            </fieldset>\n            <fieldset className=\"mt-6\">\n              <legend className=\"text-sm font-medium text-foreground dark:text-foreground\">\n                Usage\n              </legend>\n              <FieldDescription className=\"mt-1 leading-6\">\n                Configure the types of usage alerts you want to receive.\n              </FieldDescription>\n              <div className=\"mt-2\">\n                <div className=\"flex items-center gap-x-3 py-1\">\n                  <Checkbox id=\"api-requests\" name=\"api-requests\" />\n                  <FieldLabel htmlFor=\"api-requests\" className=\"font-normal\">\n                    API requests\n                  </FieldLabel>\n                </div>\n                <div className=\"flex items-center gap-x-3 py-1\">\n                  <Checkbox\n                    id=\"workspace-execution\"\n                    name=\"workspace-execution\"\n                  />\n                  <FieldLabel\n                    htmlFor=\"workspace-execution\"\n                    className=\"font-normal\"\n                  >\n                    Workspace loading times\n                  </FieldLabel>\n                </div>\n                <div className=\"flex items-center gap-x-3 py-1\">\n                  <Checkbox\n                    id=\"query-caching\"\n                    name=\"query-caching\"\n                    defaultChecked\n                  />\n                  <FieldLabel htmlFor=\"query-caching\" className=\"font-normal\">\n                    Query caching\n                  </FieldLabel>\n                </div>\n                <div className=\"flex items-center gap-x-3 py-1\">\n                  <Checkbox id=\"storage\" name=\"storage\" defaultChecked />\n                  <FieldLabel htmlFor=\"storage\" className=\"font-normal\">\n                    Storage\n                  </FieldLabel>\n                </div>\n              </div>\n            </fieldset>\n          </div>\n        </div>\n        <Separator className=\"my-8\" />\n        <div className=\"flex items-center justify-end space-x-4\">\n          <Button type=\"button\" variant=\"outline\" className=\"whitespace-nowrap\">\n            Go back\n          </Button>\n          <Button type=\"submit\" className=\"whitespace-nowrap\">\n            Save settings\n          </Button>\n        </div>\n      </form>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "form-layout"
      ]
    },
    {
      "name": "form-layout-04",
      "type": "registry:block",
      "title": "Form with Package Selection",
      "description": "A form with package selection block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "field",
        "input",
        "radio-group",
        "select",
        "separator"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/form-layout/form-layout-04.tsx",
          "type": "registry:component",
          "target": "components/form-layout-04.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\";\nimport { Input } from \"@/components/ui/input\";\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { useState } from \"react\";\n\nconst workspaces = [\n  {\n    id: 1,\n    title: \"Starter\",\n    description: \"Up to 10,000 requests per day.\",\n    users: \"Free\",\n  },\n  {\n    id: 2,\n    title: \"Premium\",\n    description: \"500,000 requests per day¹\",\n    users: \"$900/month²\",\n  },\n  {\n    id: 3,\n    title: \"Enterprise\",\n    description: \"Based on your specific needs\",\n    users: \"Custom\",\n  },\n];\n\nexport default function FormLayout04() {\n  const [selectedWorkspace, setSelectedWorkspace] = useState(workspaces[0]);\n\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <div className=\"sm:mx-auto sm:max-w-2xl\">\n        <h3 className=\"text-balance text-lg font-semibold text-foreground\">\n          Apply for early access\n        </h3>\n        <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground\">\n          Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam\n          nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.\n        </p>\n        <form action=\"#\" method=\"post\" className=\"mt-8\">\n          <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-6\">\n            <div className=\"col-span-full sm:col-span-3\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"first-name\">\n                  First name<span className=\"text-red-500\">*</span>\n                </FieldLabel>\n                <Input\n                  type=\"text\"\n                  id=\"first-name\"\n                  name=\"first-name\"\n                  autoComplete=\"given-name\"\n                  required\n                  placeholder=\"Emma\"\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full sm:col-span-3\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"last-name\">Last name</FieldLabel>\n                <Input\n                  type=\"text\"\n                  id=\"last-name\"\n                  name=\"last-name\"\n                  autoComplete=\"family-name\"\n                  placeholder=\"Crown\"\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"email\">\n                  Work email<span className=\"text-red-500\">*</span>\n                </FieldLabel>\n                <Input\n                  type=\"email\"\n                  id=\"email\"\n                  name=\"email\"\n                  autoComplete=\"email\"\n                  required\n                  placeholder=\"emma@company.com\"\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full sm:col-span-3\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"company\">Company</FieldLabel>\n                <Input\n                  type=\"text\"\n                  id=\"company\"\n                  name=\"company\"\n                  autoComplete=\"organization\"\n                  placeholder=\"Company, Inc.\"\n                />\n              </Field>\n            </div>\n            <div className=\"col-span-full sm:col-span-3\">\n              <Field className=\"gap-2\">\n                <FieldLabel htmlFor=\"size\">Company size (employees)</FieldLabel>\n                <Select defaultValue=\"\">\n                  <SelectTrigger id=\"size\" name=\"size\">\n                    <SelectValue placeholder=\"Select company size\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"1-9\">1-9</SelectItem>\n                    <SelectItem value=\"10-50\">10-50</SelectItem>\n                    <SelectItem value=\"50-250\">50-250</SelectItem>\n                    <SelectItem value=\"250+\">250+</SelectItem>\n                  </SelectContent>\n                </Select>\n              </Field>\n            </div>\n            <Separator className=\"col-span-full my-4\" />\n            <div className=\"col-span-full\">\n              <FieldLabel className=\"font-semibold text-foreground block mb-4\">\n                Select a workspace package\n              </FieldLabel>\n\n              <RadioGroup\n                className=\"grid grid-cols-1 sm:grid-cols-3 gap-5\"\n                defaultValue={selectedWorkspace.id.toString()}\n                onValueChange={(value) =>\n                  setSelectedWorkspace(\n                    workspaces.find(\n                      (workspace) => workspace.id.toString() === value\n                    ) || workspaces[0]\n                  )\n                }\n              >\n                {workspaces.map((item) => (\n                  <div\n                    key={item.id.toString()}\n                    className=\"border-input has-data-[state=checked]:border-ring relative flex flex-col gap-2 rounded-md border p-4 shadow-xs outline-none\"\n                  >\n                    <div className=\"flex justify-between\">\n                      <RadioGroupItem\n                        id={item.id.toString()}\n                        value={item.id.toString()}\n                        className=\"order-1 after:absolute after:inset-0\"\n                      />\n\n                      <FieldLabel\n                        htmlFor={item.id.toString()}\n                        className=\"block text-sm font-medium text-foreground\"\n                      >\n                        {item.title}\n                      </FieldLabel>\n                    </div>\n                    <div className=\"flex flex-col h-full justify-between\">\n                      <p className=\"text-pretty mt-1 text-sm text-muted-foreground\">\n                        {item.description}\n                      </p>\n                      <span className=\"mt-4 block text-sm font-medium text-foreground\">\n                        {item.users}\n                      </span>\n                    </div>\n                  </div>\n                ))}\n              </RadioGroup>\n\n              <FieldDescription className=\"mt-2!\">\n                <sup>1</sup> $0.5/10K requests after limit reach.\n              </FieldDescription>\n              <FieldDescription className=\"mt-1\">\n                <sup>2</sup> No credit card required for registration.\n              </FieldDescription>\n            </div>\n          </div>\n          <Separator className=\"my-6\" />\n          <div className=\"flex items-center justify-end space-x-4\">\n            <Button\n              type=\"button\"\n              variant=\"outline\"\n              className=\"whitespace-nowrap\"\n            >\n              Go back\n            </Button>\n            <Button type=\"submit\" className=\"whitespace-nowrap\">\n              Apply\n            </Button>\n          </div>\n        </form>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "form-layout"
      ]
    },
    {
      "name": "form-layout-05",
      "type": "registry:block",
      "title": "Form with Plan Selection",
      "description": "A form with plan selection block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "button",
        "card",
        "field",
        "input",
        "radio-group",
        "select",
        "separator"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/form-layout/form-layout-05.tsx",
          "type": "registry:component",
          "target": "components/form-layout-05.tsx",
          "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Field, FieldDescription, FieldLabel } from \"@/components/ui/field\";\nimport { Input } from \"@/components/ui/input\";\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { cn } from \"@/lib/utils\";\nimport { Check, CircleCheck, ExternalLink } from \"lucide-react\";\nimport { useState } from \"react\";\n\nconst highlights = [\n  {\n    id: 1,\n    feature: \"Used by top design teams worldwide\",\n  },\n  {\n    id: 2,\n    feature: \"Seamless integration with design tools\",\n  },\n  {\n    id: 3,\n    feature: \"Real-time collaboration features\",\n  },\n];\n\nconst plans = [\n  {\n    name: \"Creator\",\n    features: [\n      { feature: \"Up to 3 design projects\" },\n      { feature: \"Basic collaboration tools\" },\n      { feature: \"5GB cloud storage\" },\n      { feature: \"Community forum support\" },\n    ],\n    price: \"$15\",\n    href: \"#\",\n    isRecommended: false,\n  },\n  {\n    name: \"Team\",\n    features: [\n      { feature: \"Unlimited design projects\" },\n      { feature: \"Advanced collaboration suite\" },\n      { feature: \"50GB cloud storage\" },\n      { feature: \"Priority email support\" },\n    ],\n    price: \"$49\",\n    href: \"#\",\n    isRecommended: true,\n  },\n  {\n    name: \"Agency\",\n    features: [\n      { feature: \"Unlimited projects and team members\" },\n      { feature: \"Client portal access\" },\n      { feature: \"250GB cloud storage\" },\n      { feature: \"White-labeling options\" },\n      { feature: \"Dedicated account manager\" },\n    ],\n    price: \"$99\",\n    href: \"#\",\n    isRecommended: false,\n  },\n];\n\nexport default function FormLayout05() {\n  const [selected, setSelected] = useState(plans[0]);\n\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <form className=\"sm:mx-auto sm:max-w-7xl\">\n        <h3 className=\"text-balance text-xl font-semibold text-foreground\">\n          Create new design workspace\n        </h3>\n        <div className=\"grid grid-cols-1 gap-10 lg:grid-cols-12 lg:gap-12\">\n          <div className=\"mt-6 lg:col-span-7\">\n            <div className=\"space-y-4 md:space-y-6\">\n              <div className=\"md:flex md:items-center md:space-x-4\">\n                <div className=\"md:w-1/4\">\n                  <Field className=\"gap-2\">\n                    <FieldLabel htmlFor=\"organization\">Organization</FieldLabel>\n                    <Select defaultValue=\"1\">\n                      <SelectTrigger\n                        id=\"organization\"\n                        name=\"organization\"\n                        className=\"w-full\"\n                      >\n                        <SelectValue placeholder=\"Select organization\" />\n                      </SelectTrigger>\n                      <SelectContent>\n                        <SelectItem value=\"1\">Acme, Inc.</SelectItem>\n                        <SelectItem value=\"2\">Hero Labs</SelectItem>\n                        <SelectItem value=\"3\">Rose Holding</SelectItem>\n                      </SelectContent>\n                    </Select>\n                  </Field>\n                </div>\n                <div className=\"mt-4 md:mt-0 md:w-3/4\">\n                  <Field className=\"gap-2\">\n                    <FieldLabel htmlFor=\"workspace\">Workspace name</FieldLabel>\n                    <Input id=\"workspace\" name=\"workspace\" />\n                  </Field>\n                </div>\n              </div>\n              <div>\n                <Field className=\"gap-2\">\n                  <FieldLabel htmlFor=\"region\">Region</FieldLabel>\n                  <Select defaultValue=\"iad1\">\n                    <SelectTrigger id=\"region\" name=\"region\">\n                      <SelectValue placeholder=\"Select region\" />\n                    </SelectTrigger>\n                    <SelectContent>\n                      <SelectItem value=\"fra1\">\n                        eu-central-1 (Frankfurt, Germany)\n                      </SelectItem>\n                      <SelectItem value=\"iad1\">\n                        us-east-1 (Washington, D.C., USA)\n                      </SelectItem>\n                      <SelectItem value=\"lhr1\">\n                        eu-west-2 (London, United Kingdom)\n                      </SelectItem>\n                      <SelectItem value=\"sfo1\">\n                        us-west-1 (San Francisco, USA)\n                      </SelectItem>\n                      <SelectItem value=\"sin1\">\n                        ap-southeast-1 (Singapore)\n                      </SelectItem>\n                    </SelectContent>\n                  </Select>\n                  <FieldDescription>\n                    For best performance, choose a region closest to your\n                    operations\n                  </FieldDescription>\n                </Field>\n              </div>\n            </div>\n            <h4 className=\"text-balance mt-14 font-medium\">\n              Plan type<span className=\"text-red-500\">*</span>\n            </h4>\n            <RadioGroup\n              value={selected.name}\n              onValueChange={(value) =>\n                setSelected(\n                  plans.find((plan) => plan.name === value) || plans[0]\n                )\n              }\n              className=\"mt-4 space-y-4\"\n            >\n              {plans.map((plan) => (\n                <label\n                  key={plan.name}\n                  htmlFor={plan.name}\n                  className={cn(\n                    \"relative block cursor-pointer rounded-md border bg-background transition\",\n                    selected.name === plan.name\n                      ? \"border-primary/20 ring-2 ring-primary/20\"\n                      : \"border-border\"\n                  )}\n                >\n                  <div className=\"flex items-start space-x-4 px-6 py-4\">\n                    <div className=\"mt-1 flex h-4 w-4 shrink-0 items-center justify-center\">\n                      <RadioGroupItem value={plan.name} id={plan.name} />\n                    </div>\n                    <div className=\"w-full\">\n                      <p className=\"text-pretty leading-6\">\n                        <span className=\"font-semibold text-foreground\">\n                          {plan.name}\n                        </span>\n                        {plan.isRecommended && (\n                          <Badge variant=\"secondary\" className=\"ml-2\">\n                            recommended\n                          </Badge>\n                        )}\n                      </p>\n                      <ul className=\"mt-2 space-y-1\">\n                        {plan.features.map((feature, index) => (\n                          <li\n                            key={index}\n                            className=\"flex items-center gap-2 text-sm\"\n                          >\n                            <Check\n                              className=\"h-4 w-4 text-muted-foreground\"\n                              aria-hidden={true}\n                            />\n                            {feature.feature}\n                          </li>\n                        ))}\n                      </ul>\n                    </div>\n                  </div>\n                  <div className=\"flex items-center justify-between rounded-b-md border-t border-border bg-muted px-6 py-3\">\n                    <a\n                      href={plan.href}\n                      className=\"inline-flex items-center gap-1 text-sm text-primary hover:underline hover:underline-offset-4\"\n                    >\n                      Learn more\n                      <ExternalLink className=\"h-4 w-4\" aria-hidden={true} />\n                    </a>\n                    <div>\n                      <span className=\"text-lg font-semibold text-foreground\">\n                        {plan.price}\n                      </span>\n                      <span className=\"text-sm text-muted-foreground\">/mo</span>\n                    </div>\n                  </div>\n                </label>\n              ))}\n            </RadioGroup>\n          </div>\n          <div className=\"lg:col-span-5\">\n            <Card className=\"bg-muted shadow-none\">\n              <CardContent>\n                <h4 className=\"text-balance text-sm font-semibold text-foreground\">\n                  Choose the right plan for your design team\n                </h4>\n                <p className=\"text-pretty mt-2 text-sm leading-6 text-muted-foreground\">\n                  Our flexible plans are designed to scale with your team&apos;s\n                  needs. All plans include core design collaboration features\n                  with varying levels of storage and support.\n                </p>\n                <ul className=\"mt-4 space-y-1\">\n                  {highlights.map((item) => (\n                    <li\n                      key={item.id}\n                      className=\"flex items-center space-x-2 py-1.5 text-foreground\"\n                    >\n                      <CircleCheck className=\"h-5 w-5 text-primary\" />\n                      <span className=\"truncate text-sm\">{item.feature}</span>\n                    </li>\n                  ))}\n                </ul>\n                <a\n                  href=\"#\"\n                  className=\"mt-4 inline-flex items-center gap-1 text-sm text-primary\"\n                >\n                  Learn more\n                  <ExternalLink className=\"h-4 w-4\" aria-hidden={true} />\n                </a>\n              </CardContent>\n            </Card>\n          </div>\n        </div>\n        <Separator className=\"my-10\" />\n        <div className=\"flex items-center justify-end space-x-4\">\n          <Button type=\"button\" variant=\"ghost\">\n            Cancel\n          </Button>\n          <Button type=\"submit\">Update</Button>\n        </div>\n      </form>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "form-layout"
      ]
    },
    {
      "name": "grid-list-01",
      "type": "registry:block",
      "title": "Grid List with Dropdown",
      "description": "A grid list with dropdown block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "dropdown-menu"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/grid-list/grid-list-01.tsx",
          "type": "registry:component",
          "target": "components/grid-list-01.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { MoreVertical } from \"lucide-react\";\n\nconst bookCollections = [\n  { name: \"Science Fiction\", initials: \"SF\", href: \"#\", books: 37 },\n  { name: \"Mystery Thrillers\", initials: \"MT\", href: \"#\", books: 29 },\n  { name: \"Historical Fiction\", initials: \"HF\", href: \"#\", books: 23 },\n];\n\nexport default function GridList01() {\n  return (\n    <div className=\"flex items-center justify-center p-8\">\n      <div>\n        <h2 className=\"text-balance text-sm font-medium text-muted-foreground\">\n          Favorite Book Collections\n        </h2>\n        <ul role=\"list\" className=\"mt-3 grid grid-cols-1 gap-5 sm:gap-6 lg:grid-cols-3\">\n          {bookCollections.map((collection) => (\n            <li key={collection.name} className=\"col-span-1\">\n              <Card className=\"flex flex-row w-full gap-0 rounded-md shadow-2xs overflow-hidden py-0\">\n                <div className=\"flex w-16 shrink-0 items-center justify-center bg-primary text-sm font-medium text-primary-foreground\">\n                  {collection.initials}\n                </div>\n                <CardContent className=\"flex  flex-1 items-center justify-between truncate p-0 bg-card\">\n                  <div className=\"flex-1 truncate px-4 py-2 text-sm\">\n                    <a\n                      href={collection.href}\n                      className=\"font-medium text-foreground hover:text-muted-foreground\"\n                    >\n                      {collection.name}\n                    </a>\n                    <p className=\"text-pretty text-muted-foreground\">{collection.books} Books</p>\n                  </div>\n                  <div className=\"shrink-0 pr-2\">\n                    <DropdownMenu>\n                      <DropdownMenuTrigger asChild>\n                        <Button\n                          type=\"button\"\n                          variant=\"ghost\"\n                          size=\"icon\"\n                          className=\"h-8 w-8 rounded-full\"\n                        >\n                          <span className=\"sr-only\">Open options</span>\n                          <MoreVertical className=\"h-5 w-5\" />\n                        </Button>\n                      </DropdownMenuTrigger>\n                      <DropdownMenuContent align=\"end\">\n                        <DropdownMenuItem>View collection</DropdownMenuItem>\n                        <DropdownMenuItem>Edit collection</DropdownMenuItem>\n                        <DropdownMenuSeparator />\n                        <DropdownMenuItem>Share collection</DropdownMenuItem>\n                        <DropdownMenuItem className=\"text-destructive hover:bg-destructive/10 hover:text-destructive focus:bg-destructive/10 focus:text-destructive\">\n                          Delete collection\n                        </DropdownMenuItem>\n                      </DropdownMenuContent>\n                    </DropdownMenu>\n                  </div>\n                </CardContent>\n              </Card>\n            </li>\n          ))}\n        </ul>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "grid-list"
      ]
    },
    {
      "name": "grid-list-02",
      "type": "registry:block",
      "title": "Grid List with Links",
      "description": "A grid list with links block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "card"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/grid-list/grid-list-02.tsx",
          "type": "registry:component",
          "target": "components/grid-list-02.tsx",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Card, CardContent } from \"@/components/ui/card\";\n\nconst people = [\n  {\n    name: \"Timur Ercan\",\n    email: \"timur@documenso.com\",\n    role: \"Co-Founder / CEO\",\n    imageUrl: \"https://blocks.so/avatar-02.png\",\n  },\n  {\n    name: \"Lucas Smith\",\n    email: \"lucas@documenso.com\",\n    role: \"Co-Founder / CTO\",\n    imageUrl: \"https://blocks.so/avatar-03.png\",\n  },\n  {\n    name: \"Ephraim Duncan\",\n    email: \"ephraim@documenso.com\",\n    role: \"Software Engineer\",\n    imageUrl: \"https://blocks.so/avatar-01.png\",\n  },\n  {\n    name: \"Catalin Pit\",\n    email: \"catalin@documenso.com\",\n    role: \"Software Engineer\",\n    imageUrl: \"https://blocks.so/avatar-04.png\",\n  },\n];\n\nexport default function GridList02() {\n  return (\n    <div className=\"flex items-center justify-center p-8\">\n      <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n        {people.map((person) => (\n          <Card\n            key={person.email}\n            className=\"relative border transition-[border-color,box-shadow] duration-100 ease-out shadow-2xs hover:border-muted-foreground hover:shadow-sm focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 py-0\"\n          >\n            <CardContent className=\"flex items-center space-x-4 p-4\">\n              <Avatar className=\"h-10 w-10\">\n                <AvatarImage src={person.imageUrl} alt={person.name} />\n                <AvatarFallback>{person.name.charAt(0)}</AvatarFallback>\n              </Avatar>\n              <div className=\"min-w-0 flex-1\">\n                <a href=\"#\" className=\"focus:outline-none\">\n                  <span aria-hidden=\"true\" className=\"absolute inset-0\" />\n                  <p className=\"text-pretty text-sm font-medium text-foreground\">{person.name}</p>\n                  <p className=\"text-pretty truncate text-sm text-muted-foreground\">\n                    {person.role}\n                  </p>\n                </a>\n              </div>\n            </CardContent>\n          </Card>\n        ))}\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "grid-list"
      ]
    },
    {
      "name": "grid-list-03",
      "type": "registry:block",
      "title": "Grid List with Icons",
      "description": "A grid list with icons block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/grid-list/grid-list-03.tsx",
          "type": "registry:component",
          "target": "components/grid-list-03.tsx",
          "content": "import { Card, CardContent } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  ArrowRight,\n  ArrowUpRight,\n  CheckCircle,\n  ContactRound,\n  Hand,\n  Server,\n  UserCircle,\n} from \"lucide-react\";\n\nconst actions = [\n  {\n    title: \"Getting Started\",\n    description:\n      \"Everything you need to know to get started and get to work in ChatCloud.\",\n    href: \"#\",\n    icon: ArrowRight,\n    iconForeground: \"text-green-700\",\n    iconBackground: \"bg-green-50 dark:bg-green-950/30\",\n    ringColorClass: \"ring-green-700/30\",\n  },\n  {\n    title: \"Admin Settings\",\n    description:\n      \"Learn how to manage your current workspace or your enterprise space.\",\n    href: \"#\",\n    icon: UserCircle,\n    iconForeground: \"text-red-700\",\n    iconBackground: \"bg-red-50 dark:bg-red-950/30\",\n    ringColorClass: \"ring-red-700/30\",\n  },\n  {\n    title: \"Server Setup\",\n    description:\n      \"Connect, simplify, and automate. Discover the power of apps and tools.\",\n    href: \"#\",\n    icon: Server,\n    iconForeground: \"text-blue-700\",\n    iconBackground: \"bg-blue-50 dark:bg-blue-950/30\",\n    ringColorClass: \"ring-blue-700/30\",\n  },\n  {\n    title: \"Login and Verification\",\n    description:\n      \"Read on to learn how to sign in with your email address, or your Apple or Google.\",\n    href: \"#\",\n    icon: CheckCircle,\n    iconForeground: \"text-sky-700\",\n    iconBackground: \"bg-sky-50 dark:bg-sky-950/30\",\n    ringColorClass: \"ring-sky-700/30\",\n  },\n  {\n    title: \"Account Setup\",\n    description:\n      \"Adjust your profile and preferences to make ChatCloud work just for you.\",\n    href: \"#\",\n    icon: ContactRound,\n    iconForeground: \"text-pink-700\",\n    iconBackground: \"bg-pink-50 dark:bg-pink-950/30\",\n    ringColorClass: \"ring-pink-700/30\",\n  },\n  {\n    title: \"Trust & Safety\",\n    description:\n      \"Trust on our current database and learn how we distribute your data.\",\n    href: \"#\",\n    icon: Hand,\n    iconForeground: \"text-orange-700\",\n    iconBackground: \"bg-orange-50 dark:bg-orange-950/30\",\n    ringColorClass: \"ring-orange-700/30\",\n  },\n];\n\nexport default function GridList03() {\n  return (\n    <div className=\"flex items-center justify-center p-8\">\n      <div className=\"overflow-hidden rounded-2xl bg-muted shadow-sm grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 sm:gap-0.5 space-y-0.5 sm:space-y-0 p-0.5\">\n        {actions.map((action) => (\n          <Card\n            key={action.title}\n            className={cn(\n              \"group relative rounded-xl border-0 bg-card p-0 shadow-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-inset\"\n            )}\n          >\n            <CardContent className=\"p-6\">\n              <div>\n                <span\n                  className={cn(\n                    action.iconBackground,\n                    action.iconForeground,\n                    \"inline-flex rounded-lg p-3 ring-2 ring-inset\",\n                    action.ringColorClass\n                  )}\n                >\n                  <action.icon aria-hidden=\"true\" className=\"h-6 w-6\" />\n                </span>\n              </div>\n              <div className=\"mt-4\">\n                <h3 className=\"text-balance text-base font-semibold text-foreground\">\n                  <a href={action.href} className=\"focus:outline-none\">\n                    <span aria-hidden=\"true\" className=\"absolute inset-0\" />\n                    {action.title}\n                  </a>\n                </h3>\n                <p className=\"text-pretty mt-2 text-sm text-muted-foreground\">\n                  {action.description}\n                </p>\n              </div>\n              <span\n                aria-hidden=\"true\"\n                className=\"pointer-events-none absolute top-6 right-6 text-muted-foreground/50 group-hover:text-muted-foreground/60\"\n              >\n                <ArrowUpRight className=\"h-6 w-6\" />\n              </span>\n            </CardContent>\n          </Card>\n        ))}\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "grid-list"
      ]
    },
    {
      "name": "login-01",
      "type": "registry:block",
      "title": "Login with Email and Google",
      "description": "A login with email and google block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "input",
        "label",
        "separator"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/login/login-01.tsx",
          "type": "registry:component",
          "target": "components/login-01.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { JSX, SVGProps } from \"react\";\n\nconst GoogleIcon = (\n  props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>\n) => (\n  <svg fill=\"currentColor\" viewBox=\"0 0 24 24\" {...props}>\n    <path d=\"M3.06364 7.50914C4.70909 4.24092 8.09084 2 12 2C14.6954 2 16.959 2.99095 18.6909 4.60455L15.8227 7.47274C14.7864 6.48185 13.4681 5.97727 12 5.97727C9.39542 5.97727 7.19084 7.73637 6.40455 10.1C6.2045 10.7 6.09086 11.3409 6.09086 12C6.09086 12.6591 6.2045 13.3 6.40455 13.9C7.19084 16.2636 9.39542 18.0227 12 18.0227C13.3454 18.0227 14.4909 17.6682 15.3864 17.0682C16.4454 16.3591 17.15 15.3 17.3818 14.05H12V10.1818H21.4181C21.5364 10.8363 21.6 11.5182 21.6 12.2273C21.6 15.2727 20.5091 17.8363 18.6181 19.5773C16.9636 21.1046 14.7 22 12 22C8.09084 22 4.70909 19.7591 3.06364 16.4909C2.38638 15.1409 2 13.6136 2 12C2 10.3864 2.38638 8.85911 3.06364 7.50914Z\" />\n  </svg>\n);\n\nexport default function Login01() {\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <div className=\"flex flex-1 flex-col justify-center px-4 py-10 lg:px-6\">\n        <div className=\"sm:mx-auto sm:w-full sm:max-w-sm\">\n          <h2 className=\"text-balance text-center text-xl font-semibold text-foreground\">\n            Log in or create account\n          </h2>\n          <form action=\"#\" method=\"post\" className=\"mt-6\">\n            <Label htmlFor=\"email\" className=\"font-medium text-foreground\">\n              Email\n            </Label>\n            <Input\n              type=\"email\"\n              id=\"email\"\n              name=\"email\"\n              autoComplete=\"email\"\n              placeholder=\"john@company.com\"\n              className=\"mt-2\"\n            />\n            <Button type=\"submit\" className=\"mt-4 w-full\">\n              Sign in\n            </Button>\n          </form>\n\n          <div className=\"relative my-6\">\n            <div className=\"absolute inset-0 flex items-center\">\n              <Separator className=\"w-full\" />\n            </div>\n            <div className=\"relative flex justify-center text-xs uppercase\">\n              <span className=\"bg-background px-2 text-muted-foreground\">\n                or with\n              </span>\n            </div>\n          </div>\n\n          <Button\n            variant=\"outline\"\n            className=\"inline-flex w-full items-center justify-center space-x-2\"\n            asChild\n          >\n            <a href=\"#\">\n              <GoogleIcon className=\"size-5\" aria-hidden={true} />\n              <span className=\"text-sm font-medium\">Sign in with Google</span>\n            </a>\n          </Button>\n\n          <p className=\"text-pretty mt-4 text-xs text-muted-foreground\">\n            By signing in, you agree to our{\" \"}\n            <a href=\"#\" className=\"underline underline-offset-4\">\n              terms of service\n            </a>{\" \"}\n            and{\" \"}\n            <a href=\"#\" className=\"underline underline-offset-4\">\n              privacy policy\n            </a>\n            .\n          </p>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "login-02",
      "type": "registry:block",
      "title": "Login with Email, Password and Google",
      "description": "A login with email, password and google block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "input",
        "label",
        "separator"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/login/login-02.tsx",
          "type": "registry:component",
          "target": "components/login-02.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { JSX, SVGProps } from \"react\";\n\nconst GoogleIcon = (\n  props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>\n) => (\n  <svg fill=\"currentColor\" viewBox=\"0 0 24 24\" {...props}>\n    <path d=\"M3.06364 7.50914C4.70909 4.24092 8.09084 2 12 2C14.6954 2 16.959 2.99095 18.6909 4.60455L15.8227 7.47274C14.7864 6.48185 13.4681 5.97727 12 5.97727C9.39542 5.97727 7.19084 7.73637 6.40455 10.1C6.2045 10.7 6.09086 11.3409 6.09086 12C6.09086 12.6591 6.2045 13.3 6.40455 13.9C7.19084 16.2636 9.39542 18.0227 12 18.0227C13.3454 18.0227 14.4909 17.6682 15.3864 17.0682C16.4454 16.3591 17.15 15.3 17.3818 14.05H12V10.1818H21.4181C21.5364 10.8363 21.6 11.5182 21.6 12.2273C21.6 15.2727 20.5091 17.8363 18.6181 19.5773C16.9636 21.1046 14.7 22 12 22C8.09084 22 4.70909 19.7591 3.06364 16.4909C2.38638 15.1409 2 13.6136 2 12C2 10.3864 2.38638 8.85911 3.06364 7.50914Z\" />\n  </svg>\n);\n\nexport default function Login02() {\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <div className=\"flex flex-1 flex-col justify-center px-4 py-10 lg:px-6\">\n        <div className=\"sm:mx-auto sm:w-full sm:max-w-sm\">\n          <h2 className=\"text-balance text-center text-xl font-semibold text-foreground\">\n            Log in or create account\n          </h2>\n          <form action=\"#\" method=\"post\" className=\"mt-6 space-y-4\">\n            <div>\n              <Label\n                htmlFor=\"email-login-02\"\n                className=\"text-sm font-medium text-foreground dark:text-foreground\"\n              >\n                Email\n              </Label>\n              <Input\n                type=\"email\"\n                id=\"email-login-02\"\n                name=\"email-login-02\"\n                autoComplete=\"email\"\n                placeholder=\"ephraim@blocks.so\"\n                className=\"mt-2\"\n              />\n            </div>\n            <div>\n              <Label\n                htmlFor=\"password-login-02\"\n                className=\"text-sm font-medium text-foreground dark:text-foreground\"\n              >\n                Password\n              </Label>\n              <Input\n                type=\"password\"\n                id=\"password-login-02\"\n                name=\"password-login-02\"\n                autoComplete=\"password\"\n                placeholder=\"**************\"\n                className=\"mt-2\"\n              />\n            </div>\n            <Button type=\"submit\" className=\"mt-4 w-full py-2 font-medium\">\n              Sign in\n            </Button>\n          </form>\n\n          <div className=\"relative my-6\">\n            <div className=\"absolute inset-0 flex items-center\">\n              <Separator className=\"w-full\" />\n            </div>\n            <div className=\"relative flex justify-center text-xs uppercase\">\n              <span className=\"bg-background px-2 text-muted-foreground\">\n                or with\n              </span>\n            </div>\n          </div>\n\n          <Button\n            variant=\"outline\"\n            className=\"flex w-full items-center justify-center space-x-2 py-2\"\n            asChild\n          >\n            <a href=\"#\">\n              <GoogleIcon className=\"size-5\" aria-hidden={true} />\n              <span className=\"text-sm font-medium\">Sign in with Google</span>\n            </a>\n          </Button>\n\n          <p className=\"text-pretty mt-4 text-xs text-muted-foreground dark:text-muted-foreground\">\n            By signing in, you agree to our{\" \"}\n            <a href=\"#\" className=\"underline underline-offset-4\">\n              terms of service\n            </a>{\" \"}\n            and{\" \"}\n            <a href=\"#\" className=\"underline underline-offset-4\">\n              privacy policy\n            </a>\n            .\n          </p>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "login-03",
      "type": "registry:block",
      "title": "Login with Email and Password",
      "description": "A login with email and password block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "input",
        "label"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/login/login-03.tsx",
          "type": "registry:component",
          "target": "components/login-03.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\n\nexport default function Login03() {\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <div className=\"flex flex-1 flex-col justify-center px-4 py-10 lg:px-6\">\n        <div className=\"sm:mx-auto sm:w-full sm:max-w-sm\">\n          <h3 className=\"text-balance text-center text-lg font-semibold text-foreground dark:text-foreground\">\n            Welcome Back\n          </h3>\n          <p className=\"text-pretty text-center text-sm text-muted-foreground dark:text-muted-foreground\">\n            Enter your credentials to access your account.\n          </p>\n          <form action=\"#\" method=\"post\" className=\"mt-6 space-y-4\">\n            <div>\n              <Label\n                htmlFor=\"email-login-03\"\n                className=\"text-sm font-medium text-foreground dark:text-foreground\"\n              >\n                Email\n              </Label>\n              <Input\n                type=\"email\"\n                id=\"email-login-03\"\n                name=\"email-login-03\"\n                autoComplete=\"email\"\n                placeholder=\"ephraim@blocks.so\"\n                className=\"mt-2\"\n              />\n            </div>\n            <div>\n              <Label\n                htmlFor=\"password-login-03\"\n                className=\"text-sm font-medium text-foreground dark:text-foreground\"\n              >\n                Password\n              </Label>\n              <Input\n                type=\"password\"\n                id=\"password-login-03\"\n                name=\"password-login-03\"\n                autoComplete=\"password\"\n                placeholder=\"**************\"\n                className=\"mt-2\"\n              />\n            </div>\n            <Button type=\"submit\" className=\"mt-4 w-full py-2 font-medium\">\n              Sign in\n            </Button>\n          </form>\n          <p className=\"text-pretty mt-6 text-sm text-muted-foreground dark:text-muted-foreground\">\n            Forgot your password?{\" \"}\n            <a\n              href=\"#\"\n              className=\"font-medium text-primary hover:text-primary/90 dark:text-primary dark:hover:text-primary/90\"\n            >\n              Reset password\n            </a>\n          </p>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "login-04",
      "type": "registry:block",
      "title": "Login with Social Buttons",
      "description": "A login with social buttons block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "input",
        "label",
        "separator"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/login/login-04.tsx",
          "type": "registry:component",
          "target": "components/login-04.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { JSX, SVGProps } from \"react\";\n\nconst GitHubIcon = (\n  props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>\n) => (\n  <svg fill=\"currentColor\" viewBox=\"0 0 24 24\" {...props}>\n    <path d=\"M12.001 2C6.47598 2 2.00098 6.475 2.00098 12C2.00098 16.425 4.86348 20.1625 8.83848 21.4875C9.33848 21.575 9.52598 21.275 9.52598 21.0125C9.52598 20.775 9.51348 19.9875 9.51348 19.15C7.00098 19.6125 6.35098 18.5375 6.15098 17.975C6.03848 17.6875 5.55098 16.8 5.12598 16.5625C4.77598 16.375 4.27598 15.9125 5.11348 15.9C5.90098 15.8875 6.46348 16.625 6.65098 16.925C7.55098 18.4375 8.98848 18.0125 9.56348 17.75C9.65098 17.1 9.91348 16.6625 10.201 16.4125C7.97598 16.1625 5.65098 15.3 5.65098 11.475C5.65098 10.3875 6.03848 9.4875 6.67598 8.7875C6.57598 8.5375 6.22598 7.5125 6.77598 6.1375C6.77598 6.1375 7.61348 5.875 9.52598 7.1625C10.326 6.9375 11.176 6.825 12.026 6.825C12.876 6.825 13.726 6.9375 14.526 7.1625C16.4385 5.8625 17.276 6.1375 17.276 6.1375C17.826 7.5125 17.476 8.5375 17.376 8.7875C18.0135 9.4875 18.401 10.375 18.401 11.475C18.401 15.3125 16.0635 16.1625 13.8385 16.4125C14.201 16.725 14.5135 17.325 14.5135 18.2625C14.5135 19.6 14.501 20.675 14.501 21.0125C14.501 21.275 14.6885 21.5875 15.1885 21.4875C19.259 20.1133 21.9999 16.2963 22.001 12C22.001 6.475 17.526 2 12.001 2Z\" />\n  </svg>\n);\n\nconst GoogleIcon = (\n  props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>\n) => (\n  <svg fill=\"currentColor\" viewBox=\"0 0 24 24\" {...props}>\n    <path d=\"M3.06364 7.50914C4.70909 4.24092 8.09084 2 12 2C14.6954 2 16.959 2.99095 18.6909 4.60455L15.8227 7.47274C14.7864 6.48185 13.4681 5.97727 12 5.97727C9.39542 5.97727 7.19084 7.73637 6.40455 10.1C6.2045 10.7 6.09086 11.3409 6.09086 12C6.09086 12.6591 6.2045 13.3 6.40455 13.9C7.19084 16.2636 9.39542 18.0227 12 18.0227C13.3454 18.0227 14.4909 17.6682 15.3864 17.0682C16.4454 16.3591 17.15 15.3 17.3818 14.05H12V10.1818H21.4181C21.5364 10.8363 21.6 11.5182 21.6 12.2273C21.6 15.2727 20.5091 17.8363 18.6181 19.5773C16.9636 21.1046 14.7 22 12 22C8.09084 22 4.70909 19.7591 3.06364 16.4909C2.38638 15.1409 2 13.6136 2 12C2 10.3864 2.38638 8.85911 3.06364 7.50914Z\" />\n  </svg>\n);\n\nconst Logo = (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (\n  <svg\n    fill=\"currentColor\"\n    height=\"48\"\n    viewBox=\"0 0 40 48\"\n    width=\"40\"\n    {...props}\n  >\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n\nexport default function Login04() {\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <div className=\"flex flex-1 flex-col justify-center px-4 py-10 lg:px-6\">\n        <div className=\"sm:mx-auto sm:w-full sm:max-w-md\">\n          <div className=\"flex items-center space-x-1.5\">\n            <Logo\n              className=\"h-7 w-7 text-foreground dark:text-foreground\"\n              aria-hidden={true}\n            />\n            <p className=\"text-pretty font-medium text-lg text-foreground dark:text-foreground\">\n              Acme\n            </p>\n          </div>\n          <h3 className=\"text-balance mt-6 text-lg font-semibold text-foreground dark:text-foreground\">\n            Sign in to your account\n          </h3>\n          <p className=\"text-pretty mt-2 text-sm text-muted-foreground dark:text-muted-foreground\">\n            Don&apos;t have an account?{\" \"}\n            <a\n              href=\"#\"\n              className=\"font-medium text-primary hover:text-primary/90 dark:text-primary hover:dark:text-primary/90\"\n            >\n              Sign up\n            </a>\n          </p>\n          <div className=\"mt-8 flex flex-col items-center space-y-2 sm:flex-row sm:space-x-4 sm:space-y-0\">\n            <Button\n              variant=\"outline\"\n              className=\"flex-1 items-center justify-center space-x-2 py-2\"\n              asChild\n            >\n              <a href=\"#\">\n                <GitHubIcon className=\"size-5\" aria-hidden={true} />\n                <span className=\"text-sm font-medium\">Login with GitHub</span>\n              </a>\n            </Button>\n            <Button\n              variant=\"outline\"\n              className=\"mt-2 flex-1 items-center justify-center space-x-2 py-2 sm:mt-0\"\n              asChild\n            >\n              <a href=\"#\">\n                <GoogleIcon className=\"size-4\" aria-hidden={true} />\n                <span className=\"text-sm font-medium\">Login with Google</span>\n              </a>\n            </Button>\n          </div>\n\n          <div className=\"relative my-6\">\n            <div className=\"absolute inset-0 flex items-center\">\n              <Separator className=\"w-full\" />\n            </div>\n            <div className=\"relative flex justify-center text-xs uppercase\">\n              <span className=\"bg-background px-2 text-muted-foreground\">\n                or\n              </span>\n            </div>\n          </div>\n\n          <form action=\"#\" method=\"post\" className=\"mt-6 space-y-4\">\n            <div>\n              <Label\n                htmlFor=\"email-login-04\"\n                className=\"text-sm font-medium text-foreground dark:text-foreground\"\n              >\n                Email\n              </Label>\n              <Input\n                type=\"email\"\n                id=\"email-login-04\"\n                name=\"email-login-04\"\n                autoComplete=\"email\"\n                placeholder=\"ephraim@blocks.so\"\n                className=\"mt-2\"\n              />\n            </div>\n            <div>\n              <Label\n                htmlFor=\"password-login-04\"\n                className=\"text-sm font-medium text-foreground dark:text-foreground\"\n              >\n                Password\n              </Label>\n              <Input\n                type=\"password\"\n                id=\"password-login-04\"\n                name=\"password-login-04\"\n                autoComplete=\"password\"\n                placeholder=\"********\"\n                className=\"mt-2\"\n              />\n            </div>\n            <Button type=\"submit\" className=\"mt-4 w-full py-2 font-medium\">\n              Sign in\n            </Button>\n          </form>\n          <p className=\"text-pretty mt-6 text-sm text-muted-foreground dark:text-muted-foreground\">\n            Forgot your password?{\" \"}\n            <a\n              href=\"#\"\n              className=\"font-medium text-primary hover:text-primary/90 dark:text-primary hover:dark:text-primary/90\"\n            >\n              Reset password\n            </a>\n          </p>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "login-05",
      "type": "registry:block",
      "title": "Login Card Signup Form",
      "description": "A login card signup form block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "checkbox",
        "input",
        "label"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/login/login-05.tsx",
          "type": "registry:component",
          "target": "components/login-05.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { JSX, SVGProps } from \"react\";\n\nconst Logo = (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (\n  <svg fill=\"currentColor\" height=\"48\" viewBox=\"0 0 40 48\" width=\"40\" {...props}>\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n\nexport default function Login05() {\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <div className=\"flex flex-1 flex-col justify-center px-4 py-10 lg:px-6\">\n        <div className=\"sm:mx-auto sm:w-full sm:max-w-md\">\n          <Logo\n            className=\"mx-auto h-10 w-10 text-foreground dark:text-foreground\"\n            aria-hidden={true}\n          />\n          <h3 className=\"text-balance mt-2 text-center text-lg font-bold text-foreground dark:text-foreground\">\n            Create new account for workspace\n          </h3>\n        </div>\n\n        <Card className=\"mt-4 shadow-2xs sm:mx-auto sm:w-full sm:max-w-md\">\n          <CardContent>\n            <form action=\"#\" method=\"post\" className=\"space-y-4\">\n              <div>\n                <Label\n                  htmlFor=\"name-login-05\"\n                  className=\"text-sm font-medium text-foreground dark:text-foreground\"\n                >\n                  Name\n                </Label>\n                <Input\n                  type=\"text\"\n                  id=\"name-login-05\"\n                  name=\"name-login-05\"\n                  autoComplete=\"name-login-05\"\n                  placeholder=\"Name\"\n                  className=\"mt-2\"\n                />\n              </div>\n\n              <div>\n                <Label\n                  htmlFor=\"email-login-05\"\n                  className=\"text-sm font-medium text-foreground dark:text-foreground\"\n                >\n                  Email\n                </Label>\n                <Input\n                  type=\"email\"\n                  id=\"email-login-05\"\n                  name=\"email-login-05\"\n                  autoComplete=\"email-login-05\"\n                  placeholder=\"ephraim@blocks.so\"\n                  className=\"mt-2\"\n                />\n              </div>\n\n              <div>\n                <Label\n                  htmlFor=\"password-login-05\"\n                  className=\"text-sm font-medium text-foreground dark:text-foreground\"\n                >\n                  Password\n                </Label>\n                <Input\n                  type=\"password\"\n                  id=\"password-login-05   \"\n                  name=\"password-login-05\"\n                  autoComplete=\"password-login-05\"\n                  placeholder=\"Password\"\n                  className=\"mt-2\"\n                />\n              </div>\n\n              <div>\n                <Label\n                  htmlFor=\"confirm-password-login-05\"\n                  className=\"text-sm font-medium text-foreground dark:text-foreground\"\n                >\n                  Confirm password\n                </Label>\n                <Input\n                  type=\"password\"\n                  id=\"confirm-password-login-05\"\n                  name=\"confirm-password-login-05\"\n                  autoComplete=\"confirm-password-login-05\"\n                  placeholder=\"Password\"\n                  className=\"mt-2\"\n                />\n              </div>\n\n              <div className=\"mt-2 flex items-start\">\n                <div className=\"flex h-6 items-center\">\n                  <Checkbox\n                    id=\"newsletter-login-05\"\n                    name=\"newsletter-login-05\"\n                    className=\"size-4\"\n                  />\n                </div>\n                <Label\n                  htmlFor=\"newsletter-login-05\"\n                  className=\"ml-3 text-sm leading-6 text-muted-foreground dark:text-muted-foreground\"\n                >\n                  Sign up to our newsletter\n                </Label>\n              </div>\n\n              <Button type=\"submit\" className=\"mt-4 w-full py-2 font-medium\">\n                Create account\n              </Button>\n\n              <p className=\"text-pretty text-center text-xs text-muted-foreground dark:text-muted-foreground\">\n                By signing in, you agree to our{\" \"}\n                <a\n                  href=\"#\"\n                  className=\"capitalize text-primary hover:text-primary/90 dark:text-primary hover:dark:text-primary/90\"\n                >\n                  Terms of use\n                </a>{\" \"}\n                and{\" \"}\n                <a\n                  href=\"#\"\n                  className=\"capitalize text-primary hover:text-primary/90 dark:text-primary hover:dark:text-primary/90\"\n                >\n                  Privacy policy\n                </a>\n              </p>\n            </form>\n          </CardContent>\n        </Card>\n\n        <p className=\"text-pretty mt-6 text-center text-sm text-muted-foreground dark:text-muted-foreground\">\n          Already have an account?{\" \"}\n          <a\n            href=\"#\"\n            className=\"font-medium text-primary hover:text-primary/90 dark:text-primary hover:dark:text-primary/90\"\n          >\n            Sign in\n          </a>\n        </p>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "login-06",
      "type": "registry:block",
      "title": "Login with Magic Link and SSO",
      "description": "A login with magic link and sso block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "input",
        "separator"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/login/login-06.tsx",
          "type": "registry:component",
          "target": "components/login-06.tsx",
          "content": "import { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { JSX, SVGProps } from \"react\";\n\nconst Logo = (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (\n  <svg fill=\"currentColor\" height=\"48\" viewBox=\"0 0 40 48\" width=\"40\" {...props}>\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n\nexport default function Login06() {\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <Card className=\"w-full max-w-sm rounded-4xl px-6 py-10 pt-14 shadow-2xs\">\n        <CardContent className=\"\">\n          <div className=\"flex flex-col items-center space-y-8\">\n            <Logo />\n\n            <div className=\"space-y-2 text-center\">\n              <h1 className=\"text-balance text-3xl font-semibold text-foreground\">Welcome back!</h1>\n              <p className=\"text-pretty text-muted-foreground text-sm\">\n                First time here?{\" \"}\n                <a href=\"#\" className=\"text-foreground hover:underline\">\n                  Sign up for free\n                </a>\n              </p>\n            </div>\n\n            <div className=\"w-full space-y-4\">\n              <Input type=\"email\" placeholder=\"Your email\" className=\"w-full rounded-xl\" />\n              <div className=\"flex flex-col gap-2\">\n                <Button className=\"w-full rounded-xl\" size=\"lg\">\n                  Send me the magic link\n                </Button>\n                <Button variant=\"link\" className=\"w-full text-sm text-muted-foreground\">\n                  Sign in using password\n                </Button>\n              </div>\n\n              <div className=\"flex items-center gap-4 py-2\">\n                <Separator className=\"flex-1\" />\n                <span className=\"text-sm text-muted-foreground\">OR</span>\n                <Separator className=\"flex-1\" />\n              </div>\n\n              <Button variant=\"outline\" className=\"w-full rounded-xl\" size=\"lg\">\n                Single sign-on (SSO)\n              </Button>\n            </div>\n\n            <p className=\"text-pretty text-center text-xs w-11/12 text-muted-foreground\">\n              You acknowledge that you read, and agree, to our{\" \"}\n              <a href=\"#\" className=\"underline hover:text-foreground\">\n                Terms of Service\n              </a>{\" \"}\n              and our{\" \"}\n              <a href=\"#\" className=\"underline hover:text-foreground\">\n                Privacy Policy\n              </a>\n              .\n            </p>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "login-07",
      "type": "registry:block",
      "title": "Login Full Page with Icons",
      "description": "A login full page with icons block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "checkbox",
        "input",
        "label",
        "separator"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/login/login-07.tsx",
          "type": "registry:component",
          "target": "components/login-07.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Separator } from \"@/components/ui/separator\";\nimport { ArrowRight, Eye, EyeOff, Lock, Mail } from \"lucide-react\";\nimport { JSX, SVGProps, useState } from \"react\";\n\nconst GoogleIcon = (\n  props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>\n) => (\n  <svg fill=\"currentColor\" viewBox=\"0 0 24 24\" {...props}>\n    <path d=\"M3.06364 7.50914C4.70909 4.24092 8.09084 2 12 2C14.6954 2 16.959 2.99095 18.6909 4.60455L15.8227 7.47274C14.7864 6.48185 13.4681 5.97727 12 5.97727C9.39542 5.97727 7.19084 7.73637 6.40455 10.1C6.2045 10.7 6.09086 11.3409 6.09086 12C6.09086 12.6591 6.2045 13.3 6.40455 13.9C7.19084 16.2636 9.39542 18.0227 12 18.0227C13.3454 18.0227 14.4909 17.6682 15.3864 17.0682C16.4454 16.3591 17.15 15.3 17.3818 14.05H12V10.1818H21.4181C21.5364 10.8363 21.6 11.5182 21.6 12.2273C21.6 15.2727 20.5091 17.8363 18.6181 19.5773C16.9636 21.1046 14.7 22 12 22C8.09084 22 4.70909 19.7591 3.06364 16.4909C2.38638 15.1409 2 13.6136 2 12C2 10.3864 2.38638 8.85911 3.06364 7.50914Z\" />\n  </svg>\n);\n\nconst Logo = (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (\n  <svg\n    fill=\"currentColor\"\n    height=\"48\"\n    viewBox=\"0 0 40 48\"\n    width=\"40\"\n    {...props}\n  >\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n\nexport default function Login07() {\n  const [isVisible, setIsVisible] = useState<boolean>(false);\n\n  const toggleVisibility = () => setIsVisible((prevState) => !prevState);\n\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <div className=\"mx-auto w-full max-w-xs space-y-6\">\n        <div className=\"space-y-2 text-center\">\n          <Logo className=\"mx-auto h-16 w-16\" />\n          <h1 className=\"text-balance text-3xl font-semibold\">Welcome back</h1>\n          <p className=\"text-pretty text-muted-foreground\">\n            Sign in to access to your dashboard, settings and projects.\n          </p>\n        </div>\n\n        <div className=\"space-y-5\">\n          <Button variant=\"outline\" className=\"w-full justify-center gap-2\">\n            <GoogleIcon className=\"h-4 w-4\" />\n            Sign in with Google\n          </Button>\n\n          <div className=\"flex items-center gap-2\">\n            <Separator className=\"flex-1\" />\n            <span className=\"text-sm text-muted-foreground\">\n              or sign in with email\n            </span>\n            <Separator className=\"flex-1\" />\n          </div>\n\n          <div className=\"space-y-6\">\n            <div>\n              <Label htmlFor=\"email\">Email</Label>\n              <div className=\"relative mt-2.5\">\n                <Input\n                  id=\"email\"\n                  className=\"peer ps-9\"\n                  placeholder=\"ephraim@blocks.so\"\n                  type=\"email\"\n                />\n                <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n                  <Mail size={16} aria-hidden=\"true\" />\n                </div>\n              </div>\n            </div>\n\n            <div>\n              <div className=\"flex items-center justify-between\">\n                <Label htmlFor=\"password\">Password</Label>\n                <a href=\"#\" className=\"text-sm text-primary hover:underline\">\n                  Forgot Password?\n                </a>\n              </div>\n              <div className=\"relative mt-2.5\">\n                <Input\n                  id=\"password\"\n                  className=\"ps-9 pe-9\"\n                  placeholder=\"Enter your password\"\n                  type={isVisible ? \"text\" : \"password\"}\n                />\n                <div className=\"text-muted-foreground/80 pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 peer-disabled:opacity-50\">\n                  <Lock size={16} aria-hidden=\"true\" />\n                </div>\n                <button\n                  className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n                  type=\"button\"\n                  onClick={toggleVisibility}\n                  aria-label={isVisible ? \"Hide password\" : \"Show password\"}\n                  aria-pressed={isVisible}\n                  aria-controls=\"password\"\n                >\n                  {isVisible ? (\n                    <EyeOff size={16} aria-hidden=\"true\" />\n                  ) : (\n                    <Eye size={16} aria-hidden=\"true\" />\n                  )}\n                </button>\n              </div>\n            </div>\n\n            <div className=\"flex items-center gap-2 pt-1\">\n              <Checkbox id=\"remember-me\" />\n              <Label htmlFor=\"remember-me\">Remember for 30 days</Label>\n            </div>\n          </div>\n\n          <Button className=\"w-full\">\n            Sign in\n            <ArrowRight className=\"h-4 w-4\" />\n          </Button>\n\n          <div className=\"text-center text-sm\">\n            No account?{\" \"}\n            <a href=\"#\" className=\"text-primary font-medium hover:underline\">\n              Create an account\n            </a>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "login-08",
      "type": "registry:block",
      "title": "Login with SSO",
      "description": "A login with sso block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "checkbox",
        "input",
        "label"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/login/login-08.tsx",
          "type": "registry:component",
          "target": "components/login-08.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardFooter, CardHeader } from \"@/components/ui/card\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { EyeIcon, EyeOffIcon, Key } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { JSX, SVGProps, useState } from \"react\";\n\nconst Logo = (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (\n  <svg fill=\"currentColor\" height=\"48\" viewBox=\"0 0 40 48\" width=\"40\" {...props}>\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n\nexport default function SignIn() {\n  const [isPasswordVisible, setIsPasswordVisible] = useState<boolean>(false);\n\n  const togglePasswordVisibility = () => setIsPasswordVisible((prev) => !prev);\n\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <Card className=\"w-full max-w-md mx-4 pb-0 shadow-2xs\">\n        <CardHeader className=\"space-y-1 text-center mb-2 mt-4\">\n          <div className=\"flex justify-center\">\n            <Logo />\n          </div>\n          <div>\n            <h2 className=\"text-balance text-2xl font-semibold\">Sign in to Acme</h2>\n            <p className=\"text-pretty text-muted-foreground text-sm\">\n              Welcome back! Please enter your details.\n            </p>\n          </div>\n        </CardHeader>\n        <CardContent className=\"space-y-6\">\n          <div className=\"space-y-2\">\n            <Label htmlFor=\"email\">Email address</Label>\n            <Input id=\"email\" type=\"email\" placeholder=\"ephraim@blocks.so\" />\n          </div>\n          <div className=\"space-y-0\">\n            <div className=\"flex items-center justify-between mb-2\">\n              <Label htmlFor=\"password\">Password</Label>\n              <Link href=\"#\" className=\"text-sm text-primary hover:underline\">\n                Reset password\n              </Link>\n            </div>\n            <div className=\"relative\">\n              <Input\n                id=\"password\"\n                className=\"pe-9\"\n                placeholder=\"Enter your password\"\n                type={isPasswordVisible ? \"text\" : \"password\"}\n              />\n              <button\n                className=\"text-muted-foreground/80 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 absolute inset-y-0 end-0 flex h-full w-9 items-center justify-center rounded-e-md transition-[color,box-shadow] outline-none focus:z-10 focus-visible:ring-[3px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n                type=\"button\"\n                onClick={togglePasswordVisibility}\n                aria-label={isPasswordVisible ? \"Hide password\" : \"Show password\"}\n                aria-pressed={isPasswordVisible}\n                aria-controls=\"password\"\n              >\n                {isPasswordVisible ? (\n                  <EyeOffIcon size={16} aria-hidden=\"true\" />\n                ) : (\n                  <EyeIcon size={16} aria-hidden=\"true\" />\n                )}\n              </button>\n            </div>\n          </div>\n          <div className=\"flex items-center space-x-2\">\n            <Checkbox id=\"remember\" defaultChecked />\n            <Label htmlFor=\"remember\" className=\"text-sm font-normal\">\n              Remember me\n            </Label>\n          </div>\n\n          <div className=\"space-y-2\">\n            <Button className=\"w-full\" type=\"submit\">\n              Sign In\n            </Button>\n            <Button variant=\"outline\" className=\"w-full\" type=\"button\">\n              <Key className=\"mr-2 h-4 w-4\" />\n              Single sign-on (SSO)\n            </Button>\n          </div>\n        </CardContent>\n        <CardFooter className=\"flex justify-center border-t py-4!\">\n          <p className=\"text-pretty text-center text-sm text-muted-foreground\">\n            New to Acme?{\" \"}\n            <Link href=\"#\" className=\"text-primary hover:underline\">\n              Sign up\n            </Link>\n          </p>\n        </CardFooter>\n      </Card>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "login-09",
      "type": "registry:block",
      "title": "Login Signup with Role Selection",
      "description": "A login signup with role selection block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "checkbox",
        "input",
        "label",
        "select"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/login/login-09.tsx",
          "type": "registry:component",
          "target": "components/login-09.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Card,\n  CardContent,\n  CardFooter,\n  CardHeader,\n} from \"@/components/ui/card\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport { BarChart, Code, Eye, EyeOff, User } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { JSX, SVGProps, useState } from \"react\";\n\nconst Logo = (props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) => (\n  <svg\n    fill=\"currentColor\"\n    height=\"48\"\n    viewBox=\"0 0 40 48\"\n    width=\"40\"\n    {...props}\n  >\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n\nexport default function SignupForm() {\n  const [showPassword, setShowPassword] = useState(false);\n\n  return (\n    <div className=\"flex items-center justify-center min-h-dvh\">\n      <div className=\"w-full max-w-md\">\n        <Card className=\"border-none shadow-lg pb-0\">\n          <CardHeader className=\"flex flex-col items-center space-y-1.5 pb-4 pt-6\">\n            <Logo className=\"w-12 h-12\" />\n            <div className=\"space-y-0.5 flex flex-col items-center\">\n              <h2 className=\"text-balance text-2xl font-semibold text-foreground\">\n                Create an account\n              </h2>\n              <p className=\"text-pretty text-muted-foreground\">\n                Welcome! Create an account to get started.\n              </p>\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-6 px-8\">\n            <div className=\"space-y-2\">\n              <Label htmlFor=\"role\">Role</Label>\n              <Select defaultValue=\"designer\">\n                <SelectTrigger\n                  id=\"role\"\n                  className=\"[&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0\"\n                >\n                  <SelectValue placeholder=\"Select role\" />\n                </SelectTrigger>\n                <SelectContent className=\"[&_*[role=option]]:ps-2 [&_*[role=option]]:pe-8 [&_*[role=option]>span]:start-auto [&_*[role=option]>span]:end-2 [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0\">\n                  <SelectItem value=\"designer\">\n                    <User size={16} aria-hidden=\"true\" />\n                    <span className=\"truncate\">Product Designer</span>\n                  </SelectItem>\n                  <SelectItem value=\"developer\">\n                    <Code size={16} aria-hidden=\"true\" />\n                    <span className=\"truncate\">Developer</span>\n                  </SelectItem>\n                  <SelectItem value=\"manager\">\n                    <BarChart size={16} aria-hidden=\"true\" />\n                    <span className=\"truncate\">Product Manager</span>\n                  </SelectItem>\n                </SelectContent>\n              </Select>\n            </div>\n\n            <div className=\"grid grid-cols-2 gap-4\">\n              <div className=\"space-y-2\">\n                <Label htmlFor=\"firstName\">First name</Label>\n                <Input id=\"firstName\" />\n              </div>\n              <div className=\"space-y-2\">\n                <Label htmlFor=\"lastName\">Last name</Label>\n                <Input id=\"lastName\" />\n              </div>\n            </div>\n\n            <div className=\"space-y-2\">\n              <Label htmlFor=\"username\">Username</Label>\n              <Input id=\"username\" />\n            </div>\n\n            <div className=\"space-y-2\">\n              <Label htmlFor=\"email\">Email address</Label>\n              <Input id=\"email\" type=\"email\" />\n            </div>\n\n            <div className=\"space-y-2\">\n              <Label htmlFor=\"password\">Password</Label>\n              <div className=\"relative\">\n                <Input\n                  id=\"password\"\n                  type={showPassword ? \"text\" : \"password\"}\n                  className=\"pr-10\"\n                />\n                <Button\n                  type=\"button\"\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  className=\"absolute right-0 top-0 h-full px-3 text-muted-foreground hover:bg-transparent\"\n                  onClick={() => setShowPassword(!showPassword)}\n                >\n                  {showPassword ? (\n                    <EyeOff className=\"h-4 w-4\" />\n                  ) : (\n                    <Eye className=\"h-4 w-4\" />\n                  )}\n                </Button>\n              </div>\n            </div>\n\n            <div className=\"flex items-center space-x-2\">\n              <Checkbox id=\"terms\" />\n              <label htmlFor=\"terms\" className=\"text-sm text-muted-foreground\">\n                I agree to the{\" \"}\n                <Link href=\"#\" className=\"text-primary hover:underline\">\n                  Terms\n                </Link>{\" \"}\n                and{\" \"}\n                <Link href=\"#\" className=\"text-primary hover:underline\">\n                  Conditions\n                </Link>\n              </label>\n            </div>\n\n            <Button className=\"w-full bg-primary text-primary-foreground\">\n              Create free account\n            </Button>\n          </CardContent>\n          <CardFooter className=\"flex justify-center border-t py-4!\">\n            <p className=\"text-pretty text-center text-sm text-muted-foreground\">\n              Already have an account?{\" \"}\n              <Link href=\"#\" className=\"text-primary hover:underline\">\n                Sign in\n              </Link>\n            </p>\n          </CardFooter>\n        </Card>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "login"
      ]
    },
    {
      "name": "onboarding-01",
      "type": "registry:block",
      "title": "Onboarding",
      "description": "A onboarding block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "collapsible",
        "dropdown-menu"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/onboarding/onboarding-01.tsx",
          "type": "registry:component",
          "target": "components/onboarding-01.tsx",
          "content": "'use client';\n\nimport {\n  IconArchive,\n  IconChevronRight,\n  IconCircleCheckFilled,\n  IconCircleDashed,\n  IconDots,\n  IconMail,\n} from '@tabler/icons-react';\nimport { useState } from 'react';\nimport { Button } from '@/components/ui/button';\nimport { Collapsible, CollapsibleContent } from '@/components/ui/collapsible';\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { cn } from '@/lib/utils';\n\nconst steps = [\n  {\n    id: 'profile',\n    title: 'Complete your profile',\n    description:\n      'Add your name, photo, and role so your team knows who you are.',\n    completed: true,\n    actionLabel: 'Edit profile',\n    actionHref: '#',\n  },\n  {\n    id: 'workspace',\n    title: 'Set up your workspace',\n    description:\n      'Customize your workspace with a name, icon, and default settings.',\n    completed: false,\n    actionLabel: 'Configure workspace',\n    actionHref: '#',\n  },\n  {\n    id: 'invite',\n    title: 'Invite your team',\n    description:\n      'Bring your teammates on board so you can collaborate in real time.',\n    completed: false,\n    actionLabel: 'Send invites',\n    actionHref: '#',\n  },\n  {\n    id: 'integrations',\n    title: 'Connect integrations',\n    description:\n      'Link your favorite tools like Slack, GitHub, and Linear to streamline workflows.',\n    completed: false,\n    actionLabel: 'Browse integrations',\n    actionHref: '#',\n  },\n  {\n    id: 'workflow',\n    title: 'Create your first workflow',\n    description:\n      'Automate a repetitive task with a simple drag-and-drop workflow builder.',\n    completed: false,\n    actionLabel: 'Build workflow',\n    actionHref: '#',\n  },\n  {\n    id: 'notifications',\n    title: 'Set up notifications',\n    description:\n      'Choose how and when you want to be notified about updates and mentions.',\n    completed: false,\n    actionLabel: 'Manage notifications',\n    actionHref: '#',\n  },\n];\n\ninterface OnboardingStep {\n  id: string;\n  title: string;\n  description: string;\n  completed: boolean;\n  actionLabel: string;\n  actionHref: string;\n}\n\nfunction CircularProgress({\n  completed,\n  total,\n}: {\n  completed: number;\n  total: number;\n}) {\n  const progress = total > 0 ? ((total - completed) / total) * 100 : 0;\n  const strokeDashoffset = 100 - progress;\n\n  return (\n    <svg\n      className=\"-rotate-90\"\n      height=\"14\"\n      viewBox=\"0 0 14 14\"\n      width=\"14\"\n    >\n      <circle\n        className=\"stroke-muted\"\n        cx=\"7\"\n        cy=\"7\"\n        fill=\"none\"\n        pathLength=\"100\"\n        r=\"6\"\n        strokeWidth=\"2\"\n      />\n      <circle\n        className=\"stroke-primary\"\n        cx=\"7\"\n        cy=\"7\"\n        fill=\"none\"\n        pathLength=\"100\"\n        r=\"6\"\n        strokeDasharray=\"100\"\n        strokeLinecap=\"round\"\n        strokeWidth=\"2\"\n        style={{ strokeDashoffset }}\n      />\n    </svg>\n  );\n}\n\nfunction StepIndicator({ completed }: { completed: boolean }) {\n  if (completed) {\n    return (\n      <IconCircleCheckFilled\n        aria-hidden=\"true\"\n        className=\"mt-1 size-4.5 shrink-0 text-primary\"\n      />\n    );\n  }\n  return (\n    <IconCircleDashed\n      aria-hidden=\"true\"\n      className=\"mt-1 size-5 shrink-0 stroke-muted-foreground/40\"\n      strokeWidth={2}\n    />\n  );\n}\n\nexport function Onboarding01() {\n  const [currentSteps, setCurrentSteps] = useState<OnboardingStep[]>(steps);\n  const [openStepId, setOpenStepId] = useState<string | null>(() => {\n    const firstIncomplete = steps.find((s) => !s.completed);\n    return firstIncomplete?.id ?? steps[0]?.id ?? null;\n  });\n  const [dismissed, setDismissed] = useState(false);\n\n  const completedCount = currentSteps.filter((s) => s.completed).length;\n  const remainingCount = currentSteps.length - completedCount;\n\n  const handleStepClick = (stepId: string) => {\n    setOpenStepId(openStepId === stepId ? null : stepId);\n  };\n\n  const handleStepAction = (step: OnboardingStep) => {\n    const updated = currentSteps.map((s) =>\n      s.id === step.id ? { ...s, completed: true } : s\n    );\n    setCurrentSteps(updated);\n    const nextIncomplete = updated.find((s) => !s.completed);\n    setOpenStepId(nextIncomplete?.id ?? null);\n  };\n\n  if (dismissed) {\n    return (\n      <div className=\"flex min-h-dvh items-center justify-center bg-background p-4\">\n        <div className=\"text-center\">\n          <p className=\"text-pretty text-muted-foreground\">\n            Checklist dismissed\n          </p>\n          <button\n            className=\"mt-2 text-primary text-sm underline\"\n            onClick={() => setDismissed(false)}\n          >\n            Show again\n          </button>\n        </div>\n      </div>\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-lg\">\n        <div className=\"w-md rounded-lg border bg-card p-4 text-card-foreground shadow-xs\">\n          <div className=\"mr-2 mb-4 flex flex-col justify-between sm:flex-row sm:items-center\">\n            <h3 className=\"ml-2 text-balance font-semibold text-foreground\">\n              Get started with Acme\n            </h3>\n            <div className=\"mt-2 flex items-center justify-end sm:mt-0\">\n              <CircularProgress\n                completed={remainingCount}\n                total={currentSteps.length}\n              />\n              <div className=\"mr-3 ml-1.5 text-muted-foreground text-sm\">\n                <span className=\"font-medium text-foreground\">\n                  {completedCount}\n                </span>\n                {' / '}\n                <span className=\"font-medium text-foreground\">\n                  {currentSteps.length}\n                </span>{' '}\n                completed\n              </div>\n              <DropdownMenu>\n                <DropdownMenuTrigger asChild>\n                  <Button className=\"h-6 w-6\" size=\"icon\" variant=\"ghost\">\n                    <IconDots aria-hidden=\"true\" className=\"h-4 w-4 shrink-0\" />\n                    <span className=\"sr-only\">Options</span>\n                  </Button>\n                </DropdownMenuTrigger>\n                <DropdownMenuContent align=\"end\" className=\"w-40\">\n                  <DropdownMenuItem onClick={() => setDismissed(true)}>\n                    <IconArchive\n                      aria-hidden=\"true\"\n                      className=\"mr-2 h-4 w-4 shrink-0\"\n                    />\n                    Dismiss\n                  </DropdownMenuItem>\n                  <DropdownMenuItem\n                    onClick={() =>\n                      window.open('mailto:support@acme.com?subject=Feedback')\n                    }\n                  >\n                    <IconMail\n                      aria-hidden=\"true\"\n                      className=\"mr-2 h-4 w-4 shrink-0\"\n                    />\n                    Give feedback\n                  </DropdownMenuItem>\n                </DropdownMenuContent>\n              </DropdownMenu>\n            </div>\n          </div>\n\n          <div className=\"space-y-0\">\n            {currentSteps.map((step, index) => {\n              const isOpen = openStepId === step.id;\n              const isFirst = index === 0;\n              const prevStep = currentSteps[index - 1];\n              const isPrevOpen = prevStep && openStepId === prevStep.id;\n\n              const showBorderTop = !(isFirst || isOpen || isPrevOpen);\n\n              return (\n                <div\n                  className={cn(\n                    'group',\n                    isOpen && 'rounded-lg',\n                    showBorderTop && 'border-border border-t'\n                  )}\n                  key={step.id}\n                >\n                  <div\n                    className={cn(\n                      'block w-full cursor-pointer text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n                      isOpen && 'rounded-lg'\n                    )}\n                    onClick={() => handleStepClick(step.id)}\n                    onKeyDown={(e) => {\n                      if (e.key === 'Enter' || e.key === ' ') {\n                        e.preventDefault();\n                        handleStepClick(step.id);\n                      }\n                    }}\n                    role=\"button\"\n                    tabIndex={0}\n                  >\n                    <div\n                      className={cn(\n                        'relative overflow-hidden rounded-lg transition-colors',\n                        isOpen && 'border border-border bg-muted'\n                      )}\n                    >\n                      <div className=\"relative flex items-center justify-between gap-3 py-3 pr-2 pl-4\">\n                        <div className=\"flex w-full gap-3\">\n                          <div className=\"shrink-0\">\n                            <StepIndicator completed={step.completed} />\n                          </div>\n                          <div className=\"mt-0.5 grow\">\n                            <h4\n                              className={cn(\n                                'font-semibold',\n                                step.completed\n                                  ? 'text-primary'\n                                  : 'text-foreground'\n                              )}\n                            >\n                              {step.title}\n                            </h4>\n                            <Collapsible open={isOpen}>\n                              <CollapsibleContent>\n                                <p className=\"mt-2 text-pretty text-muted-foreground text-sm sm:max-w-64 md:max-w-xs\">\n                                  {step.description}\n                                </p>\n                                <Button\n                                  asChild\n                                  className=\"mt-3\"\n                                  onClick={(e) => {\n                                    e.stopPropagation();\n                                    handleStepAction(step);\n                                  }}\n                                  size=\"sm\"\n                                >\n                                  <a href={step.actionHref}>\n                                    {step.actionLabel}\n                                  </a>\n                                </Button>\n                              </CollapsibleContent>\n                            </Collapsible>\n                          </div>\n                        </div>\n                        {!isOpen && (\n                          <IconChevronRight\n                            aria-hidden=\"true\"\n                            className=\"h-4 w-4 shrink-0 text-muted-foreground\"\n                          />\n                        )}\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              );\n            })}\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "onboarding"
      ]
    },
    {
      "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"
      ]
    },
    {
      "name": "onboarding-03",
      "type": "registry:block",
      "title": "Onboarding Steps with Progress",
      "description": "A onboarding steps with progress block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "progress"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/onboarding/onboarding-03.tsx",
          "type": "registry:component",
          "target": "components/onboarding-03.tsx",
          "content": "'use client';\n\nimport { IconCircleCheckFilled } from '@tabler/icons-react';\nimport { useState } from 'react';\nimport { Progress } from '@/components/ui/progress';\nimport { cn } from '@/lib/utils';\n\nconst steps = [\n  {\n    id: '1.',\n    title: 'Create your store',\n    description:\n      \"Choose a name, pick a subdomain, and configure your store's basic settings.\",\n  },\n  {\n    id: '2.',\n    title: 'Add your products',\n    description:\n      'Upload your catalog with photos, pricing, and inventory details.',\n  },\n  {\n    id: '3.',\n    title: 'Set up payments',\n    description:\n      'Connect Stripe or PayPal to start accepting orders from customers.',\n  },\n  {\n    id: '4.',\n    title: 'Launch your store',\n    description: 'Review everything and publish your storefront to the world.',\n  },\n];\n\nexport function Onboarding03() {\n  const [activeStep, setActiveStep] = useState(0);\n\n  return (\n    <div className=\"flex min-h-dvh items-center justify-center bg-background p-4\">\n      <div className=\"sm:mx-auto sm:max-w-lg\">\n        <h3 className=\"font-semibold text-foreground text-lg\">Store setup</h3>\n        <p className=\"mt-1 text-muted-foreground text-sm leading-6\">\n          Complete each step to launch your online store.\n        </p>\n        <div className=\"mt-4 flex items-center justify-end space-x-4\">\n          <span className=\"text-muted-foreground text-sm\">\n            Step {activeStep + 1}/{steps.length}\n          </span>\n          <Progress\n            className=\"w-32\"\n            value={(activeStep / steps.length) * 100}\n          />\n        </div>\n        <ul className=\"mt-4 space-y-4\">\n          {steps.map((step, index) => (\n            <li key={step.id}>\n              <button\n                className={cn(\n                  'relative w-full cursor-pointer rounded-lg border bg-card p-4 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n                  index === activeStep\n                    ? 'border-foreground/20'\n                    : 'border-border'\n                )}\n                onClick={() => setActiveStep(index)}\n                type=\"button\"\n              >\n                <div className=\"flex items-start space-x-3\">\n                  {index < activeStep ? (\n                    <IconCircleCheckFilled\n                      aria-hidden={true}\n                      className=\"size-6 shrink-0 text-foreground\"\n                    />\n                  ) : (\n                    <span\n                      aria-hidden={true}\n                      className=\"flex size-6 items-center justify-center font-medium text-muted-foreground\"\n                    >\n                      {step.id}\n                    </span>\n                  )}\n                  <div>\n                    <h3\n                      className={cn(\n                        'font-medium',\n                        index < activeStep\n                          ? 'text-muted-foreground line-through'\n                          : 'text-foreground'\n                      )}\n                    >\n                      {step.title}\n                    </h3>\n                    <p className=\"mt-1 text-muted-foreground text-sm leading-6\">\n                      {step.description}\n                    </p>\n                  </div>\n                </div>\n              </button>\n            </li>\n          ))}\n        </ul>\n        <div className=\"mt-6 rounded-lg bg-muted p-4\">\n          <h4 className=\"font-medium text-foreground text-sm\">Need help?</h4>\n          <p className=\"mt-1 text-muted-foreground text-sm\">\n            Connect with a member of our team at{' '}\n            <a\n              className=\"font-medium text-primary\"\n              href=\"mailto:help@example.com\"\n            >\n              help@example.com\n            </a>\n            .\n          </p>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "onboarding"
      ]
    },
    {
      "name": "onboarding-04",
      "type": "registry:block",
      "title": "Onboarding Accordion",
      "description": "A onboarding accordion block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "accordion",
        "button"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/onboarding/onboarding-04.tsx",
          "type": "registry:component",
          "target": "components/onboarding-04.tsx",
          "content": "'use client';\n\nimport {\n  IconAdjustments,\n  IconCalculator,\n  IconChartBar,\n  IconCircleCheckFilled,\n  IconDatabase,\n} from '@tabler/icons-react';\nimport { useState } from 'react';\nimport {\n  Accordion,\n  AccordionContent,\n  AccordionItem,\n  AccordionTrigger,\n} from '@/components/ui/accordion';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\nconst steps = [\n  {\n    title: 'Configure your environment',\n    subtitle: 'Environment ready',\n    icon: IconAdjustments,\n    description:\n      'Set up your development environment with API keys and preferences.',\n    buttonText: 'Edit settings',\n  },\n  {\n    title: 'Connect your database',\n    subtitle: 'Add connection',\n    icon: IconDatabase,\n    description:\n      'Link your PostgreSQL, MySQL, or MongoDB instance to get started.',\n    buttonText: 'Add database',\n  },\n  {\n    title: 'Define your schema',\n    subtitle: 'Create schema',\n    icon: IconCalculator,\n    description: 'Model your data with types, relations, and validation rules.',\n    buttonText: 'Open editor',\n  },\n  {\n    title: 'Build your first API',\n    subtitle: 'Generate endpoints',\n    icon: IconChartBar,\n    description:\n      'Auto-generate REST or GraphQL endpoints from your schema in seconds.',\n    buttonText: 'Generate API',\n  },\n];\n\nexport function Onboarding04() {\n  const [activeStep, setActiveStep] = useState(1);\n\n  const [openItem, setOpenItem] = useState(\n    activeStep < steps.length ? steps[activeStep].title : ''\n  );\n\n  const handleComplete = () => {\n    const next = activeStep + 1;\n    setActiveStep(next);\n    setOpenItem(next < steps.length ? steps[next].title : '');\n  };\n\n  return (\n    <div className=\"flex min-h-dvh items-center justify-center bg-background p-4\">\n      <div className=\"mx-auto w-full min-w-0 max-w-sm sm:min-w-sm\">\n        <h3 className=\"font-semibold text-foreground text-lg\">Quick start</h3>\n        <p className=\"mt-1 text-muted-foreground text-sm\">\n          Set up your backend in four simple steps\n        </p>\n        <Accordion\n          className=\"mt-6 space-y-2\"\n          collapsible\n          onValueChange={setOpenItem}\n          type=\"single\"\n          value={openItem}\n        >\n          {steps.map((step, index) => {\n            let status: 'complete' | 'current' | 'upcoming' = 'upcoming';\n            if (index < activeStep) {\n              status = 'complete';\n            } else if (index === activeStep) {\n              status = 'current';\n            }\n\n            return (\n              <AccordionItem\n                className=\"!border-b rounded-lg border shadow-xs\"\n                key={step.title}\n                value={step.title}\n              >\n                <AccordionTrigger className=\"px-4 hover:no-underline\">\n                  <div className=\"flex items-center space-x-2\">\n                    {status === 'complete' ? (\n                      <span\n                        aria-hidden\n                        className=\"flex size-5 items-center justify-center\"\n                      >\n                        <IconCircleCheckFilled\n                          aria-hidden\n                          className=\"size-6 shrink-0 text-foreground\"\n                        />\n                      </span>\n                    ) : (\n                      <span\n                        aria-hidden\n                        className=\"size-5 shrink-0 rounded-full border border-border\"\n                      />\n                    )}\n                    <p\n                      className={cn(\n                        'font-medium text-sm',\n                        status === 'upcoming'\n                          ? 'text-muted-foreground/60'\n                          : 'text-foreground'\n                      )}\n                    >\n                      {step.title}\n                    </p>\n                  </div>\n                </AccordionTrigger>\n                <AccordionContent className=\"px-4\">\n                  <div className=\"flex items-center justify-center rounded-md bg-muted px-4 py-5 ring-1 ring-ring ring-inset\">\n                    <div className=\"max-w-xs text-center\">\n                      <step.icon\n                        aria-hidden\n                        className=\"mx-auto size-7 shrink-0 text-muted-foreground\"\n                      />\n                      <p className=\"mt-4 font-semibold text-muted-foreground text-sm\">\n                        {step.subtitle}\n                      </p>\n                      <p className=\"mt-1 text-muted-foreground text-sm\">\n                        {step.description}\n                      </p>\n                      {status === 'complete' ? (\n                        <Button className=\"mt-6\" size=\"sm\" variant=\"outline\">\n                          {step.buttonText}\n                        </Button>\n                      ) : (\n                        <Button\n                          className=\"mt-6\"\n                          disabled={status === 'upcoming'}\n                          onClick={() => {\n                            if (status === 'current') {\n                              handleComplete();\n                            }\n                          }}\n                          size=\"sm\"\n                        >\n                          {step.buttonText}\n                        </Button>\n                      )}\n                    </div>\n                  </div>\n                </AccordionContent>\n              </AccordionItem>\n            );\n          })}\n        </Accordion>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "onboarding"
      ]
    },
    {
      "name": "onboarding-05",
      "type": "registry:block",
      "title": "Onboarding Activity Feed",
      "description": "A onboarding activity feed block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/onboarding/onboarding-05.tsx",
          "type": "registry:component",
          "target": "components/onboarding-05.tsx",
          "content": "import { cn } from '@/lib/utils';\n\nconst steps = [\n  {\n    id: 1,\n    type: 'created',\n    description: 'Created project \"Brand Refresh\"',\n    user: { name: 'Sarah K.', initial: 'S', bgColor: 'bg-violet-500' },\n    activityTime: '3d ago',\n  },\n  {\n    id: 2,\n    type: 'created',\n    description: 'Uploaded 12 design assets',\n    user: { name: 'Marcus L.', initial: 'M', bgColor: 'bg-orange-500' },\n    activityTime: '2d ago',\n  },\n  {\n    id: 3,\n    type: 'created',\n    description: 'Shared prototype with stakeholders',\n    user: { name: 'Sarah K.', initial: 'S', bgColor: 'bg-emerald-500' },\n    activityTime: '2h ago',\n  },\n  {\n    id: 4,\n    type: 'created',\n    description: 'Left feedback on homepage layout',\n    user: { name: 'Jamie R.', initial: 'J', bgColor: 'bg-fuchsia-500' },\n    activityTime: '5min ago',\n  },\n  {\n    id: 5,\n    type: 'in progress',\n    description: 'Scheduled design review meeting',\n    user: { name: 'Team Ops', initial: 'T', bgColor: 'bg-blue-500' },\n    activityTime: 'today 2:30pm',\n  },\n];\n\nexport function Onboarding05() {\n  return (\n    <div className=\"flex min-h-dvh items-center justify-center bg-background p-4\">\n      <div className=\"sm:max-w-lg md:mx-auto\">\n        <h3 className=\"font-medium text-foreground\">Project activity</h3>\n        <p className=\"mt-1 text-muted-foreground text-sm leading-6\">\n          Recent updates from your team\n        </p>\n        <ul className=\"mt-6 space-y-6 pb-2\">\n          {steps.map((step, stepIdx) => (\n            <li className=\"relative flex gap-x-3\" key={step.id}>\n              <div\n                className={cn(\n                  'absolute top-0 left-0 flex w-6 justify-center',\n                  stepIdx === steps.length - 1 ? 'h-6' : '-bottom-6'\n                )}\n              >\n                <span aria-hidden className=\"w-px bg-border\" />\n              </div>\n              <div className=\"flex items-start space-x-2\">\n                <div className=\"flex items-center space-x-2\">\n                  <div className=\"relative flex size-6 flex-none items-center justify-center bg-background\">\n                    {step.type === 'created' ? (\n                      <div className=\"size-3 rounded-full border border-gray-300 bg-muted/50 ring-4 ring-background\" />\n                    ) : (\n                      <div className=\"size-3 rounded-full border border-gray-300 bg-background ring-4 ring-background\" />\n                    )}\n                  </div>\n                  <span\n                    aria-hidden\n                    className={cn(\n                      step.user.bgColor,\n                      'inline-flex size-6 flex-none items-center justify-center rounded-full text-primary-foreground text-xs'\n                    )}\n                  >\n                    {step.user.initial}\n                  </span>\n                </div>\n                <p className=\"mt-0.5 font-medium text-foreground text-sm\">\n                  {step.user.name}\n                  <span className=\"font-normal text-muted-foreground\">\n                    {' '}\n                    {step.description}\n                  </span>\n                  <span className=\"font-normal text-muted-foreground/60\">\n                    {' '}\n                    &#8729; {step.activityTime}\n                  </span>\n                </p>\n              </div>\n            </li>\n          ))}\n        </ul>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "onboarding"
      ]
    },
    {
      "name": "onboarding-06",
      "type": "registry:block",
      "title": "Onboarding Timeline",
      "description": "A onboarding timeline block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/onboarding/onboarding-06.tsx",
          "type": "registry:component",
          "target": "components/onboarding-06.tsx",
          "content": "import { IconCheck } from '@tabler/icons-react';\nimport { cn } from '@/lib/utils';\n\nconst steps = [\n  {\n    id: 1,\n    type: 'done',\n    title: 'Repository connected',\n    description: 'Linked GitHub repository to deployment pipeline',\n    activityTime: '3d ago',\n  },\n  {\n    id: 2,\n    type: 'done',\n    title: 'Build configuration set',\n    description: 'Configured build commands and environment variables',\n    activityTime: '2d ago',\n  },\n  {\n    id: 3,\n    type: 'done',\n    title: 'Domain configured',\n    description: 'Custom domain verified and SSL certificate issued',\n    activityTime: '31min ago',\n  },\n  {\n    id: 4,\n    type: 'in progress',\n    title: 'Running health checks',\n    description: 'Verifying all endpoints respond correctly',\n    activityTime: 'Running now...',\n  },\n  {\n    id: 5,\n    type: 'open',\n    title: 'Go live',\n    description: 'Switch traffic to the new deployment',\n    activityTime: 'Upcoming',\n  },\n];\n\nexport function Onboarding06() {\n  return (\n    <div className=\"flex min-h-dvh items-center justify-center bg-background p-4\">\n      <div className=\"sm:mx-auto sm:max-w-lg\">\n        <h3 className=\"font-medium text-foreground\">Deployment progress</h3>\n        <ul className=\"mt-6 space-y-6\">\n          {steps.map((step, stepIdx) => (\n            <li className=\"relative flex gap-x-3\" key={step.id}>\n              <div\n                className={cn(\n                  'absolute top-0 left-0 flex w-6 justify-center',\n                  stepIdx === steps.length - 1 ? 'h-6' : '-bottom-6'\n                )}\n              >\n                <span aria-hidden className=\"w-px bg-border\" />\n              </div>\n              <div className=\"flex items-start space-x-2.5\">\n                <div className=\"relative flex size-6 flex-none items-center justify-center bg-background\">\n                  {step.type === 'done' ? (\n                    <IconCheck aria-hidden className=\"size-5 text-primary\" />\n                  ) : step.type === 'in progress' ? (\n                    <div\n                      aria-hidden\n                      className=\"size-2.5 rounded-full bg-primary ring-4 ring-background\"\n                    />\n                  ) : (\n                    <div\n                      aria-hidden\n                      className=\"size-3 rounded-full border border-border bg-background ring-4 ring-background\"\n                    />\n                  )}\n                </div>\n                <div>\n                  <p className=\"mt-0.5 font-medium text-foreground text-sm\">\n                    {step.title}{' '}\n                    <span className=\"font-normal text-muted-foreground/60\">\n                      &#8729; {step.activityTime}\n                    </span>\n                  </p>\n                  <p className=\"mt-0.5 text-muted-foreground text-sm leading-6\">\n                    {step.description}\n                  </p>\n                </div>\n              </div>\n            </li>\n          ))}\n        </ul>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "onboarding"
      ]
    },
    {
      "name": "onboarding-07",
      "type": "registry:block",
      "title": "Onboarding Deploy Pipeline",
      "description": "A onboarding deploy pipeline block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "accordion",
        "button",
        "progress"
      ],
      "dependencies": [
        "@tabler/icons-react"
      ],
      "files": [
        {
          "path": "content/components/onboarding/onboarding-07.tsx",
          "type": "registry:component",
          "target": "components/onboarding-07.tsx",
          "content": "'use client';\n\nimport {\n  IconCircleCheckFilled,\n  IconLoader2,\n  IconRefresh,\n} from '@tabler/icons-react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n  Accordion,\n  AccordionContent,\n  AccordionItem,\n  AccordionTrigger,\n} from '@/components/ui/accordion';\nimport { Button } from '@/components/ui/button';\nimport { Progress } from '@/components/ui/progress';\nimport { cn } from '@/lib/utils';\n\nconst initialSteps = [\n  {\n    id: 1,\n    type: 'created' as const,\n    description: 'Export records',\n    value: 100,\n    createdOn: '2024-03-10 09:32',\n    runTime: '12min 18s',\n  },\n  {\n    id: 2,\n    type: 'created' as const,\n    description: 'Transform schema',\n    value: 100,\n    createdOn: '2024-03-10 10:03',\n    runTime: '18min 45s',\n  },\n  {\n    id: 3,\n    type: 'in progress' as const,\n    description: 'Import to new system',\n    value: 45,\n    createdOn: null as string | null,\n    runTime: null as string | null,\n  },\n];\n\nexport function Onboarding07() {\n  const [steps, setSteps] = useState(initialSteps);\n  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n  const allComplete = steps.every((s) => s.value === 100);\n\n  const startAnimation = useCallback(() => {\n    if (intervalRef.current) {\n      clearInterval(intervalRef.current);\n    }\n    intervalRef.current = setInterval(() => {\n      setSteps((prev) => {\n        const next = prev.map((step) => {\n          if (step.id !== 3 || step.value >= 100) {\n            return step;\n          }\n          const increment = Math.random() * 0.8 + 0.3;\n          const newValue = Math.min(step.value + increment, 100);\n          if (newValue >= 100) {\n            return {\n              ...step,\n              value: 100,\n              type: 'created' as const,\n              createdOn: '2024-03-10 10:47',\n              runTime: '6min 32s',\n            };\n          }\n          return { ...step, value: newValue };\n        });\n        if (next[2].value >= 100 && intervalRef.current) {\n          clearInterval(intervalRef.current);\n          intervalRef.current = null;\n        }\n        return next;\n      });\n    }, 50);\n  }, []);\n\n  useEffect(() => {\n    startAnimation();\n    return () => {\n      if (intervalRef.current) {\n        clearInterval(intervalRef.current);\n      }\n    };\n  }, [startAnimation]);\n\n  const handleRunAgain = () => {\n    setSteps(\n      initialSteps.map((step) =>\n        step.id === 3\n          ? {\n              ...step,\n              value: 45,\n              type: 'in progress' as const,\n              createdOn: null,\n              runTime: null,\n            }\n          : step\n      )\n    );\n    startAnimation();\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=\"flex items-center justify-between\">\n          <h3 className=\"font-semibold text-foreground\">Data Migration</h3>\n          <Button\n            className={\n              allComplete ? 'opacity-100' : 'pointer-events-none opacity-0'\n            }\n            onClick={handleRunAgain}\n            size=\"icon\"\n            variant=\"secondary\"\n          >\n            <IconRefresh aria-hidden=\"true\" className=\"size-4\" />\n          </Button>\n        </div>\n        <p className=\"mt-1 text-muted-foreground text-sm leading-6\">\n          Migrating records from your legacy system\n        </p>\n        <div className=\"mt-6 flex items-center space-x-2\">\n          {steps.map((step) => (\n            <div className=\"w-full truncate\" key={step.id}>\n              <Progress className=\"h-1.5\" value={step.value} />\n              <div className=\"mt-2 flex items-center space-x-1 truncate\">\n                {step.value === 100 ? (\n                  <IconCircleCheckFilled\n                    aria-hidden={true}\n                    className=\"size-4 shrink-0 text-primary\"\n                  />\n                ) : (\n                  <IconLoader2\n                    aria-hidden={true}\n                    className=\"size-4 shrink-0 animate-spin text-primary\"\n                  />\n                )}\n                <p className=\"truncate text-muted-foreground text-xs\">\n                  {step.description}\n                </p>\n              </div>\n            </div>\n          ))}\n        </div>\n        <Accordion\n          className=\"mt-8\"\n          collapsible\n          defaultValue=\"logs\"\n          type=\"single\"\n        >\n          <AccordionItem className=\"rounded-sm border-b-0\" value=\"logs\">\n            <AccordionTrigger className=\"font-medium text-foreground text-sm\">\n              Logs overview ({steps.length})\n            </AccordionTrigger>\n            <AccordionContent>\n              <ul className=\"mt-2 space-y-6 pb-2\">\n                {steps.map((step, stepIdx) => (\n                  <li className=\"relative flex gap-x-3\" key={step.id}>\n                    <div\n                      className={cn(\n                        'absolute top-0 left-0 flex w-6 justify-center',\n                        stepIdx === steps.length - 1 ? 'h-6' : '-bottom-6'\n                      )}\n                    >\n                      <span aria-hidden={true} className=\"w-px bg-border\" />\n                    </div>\n                    <div className=\"flex items-start space-x-2.5\">\n                      <div className=\"relative flex size-6 flex-none items-center justify-center bg-background\">\n                        {step.type === 'created' ? (\n                          <div className=\"size-3 rounded-full border border-border bg-muted/50 ring-4 ring-background\" />\n                        ) : (\n                          <div className=\"size-3 rounded-full border border-border bg-background ring-4 ring-background\" />\n                        )}\n                      </div>\n                      <div>\n                        <p className=\"mt-0.5 font-medium text-foreground text-sm\">\n                          {step.description}\n                        </p>\n                        {step.type === 'created' ? (\n                          <p className=\"text-muted-foreground text-sm leading-6\">\n                            Created on {step.createdOn}, Runtime: {step.runTime}\n                          </p>\n                        ) : (\n                          <p className=\"text-muted-foreground text-sm leading-6\">\n                            12,847 of 28,500 records processed...\n                          </p>\n                        )}\n                      </div>\n                    </div>\n                  </li>\n                ))}\n              </ul>\n            </AccordionContent>\n          </AccordionItem>\n        </Accordion>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "onboarding"
      ]
    },
    {
      "name": "sidebar-01",
      "type": "registry:block",
      "title": "Sidebar Collapsible Sections",
      "description": "A sidebar collapsible sections block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "button",
        "collapsible",
        "command",
        "dropdown-menu",
        "sidebar",
        "tooltip"
      ],
      "dependencies": [
        "@tabler/icons-react",
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/sidebar/sidebar-01/index.tsx",
          "type": "registry:component",
          "target": "components/sidebar-01/index.tsx",
          "content": "import {\n  SidebarInset,\n  SidebarProvider,\n  SidebarTrigger,\n} from \"@/components/ui/sidebar\";\nimport { AppSidebar } from \"@/components/sidebar-01/app-sidebar\";\n\nexport default function Sidebar01() {\n  return (\n    <SidebarProvider>\n      <AppSidebar />\n      <SidebarInset>\n        <header className=\"flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12\">\n          <div className=\"flex items-center gap-2 px-4\">\n            <SidebarTrigger className=\"sm:hidden\" />\n          </div>\n        </header>\n      </SidebarInset>\n    </SidebarProvider>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-01/app-sidebar.tsx",
          "type": "registry:component",
          "target": "components/sidebar-01/app-sidebar.tsx",
          "content": "\"use client\";\n\nimport { Sidebar, SidebarContent } from \"@/components/ui/sidebar\";\nimport {\n  IconAd2,\n  IconBellRinging,\n  IconCalendar,\n  IconCalendarStats,\n  IconListDetails,\n  IconNews,\n  IconNotebook,\n  IconProgressCheck,\n  IconSettingsCode,\n} from \"@tabler/icons-react\";\nimport { LayoutDashboard, Package } from \"lucide-react\";\nimport { NavCollapsible } from \"@/components/sidebar-01/nav-collapsible\";\nimport { NavFooter } from \"@/components/sidebar-01/nav-footer\";\nimport { NavHeader } from \"@/components/sidebar-01/nav-header\";\nimport { NavMain } from \"@/components/sidebar-01/nav-main\";\nimport type { SidebarData } from \"./types\";\n\nconst data: SidebarData = {\n  user: {\n    name: \"ephraim\",\n    email: \"ephraim@blocks.so\",\n    avatar: \"/avatar-01.png\",\n  },\n  navMain: [\n    {\n      id: \"overview\",\n      title: \"Overview\",\n      url: \"#\",\n      icon: LayoutDashboard,\n      isActive: true,\n    },\n    {\n      id: \"tasks\",\n      title: \"Tasks\",\n      url: \"#\",\n      icon: IconListDetails,\n    },\n    {\n      id: \"meetings\",\n      title: \"Meetings\",\n      url: \"#\",\n      icon: IconCalendarStats,\n    },\n    {\n      id: \"notes\",\n      title: \"Notes\",\n      url: \"#\",\n      icon: IconNotebook,\n    },\n    {\n      id: \"calendar\",\n      title: \"Calendar\",\n      url: \"#\",\n      icon: IconCalendar,\n    },\n    {\n      id: \"completed\",\n      title: \"Completed\",\n      url: \"#\",\n      icon: IconProgressCheck,\n    },\n    {\n      id: \"notifications\",\n      title: \"Notifications\",\n      url: \"#\",\n      icon: IconBellRinging,\n    },\n  ],\n  navCollapsible: {\n    favorites: [\n      {\n        id: \"design\",\n        title: \"Design\",\n        href: \"#\",\n        color: \"bg-green-400 dark:bg-green-300\",\n      },\n      {\n        id: \"development\",\n        title: \"Development\",\n        href: \"#\",\n        color: \"bg-blue-400 dark:bg-blue-300\",\n      },\n      {\n        id: \"workshop\",\n        title: \"Workshop\",\n        href: \"#\",\n        color: \"bg-orange-400 dark:bg-orange-300\",\n      },\n      {\n        id: \"personal\",\n        title: \"Personal\",\n        href: \"#\",\n        color: \"bg-red-400 dark:bg-red-300\",\n      },\n    ],\n    teams: [\n      {\n        id: \"engineering\",\n        title: \"Engineering\",\n        icon: IconSettingsCode,\n      },\n      {\n        id: \"marketing\",\n        title: \"Marketing\",\n        icon: IconAd2,\n      },\n    ],\n    topics: [\n      {\n        id: \"product-updates\",\n        title: \"Product Updates\",\n        icon: Package,\n      },\n      {\n        id: \"company-news\",\n        title: \"Company News\",\n        icon: IconNews,\n      },\n    ],\n  },\n};\n\nexport function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {\n  return (\n    <Sidebar {...props}>\n      <NavHeader data={data} />\n      <SidebarContent>\n        <NavMain items={data.navMain} />\n        <NavCollapsible\n          favorites={data.navCollapsible.favorites}\n          teams={data.navCollapsible.teams}\n          topics={data.navCollapsible.topics}\n        />\n      </SidebarContent>\n      <NavFooter user={data.user} />\n    </Sidebar>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-01/nav-collapsible.tsx",
          "type": "registry:component",
          "target": "components/sidebar-01/nav-collapsible.tsx",
          "content": "\"use client\";\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport {\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarGroupLabel,\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n} from \"@/components/ui/sidebar\";\nimport { ChevronDown } from \"lucide-react\";\nimport { FavoriteItem, TeamItem, TopicItem } from \"@/components/sidebar-01/types\";\n\ninterface NavCollapsibleProps {\n  favorites: FavoriteItem[];\n  teams: TeamItem[];\n  topics: TopicItem[];\n}\n\nexport function NavCollapsible({\n  favorites,\n  teams,\n  topics,\n}: NavCollapsibleProps) {\n  return (\n    <div className=\"space-y-0\">\n      {favorites && favorites.length > 0 && (\n        <Collapsible defaultOpen className=\"group/collapsible\">\n          <SidebarGroup>\n            <SidebarGroupLabel\n              asChild\n              className=\"text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n            >\n              <CollapsibleTrigger>\n                Favorites\n                <ChevronDown className=\"ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180\" />\n              </CollapsibleTrigger>\n            </SidebarGroupLabel>\n            <CollapsibleContent>\n              <SidebarGroupContent>\n                <SidebarMenu>\n                  {favorites.map((item) => (\n                    <SidebarMenuItem key={item.id}>\n                      <SidebarMenuButton asChild>\n                        <a href={item.href} className=\"flex items-center gap-3\">\n                          <div\n                            className={`h-3 w-3 rounded ${item.color}`}\n                          ></div>\n                          <span>{item.title}</span>\n                        </a>\n                      </SidebarMenuButton>\n                    </SidebarMenuItem>\n                  ))}\n                </SidebarMenu>\n              </SidebarGroupContent>\n            </CollapsibleContent>\n          </SidebarGroup>\n        </Collapsible>\n      )}\n\n      {teams && teams.length > 0 && (\n        <Collapsible className=\"group/collapsible\">\n          <SidebarGroup>\n            <SidebarGroupLabel\n              asChild\n              className=\"text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n            >\n              <CollapsibleTrigger>\n                Teams\n                <ChevronDown className=\"ml-auto transition-transform group-data-[state=closed]/collapsible:rotate-0 group-data-[state=open]/collapsible:rotate-180\" />\n              </CollapsibleTrigger>\n            </SidebarGroupLabel>\n            <CollapsibleContent>\n              <SidebarGroupContent>\n                <SidebarMenu>\n                  {teams.map((item) => {\n                    const Icon = item.icon;\n                    return (\n                      <SidebarMenuItem key={item.id}>\n                        <SidebarMenuButton>\n                          <Icon className=\"mr-2 h-4 w-4\" />\n                          {item.title}\n                        </SidebarMenuButton>\n                      </SidebarMenuItem>\n                    );\n                  })}\n                </SidebarMenu>\n              </SidebarGroupContent>\n            </CollapsibleContent>\n          </SidebarGroup>\n        </Collapsible>\n      )}\n\n      {topics && topics.length > 0 && (\n        <Collapsible className=\"group/collapsible\">\n          <SidebarGroup>\n            <SidebarGroupLabel\n              asChild\n              className=\"text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\"\n            >\n              <CollapsibleTrigger>\n                Topics\n                <ChevronDown className=\"ml-auto transition-transform group-data-[state=closed]/collapsible:rotate-0 group-data-[state=open]/collapsible:rotate-180\" />\n              </CollapsibleTrigger>\n            </SidebarGroupLabel>\n            <CollapsibleContent>\n              <SidebarGroupContent>\n                <SidebarMenu>\n                  {topics.map((item) => {\n                    const Icon = item.icon;\n                    return (\n                      <SidebarMenuItem key={item.id}>\n                        <SidebarMenuButton>\n                          <Icon className=\"mr-2 h-4 w-4\" />\n                          {item.title}\n                        </SidebarMenuButton>\n                      </SidebarMenuItem>\n                    );\n                  })}\n                </SidebarMenu>\n              </SidebarGroupContent>\n            </CollapsibleContent>\n          </SidebarGroup>\n        </Collapsible>\n      )}\n    </div>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-01/nav-footer.tsx",
          "type": "registry:component",
          "target": "components/sidebar-01/nav-footer.tsx",
          "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n  SidebarFooter,\n  SidebarMenu,\n  SidebarMenuItem,\n} from \"@/components/ui/sidebar\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport {\n  BookmarkPlus,\n  CircleHelp,\n  LogOut,\n  Plus,\n  PlusCircle,\n  Puzzle,\n  Settings,\n  User,\n} from \"lucide-react\";\n\nexport function NavFooter({\n  user,\n}: {\n  user: {\n    name: string;\n    email: string;\n    avatar: string;\n  };\n}) {\n  return (\n    <SidebarFooter className=\"p-4\">\n      <SidebarMenu>\n        <SidebarMenuItem>\n          <div className=\"flex items-center gap-2 justify-between\">\n            <div className=\"flex items-center gap-2\">\n              <DropdownMenu>\n                <DropdownMenuTrigger asChild>\n                  <Avatar className=\"h-8 w-8 rounded-full\">\n                    <AvatarImage src={user.avatar} alt={user.name} />\n                    <AvatarFallback className=\"rounded-full\">CN</AvatarFallback>\n                  </Avatar>\n                </DropdownMenuTrigger>\n                <DropdownMenuContent className=\"m-2\">\n                  <DropdownMenuItem>\n                    <User size={16} className=\"opacity-80\" aria-hidden=\"true\" />\n                    Profile\n                  </DropdownMenuItem>\n                  <DropdownMenuItem>\n                    <Settings\n                      size={16}\n                      className=\"opacity-80\"\n                      aria-hidden=\"true\"\n                    />\n                    Settings\n                  </DropdownMenuItem>\n                  <DropdownMenuItem>\n                    <LogOut\n                      size={16}\n                      className=\"opacity-80\"\n                      aria-hidden=\"true\"\n                    />\n                    Logout\n                  </DropdownMenuItem>\n                </DropdownMenuContent>\n              </DropdownMenu>\n\n              <TooltipProvider delayDuration={0}>\n                <Tooltip>\n                  <TooltipTrigger asChild>\n                    <CircleHelp\n                      size={16}\n                      aria-hidden=\"true\"\n                      className=\"cursor-pointer opacity-60 hover:opacity-100\"\n                    />\n                  </TooltipTrigger>\n                  <TooltipContent\n                    side=\"top\"\n                    className=\"py-1 px-2 m-2 max-w-[150px] border bg-popover text-popover-foreground\"\n                  >\n                    <div className=\"space-y-1 text-xs\">\n                      <p className=\"font-medium\">User Information</p>\n                      <p className=\"text-muted-foreground\">\n                        More details about the current user or section can be\n                        displayed here.\n                      </p>\n                    </div>\n                  </TooltipContent>\n                </Tooltip>\n              </TooltipProvider>\n            </div>\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button\n                  size=\"icon\"\n                  variant=\"ghost\"\n                  className=\"rounded-full shadow-none focus-visible:ring-0 focus-visible:ring-offset-0\"\n                  aria-label=\"Open edit menu\"\n                >\n                  <Plus size={16} aria-hidden=\"true\" />\n                </Button>\n              </DropdownMenuTrigger>\n              <DropdownMenuContent className=\"pb-2\">\n                <DropdownMenuLabel>Add New</DropdownMenuLabel>\n                <DropdownMenuItem>\n                  <PlusCircle\n                    size={16}\n                    className=\"mr-2 opacity-80\"\n                    aria-hidden=\"true\"\n                  />\n                  Add New Item\n                </DropdownMenuItem>\n                <DropdownMenuItem>\n                  <BookmarkPlus\n                    size={16}\n                    className=\"mr-2 opacity-80\"\n                    aria-hidden=\"true\"\n                  />\n                  Add Bookmark\n                </DropdownMenuItem>\n                <DropdownMenuItem>\n                  <Puzzle\n                    size={16}\n                    className=\"mr-2 opacity-80\"\n                    aria-hidden=\"true\"\n                  />\n                  Add Integration\n                </DropdownMenuItem>\n              </DropdownMenuContent>\n            </DropdownMenu>\n          </div>\n        </SidebarMenuItem>\n      </SidebarMenu>\n    </SidebarFooter>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-01/nav-main.tsx",
          "type": "registry:component",
          "target": "components/sidebar-01/nav-main.tsx",
          "content": "\"use client\";\n\nimport {\n  SidebarGroup,\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n} from \"@/components/ui/sidebar\";\nimport type { NavItem } from \"./types\";\n\nexport function NavMain({ items }: { items: NavItem[] }) {\n  return (\n    <SidebarGroup>\n      <SidebarMenu>\n        {items.map((item) => {\n          const Icon = item.icon;\n\n          return (\n            <SidebarMenuItem key={item.id}>\n              <SidebarMenuButton tooltip={item.title}>\n                {Icon && <Icon className=\"mr-2 h-4 w-4\" />}\n                <span>{item.title}</span>\n              </SidebarMenuButton>\n            </SidebarMenuItem>\n          );\n        })}\n      </SidebarMenu>\n    </SidebarGroup>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-01/nav-header.tsx",
          "type": "registry:component",
          "target": "components/sidebar-01/nav-header.tsx",
          "content": "\"use client\";\n\nimport { Search } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n} from \"@/components/ui/command\";\nimport { SidebarHeader } from \"@/components/ui/sidebar\";\nimport { cn } from \"@/lib/utils\";\nimport { useEffect } from \"react\";\nimport { SidebarData } from \"@/components/sidebar-01/types\";\n\ninterface NavHeaderProps {\n  data: SidebarData;\n}\n\nexport function NavHeader({ data }: NavHeaderProps) {\n  const [open, setOpen] = React.useState(false);\n\n  useEffect(() => {\n    const down = (e: KeyboardEvent) => {\n      if (e.key === \"k\" && (e.metaKey || e.ctrlKey)) {\n        e.preventDefault();\n        setOpen((open) => !open);\n      }\n    };\n    document.addEventListener(\"keydown\", down);\n    return () => document.removeEventListener(\"keydown\", down);\n  }, []);\n\n  return (\n    <>\n      <SidebarHeader>\n        <div\n          className=\"flex items-center justify-between px-2 pb-0 pt-3 cursor-pointer\"\n          onClick={() => setOpen(true)}\n        >\n          <div className=\"flex items-center flex-1 gap-3\">\n            <Search className=\"h-4 w-4 text-muted-foreground\" />\n            <span className=\"text-sm text-muted-foreground font-normal\">\n              Search\n            </span>\n          </div>\n          <div className=\"flex items-center justify-center px-2 py-1 border border-border rounded-md\">\n            <kbd className=\"text-muted-foreground inline-flex font-[inherit] text-xs font-medium\">\n              <span className=\"opacity-70\">⌘K</span>\n            </kbd>\n          </div>\n        </div>\n      </SidebarHeader>\n\n      <CommandDialog open={open} onOpenChange={setOpen}>\n        <CommandInput placeholder=\"Search everything...\" />\n        <CommandList>\n          <CommandEmpty>No results found.</CommandEmpty>\n          <CommandGroup heading=\"Navigation\">\n            {data.navMain.map((item) => (\n              <CommandItem\n                className=\"py-2!\"\n                key={item.id}\n                onSelect={() => {\n                  setOpen(false);\n                }}\n              >\n                <item.icon className=\"mr-2 h-4 w-4\" />\n                <span>{item.title}</span>\n              </CommandItem>\n            ))}\n          </CommandGroup>\n          <CommandSeparator className=\"my-2\" />\n          <CommandGroup heading=\"Favorites\">\n            {data.navCollapsible.favorites.map((item) => (\n              <CommandItem\n                className=\"py-2!\"\n                key={item.id}\n                onSelect={() => {\n                  setOpen(false);\n                }}\n              >\n                <div className={cn(\"mr-2 h-3 w-3 rounded-full\", item.color)} />\n                <span>{item.title}</span>\n              </CommandItem>\n            ))}\n          </CommandGroup>\n          <CommandSeparator className=\"my-2\" />\n          <CommandGroup heading=\"Teams\">\n            {data.navCollapsible.teams.map((item) => (\n              <CommandItem\n                className=\"py-2!\"\n                key={item.id}\n                onSelect={() => {\n                  setOpen(false);\n                }}\n              >\n                <item.icon className=\"mr-2 h-4 w-4\" />\n                <span>{item.title}</span>\n              </CommandItem>\n            ))}\n          </CommandGroup>\n          <CommandSeparator className=\"my-2\" />\n          <CommandGroup heading=\"Topics\">\n            {data.navCollapsible.topics.map((item) => (\n              <CommandItem\n                className=\"py-2!\"\n                key={item.id}\n                onSelect={() => {\n                  setOpen(false);\n                }}\n              >\n                <item.icon className=\"mr-2 h-4 w-4\" />\n                <span>{item.title}</span>\n              </CommandItem>\n            ))}\n          </CommandGroup>\n        </CommandList>\n      </CommandDialog>\n    </>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-01/types.ts",
          "type": "registry:file",
          "target": "components/sidebar-01/types.ts",
          "content": "import type { ElementType } from \"react\";\n\nexport interface NavItem {\n  id: string;\n  title: string;\n  icon: ElementType;\n  url?: string;\n  isActive?: boolean;\n}\n\nexport interface User {\n  name: string;\n  email: string;\n  avatar: string;\n}\n\nexport interface FavoriteItem {\n  id: string;\n  title: string;\n  href: string;\n  color: string;\n}\n\nexport interface TeamItem {\n  id: string;\n  title: string;\n  icon: ElementType;\n}\n\nexport interface TopicItem {\n  id: string;\n  title: string;\n  icon: ElementType;\n}\n\nexport interface SidebarData {\n  user: User;\n  navMain: NavItem[];\n  navCollapsible: {\n    favorites: FavoriteItem[];\n    teams: TeamItem[];\n    topics: TopicItem[];\n  };\n}\n"
        }
      ],
      "categories": [
        "sidebar"
      ]
    },
    {
      "name": "sidebar-02",
      "type": "registry:block",
      "title": "Sidebar Dashboard Inset",
      "description": "A sidebar dashboard inset block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "button",
        "collapsible",
        "dropdown-menu",
        "sidebar"
      ],
      "dependencies": [
        "framer-motion",
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/sidebar/sidebar-02/team-switcher.tsx",
          "type": "registry:component",
          "target": "components/sidebar-02/team-switcher.tsx",
          "content": "\"use client\";\n\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\nimport { ChevronsUpDown, Plus } from \"lucide-react\";\nimport * as React from \"react\";\n\ntype Team = {\n  name: string;\n  logo: React.ElementType;\n  plan: string;\n};\n\nexport function TeamSwitcher({ teams }: { teams: Team[] }) {\n  const { isMobile } = useSidebar();\n  const [activeTeam, setActiveTeam] = React.useState(teams[0]);\n\n  if (!activeTeam) return null;\n\n  const Logo = activeTeam.logo;\n\n  return (\n    <SidebarMenu>\n      <SidebarMenuItem>\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <SidebarMenuButton\n              size=\"lg\"\n              className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n            >\n              <div className=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-background text-foreground\">\n                <Logo className=\"size-4\" />\n              </div>\n              <div className=\"grid flex-1 text-left text-sm leading-tight\">\n                <span className=\"truncate font-semibold\">\n                  {activeTeam.name}\n                </span>\n                <span className=\"truncate text-xs\">{activeTeam.plan}</span>\n              </div>\n              <ChevronsUpDown className=\"ml-auto\" />\n            </SidebarMenuButton>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            className=\"w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg mb-4\"\n            align=\"start\"\n            side={isMobile ? \"bottom\" : \"right\"}\n            sideOffset={4}\n          >\n            <DropdownMenuLabel className=\"text-xs text-muted-foreground\">\n              Teams\n            </DropdownMenuLabel>\n            {teams.map((team, index) => (\n              <DropdownMenuItem\n                key={team.name}\n                onClick={() => setActiveTeam(team)}\n                className=\"gap-2 p-2\"\n              >\n                <div className=\"flex size-6 items-center justify-center rounded-sm border\">\n                  <team.logo className=\"size-4 shrink-0\" />\n                </div>\n                {team.name}\n                <DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>\n              </DropdownMenuItem>\n            ))}\n            <DropdownMenuSeparator />\n            <DropdownMenuItem className=\"gap-2 p-2\">\n              <div className=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n                <Plus className=\"size-4\" />\n              </div>\n              <div className=\"font-medium text-muted-foreground\">Add team</div>\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </SidebarMenuItem>\n    </SidebarMenu>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-02/nav-notifications.tsx",
          "type": "registry:component",
          "target": "components/sidebar-02/nav-notifications.tsx",
          "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { BellIcon } from \"lucide-react\";\n\ntype Notification = {\n  id: string;\n  avatar: string;\n  fallback: string;\n  text: string;\n  time: string;\n};\n\nexport function NotificationsPopover({\n  notifications,\n}: {\n  notifications: Notification[];\n}) {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          variant=\"ghost\"\n          size=\"icon\"\n          className=\"rounded-full\"\n          aria-label=\"Open notifications\"\n        >\n          <BellIcon className=\"size-5\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent side=\"right\" className=\"w-80 my-6\">\n        <DropdownMenuLabel>Notifications</DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        {notifications.map(({ id, avatar, fallback, text, time }) => (\n          <DropdownMenuItem key={id} className=\"flex items-start gap-3\">\n            <Avatar className=\"size-8\">\n              <AvatarImage src={avatar} alt=\"Avatar\" />\n              <AvatarFallback>{fallback}</AvatarFallback>\n            </Avatar>\n            <div className=\"flex flex-col\">\n              <span className=\"text-sm font-medium\">{text}</span>\n              <span className=\"text-xs text-muted-foreground\">{time}</span>\n            </div>\n          </DropdownMenuItem>\n        ))}\n        <DropdownMenuSeparator />\n        <DropdownMenuItem className=\"justify-center text-sm text-muted-foreground hover:text-primary\">\n          View all notifications\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-02/index.tsx",
          "type": "registry:component",
          "target": "components/sidebar-02/index.tsx",
          "content": "import { SidebarInset, SidebarProvider } from \"@/components/ui/sidebar\";\nimport { DashboardSidebar } from \"@/components/sidebar-02/app-sidebar\";\n\nexport default function Sidebar02() {\n  return (\n    <SidebarProvider>\n      <div className=\"relative flex h-dvh w-full\">\n        <DashboardSidebar />\n        <SidebarInset className=\"flex flex-col\" />\n      </div>\n    </SidebarProvider>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-02/app-sidebar.tsx",
          "type": "registry:component",
          "target": "components/sidebar-02/app-sidebar.tsx",
          "content": "\"use client\";\n\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarHeader,\n  SidebarTrigger,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\nimport {\n  Activity,\n  DollarSign,\n  Home,\n  Infinity,\n  LinkIcon,\n  Package2,\n  Percent,\n  PieChart,\n  Settings,\n  ShoppingBag,\n  Sparkles,\n  Store,\n  TrendingUp,\n  Users,\n} from \"lucide-react\";\nimport { Logo } from \"@/components/sidebar-02/logo\";\nimport type { Route } from \"./nav-main\";\nimport DashboardNavigation from \"@/components/sidebar-02/nav-main\";\nimport { NotificationsPopover } from \"@/components/sidebar-02/nav-notifications\";\nimport { TeamSwitcher } from \"@/components/sidebar-02/team-switcher\";\n\nconst sampleNotifications = [\n  {\n    id: \"1\",\n    avatar: \"/avatars/01.png\",\n    fallback: \"OM\",\n    text: \"New order received.\",\n    time: \"10m ago\",\n  },\n  {\n    id: \"2\",\n    avatar: \"/avatars/02.png\",\n    fallback: \"JL\",\n    text: \"Server upgrade completed.\",\n    time: \"1h ago\",\n  },\n  {\n    id: \"3\",\n    avatar: \"/avatars/03.png\",\n    fallback: \"HH\",\n    text: \"New user signed up.\",\n    time: \"2h ago\",\n  },\n];\n\nconst dashboardRoutes: Route[] = [\n  {\n    id: \"home\",\n    title: \"Home\",\n    icon: <Home className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"products\",\n    title: \"Products\",\n    icon: <Package2 className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      {\n        title: \"Catalogue\",\n        link: \"#\",\n        icon: <Package2 className=\"size-4\" />,\n      },\n      {\n        title: \"Checkout Links\",\n        link: \"#\",\n        icon: <LinkIcon className=\"size-4\" />,\n      },\n      {\n        title: \"Discounts\",\n        link: \"#\",\n        icon: <Percent className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: \"usage-billing\",\n    title: \"Usage Billing\",\n    icon: <PieChart className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      {\n        title: \"Meters\",\n        link: \"#\",\n        icon: <PieChart className=\"size-4\" />,\n      },\n      {\n        title: \"Events\",\n        link: \"#\",\n        icon: <Activity className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: \"benefits\",\n    title: \"Benefits\",\n    icon: <Sparkles className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"customers\",\n    title: \"Customers\",\n    icon: <Users className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"sales\",\n    title: \"Sales\",\n    icon: <ShoppingBag className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      {\n        title: \"Orders\",\n        link: \"#\",\n        icon: <ShoppingBag className=\"size-4\" />,\n      },\n      {\n        title: \"Subscriptions\",\n        link: \"#\",\n        icon: <Infinity className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: \"storefront\",\n    title: \"Storefront\",\n    icon: <Store className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"analytics\",\n    title: \"Analytics\",\n    icon: <TrendingUp className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"finance\",\n    title: \"Finance\",\n    icon: <DollarSign className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      { title: \"Incoming\", link: \"#\" },\n      { title: \"Outgoing\", link: \"#\" },\n      { title: \"Payout Account\", link: \"#\" },\n    ],\n  },\n  {\n    id: \"settings\",\n    title: \"Settings\",\n    icon: <Settings className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      { title: \"General\", link: \"#\" },\n      { title: \"Webhooks\", link: \"#\" },\n      { title: \"Custom Fields\", link: \"#\" },\n    ],\n  },\n];\n\nconst teams = [\n  { id: \"1\", name: \"Alpha Inc.\", logo: Logo, plan: \"Free\" },\n  { id: \"2\", name: \"Beta Corp.\", logo: Logo, plan: \"Free\" },\n  { id: \"3\", name: \"Gamma Tech\", logo: Logo, plan: \"Free\" },\n];\n\nexport function DashboardSidebar() {\n  const { state } = useSidebar();\n  const isCollapsed = state === \"collapsed\";\n\n  return (\n    <Sidebar variant=\"inset\" collapsible=\"icon\">\n      <SidebarHeader\n        className={cn(\n          \"flex md:pt-3.5\",\n          isCollapsed\n            ? \"flex-row items-center justify-between gap-y-4 md:flex-col md:items-start md:justify-start\"\n            : \"flex-row items-center justify-between\"\n        )}\n      >\n        <a href=\"#\" className=\"flex items-center gap-2\">\n          <Logo className=\"h-8 w-8\" />\n          {!isCollapsed && (\n            <span className=\"font-semibold text-black dark:text-white\">\n              Acme\n            </span>\n          )}\n        </a>\n\n        <motion.div\n          key={isCollapsed ? \"header-collapsed\" : \"header-expanded\"}\n          className={cn(\n            \"flex items-center gap-2\",\n            isCollapsed ? \"flex-row md:flex-col-reverse\" : \"flex-row\"\n          )}\n          initial={{ opacity: 0 }}\n          animate={{ opacity: 1 }}\n          transition={{ duration: 0.8 }}\n        >\n          <NotificationsPopover notifications={sampleNotifications} />\n          <SidebarTrigger />\n        </motion.div>\n      </SidebarHeader>\n      <SidebarContent className=\"gap-4 px-2 py-4\">\n        <DashboardNavigation routes={dashboardRoutes} />\n      </SidebarContent>\n      <SidebarFooter className=\"px-2\">\n        <TeamSwitcher teams={teams} />\n      </SidebarFooter>\n    </Sidebar>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-02/logo.tsx",
          "type": "registry:component",
          "target": "components/sidebar-02/logo.tsx",
          "content": "import { SVGProps } from \"react\";\n\nexport const Logo = (props: SVGProps<SVGSVGElement>) => (\n  <svg\n    fill=\"currentColor\"\n    height=\"48\"\n    viewBox=\"0 0 40 48\"\n    width=\"40\"\n    {...props}\n  >\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n"
        },
        {
          "path": "content/components/sidebar/sidebar-02/nav-main.tsx",
          "type": "registry:component",
          "target": "components/sidebar-02/nav-main.tsx",
          "content": "\"use client\";\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarMenuSub,\n  SidebarMenuSubButton,\n  SidebarMenuItem as SidebarMenuSubItem,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\nimport { cn } from \"@/lib/utils\";\nimport { ChevronDown, ChevronUp } from \"lucide-react\";\nimport Link from \"next/link\";\nimport type React from \"react\";\nimport { useState } from \"react\";\n\nexport type Route = {\n  id: string;\n  title: string;\n  icon?: React.ReactNode;\n  link: string;\n  subs?: {\n    title: string;\n    link: string;\n    icon?: React.ReactNode;\n  }[];\n};\n\nexport default function DashboardNavigation({ routes }: { routes: Route[] }) {\n  const { state } = useSidebar();\n  const isCollapsed = state === \"collapsed\";\n  const [openCollapsible, setOpenCollapsible] = useState<string | null>(null);\n\n  return (\n    <SidebarMenu>\n      {routes.map((route) => {\n        const isOpen = !isCollapsed && openCollapsible === route.id;\n        const hasSubRoutes = !!route.subs?.length;\n\n        return (\n          <SidebarMenuItem key={route.id}>\n            {hasSubRoutes ? (\n              <Collapsible\n                open={isOpen}\n                onOpenChange={(open) =>\n                  setOpenCollapsible(open ? route.id : null)\n                }\n                className=\"w-full\"\n              >\n                <CollapsibleTrigger asChild>\n                  <SidebarMenuButton\n                    className={cn(\n                      \"flex w-full items-center rounded-lg px-2 transition-colors\",\n                      isOpen\n                        ? \"bg-sidebar-muted text-foreground\"\n                        : \"text-muted-foreground hover:bg-sidebar-muted hover:text-foreground\",\n                      isCollapsed && \"justify-center\"\n                    )}\n                  >\n                    {route.icon}\n                    {!isCollapsed && (\n                      <span className=\"ml-2 flex-1 text-sm font-medium\">\n                        {route.title}\n                      </span>\n                    )}\n                    {!isCollapsed && hasSubRoutes && (\n                      <span className=\"ml-auto\">\n                        {isOpen ? (\n                          <ChevronUp className=\"size-4\" />\n                        ) : (\n                          <ChevronDown className=\"size-4\" />\n                        )}\n                      </span>\n                    )}\n                  </SidebarMenuButton>\n                </CollapsibleTrigger>\n\n                {!isCollapsed && (\n                  <CollapsibleContent>\n                    <SidebarMenuSub className=\"my-1 ml-3.5 \">\n                      {route.subs?.map((subRoute) => (\n                        <SidebarMenuSubItem\n                          key={`${route.id}-${subRoute.title}`}\n                          className=\"h-auto\"\n                        >\n                          <SidebarMenuSubButton asChild>\n                            <Link\n                              href={subRoute.link}\n                              prefetch={true}\n                              className=\"flex items-center rounded-md px-4 py-1.5 text-sm font-medium text-muted-foreground hover:bg-sidebar-muted hover:text-foreground\"\n                            >\n                              {subRoute.title}\n                            </Link>\n                          </SidebarMenuSubButton>\n                        </SidebarMenuSubItem>\n                      ))}\n                    </SidebarMenuSub>\n                  </CollapsibleContent>\n                )}\n              </Collapsible>\n            ) : (\n              <SidebarMenuButton tooltip={route.title} asChild>\n                <Link\n                  href={route.link}\n                  prefetch={true}\n                  className={cn(\n                    \"flex items-center rounded-lg px-2 transition-colors text-muted-foreground hover:bg-sidebar-muted hover:text-foreground\",\n                    isCollapsed && \"justify-center\"\n                  )}\n                >\n                  {route.icon}\n                  {!isCollapsed && (\n                    <span className=\"ml-2 text-sm font-medium\">\n                      {route.title}\n                    </span>\n                  )}\n                </Link>\n              </SidebarMenuButton>\n            )}\n          </SidebarMenuItem>\n        );\n      })}\n    </SidebarMenu>\n  );\n}\n"
        }
      ],
      "categories": [
        "sidebar"
      ]
    },
    {
      "name": "sidebar-03",
      "type": "registry:block",
      "title": "Sidebar Dashboard Floating",
      "description": "A sidebar dashboard floating block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "button",
        "collapsible",
        "dropdown-menu",
        "sidebar"
      ],
      "dependencies": [
        "framer-motion",
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/sidebar/sidebar-03/team-switcher.tsx",
          "type": "registry:component",
          "target": "components/sidebar-03/team-switcher.tsx",
          "content": "\"use client\";\n\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\nimport { ChevronsUpDown, Plus } from \"lucide-react\";\nimport * as React from \"react\";\n\ntype Team = {\n  name: string;\n  logo: React.ElementType;\n  plan: string;\n};\n\nexport function TeamSwitcher({ teams }: { teams: Team[] }) {\n  const { isMobile } = useSidebar();\n  const [activeTeam, setActiveTeam] = React.useState(teams[0]);\n\n  if (!activeTeam) return null;\n\n  const Logo = activeTeam.logo;\n\n  return (\n    <SidebarMenu>\n      <SidebarMenuItem>\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <SidebarMenuButton\n              size=\"lg\"\n              className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n            >\n              <div className=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-background text-foreground\">\n                <Logo className=\"size-4\" />\n              </div>\n              <div className=\"grid flex-1 text-left text-sm leading-tight\">\n                <span className=\"truncate font-semibold\">\n                  {activeTeam.name}\n                </span>\n                <span className=\"truncate text-xs\">{activeTeam.plan}</span>\n              </div>\n              <ChevronsUpDown className=\"ml-auto\" />\n            </SidebarMenuButton>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            className=\"w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg mb-4\"\n            align=\"start\"\n            side={isMobile ? \"bottom\" : \"right\"}\n            sideOffset={4}\n          >\n            <DropdownMenuLabel className=\"text-xs text-muted-foreground\">\n              Teams\n            </DropdownMenuLabel>\n            {teams.map((team, index) => (\n              <DropdownMenuItem\n                key={team.name}\n                onClick={() => setActiveTeam(team)}\n                className=\"gap-2 p-2\"\n              >\n                <div className=\"flex size-6 items-center justify-center rounded-sm border\">\n                  <team.logo className=\"size-4 shrink-0\" />\n                </div>\n                {team.name}\n                <DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>\n              </DropdownMenuItem>\n            ))}\n            <DropdownMenuSeparator />\n            <DropdownMenuItem className=\"gap-2 p-2\">\n              <div className=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n                <Plus className=\"size-4\" />\n              </div>\n              <div className=\"font-medium text-muted-foreground\">Add team</div>\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </SidebarMenuItem>\n    </SidebarMenu>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-03/nav-notifications.tsx",
          "type": "registry:component",
          "target": "components/sidebar-03/nav-notifications.tsx",
          "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { BellIcon } from \"lucide-react\";\n\ntype Notification = {\n  id: string;\n  avatar: string;\n  fallback: string;\n  text: string;\n  time: string;\n};\n\nexport function NotificationsPopover({\n  notifications,\n}: {\n  notifications: Notification[];\n}) {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          variant=\"ghost\"\n          size=\"icon\"\n          className=\"rounded-full\"\n          aria-label=\"Open notifications\"\n        >\n          <BellIcon className=\"size-5\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent side=\"right\" className=\"w-80 my-6\">\n        <DropdownMenuLabel>Notifications</DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        {notifications.map(({ id, avatar, fallback, text, time }) => (\n          <DropdownMenuItem key={id} className=\"flex items-start gap-3\">\n            <Avatar className=\"size-8\">\n              <AvatarImage src={avatar} alt=\"Avatar\" />\n              <AvatarFallback>{fallback}</AvatarFallback>\n            </Avatar>\n            <div className=\"flex flex-col\">\n              <span className=\"text-sm font-medium\">{text}</span>\n              <span className=\"text-xs text-muted-foreground\">{time}</span>\n            </div>\n          </DropdownMenuItem>\n        ))}\n        <DropdownMenuSeparator />\n        <DropdownMenuItem className=\"justify-center text-sm text-muted-foreground hover:text-primary\">\n          View all notifications\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-03/index.tsx",
          "type": "registry:component",
          "target": "components/sidebar-03/index.tsx",
          "content": "import { SidebarInset, SidebarProvider } from \"@/components/ui/sidebar\";\nimport { DashboardSidebar } from \"@/components/sidebar-03/app-sidebar\";\n\nexport default function Sidebar03() {\n  return (\n    <SidebarProvider>\n      <div className=\"relative flex h-dvh w-full\">\n        <DashboardSidebar />\n        <SidebarInset className=\"flex flex-col\" />\n      </div>\n    </SidebarProvider>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-03/app-sidebar.tsx",
          "type": "registry:component",
          "target": "components/sidebar-03/app-sidebar.tsx",
          "content": "\"use client\";\n\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarHeader,\n  SidebarTrigger,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\nimport {\n  Activity,\n  DollarSign,\n  Home,\n  Infinity,\n  LinkIcon,\n  Package2,\n  Percent,\n  PieChart,\n  Settings,\n  ShoppingBag,\n  Sparkles,\n  Store,\n  TrendingUp,\n  Users,\n} from \"lucide-react\";\nimport { Logo } from \"@/components/sidebar-03/logo\";\nimport type { Route } from \"./nav-main\";\nimport DashboardNavigation from \"@/components/sidebar-03/nav-main\";\nimport { NotificationsPopover } from \"@/components/sidebar-03/nav-notifications\";\nimport { TeamSwitcher } from \"@/components/sidebar-03/team-switcher\";\n\nconst sampleNotifications = [\n  {\n    id: \"1\",\n    avatar: \"/avatars/01.png\",\n    fallback: \"OM\",\n    text: \"New order received.\",\n    time: \"10m ago\",\n  },\n  {\n    id: \"2\",\n    avatar: \"/avatars/02.png\",\n    fallback: \"JL\",\n    text: \"Server upgrade completed.\",\n    time: \"1h ago\",\n  },\n  {\n    id: \"3\",\n    avatar: \"/avatars/03.png\",\n    fallback: \"HH\",\n    text: \"New user signed up.\",\n    time: \"2h ago\",\n  },\n];\n\nconst dashboardRoutes: Route[] = [\n  {\n    id: \"home\",\n    title: \"Home\",\n    icon: <Home className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"products\",\n    title: \"Products\",\n    icon: <Package2 className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      {\n        title: \"Catalogue\",\n        link: \"#\",\n        icon: <Package2 className=\"size-4\" />,\n      },\n      {\n        title: \"Checkout Links\",\n        link: \"#\",\n        icon: <LinkIcon className=\"size-4\" />,\n      },\n      {\n        title: \"Discounts\",\n        link: \"#\",\n        icon: <Percent className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: \"usage-billing\",\n    title: \"Usage Billing\",\n    icon: <PieChart className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      {\n        title: \"Meters\",\n        link: \"#\",\n        icon: <PieChart className=\"size-4\" />,\n      },\n      {\n        title: \"Events\",\n        link: \"#\",\n        icon: <Activity className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: \"benefits\",\n    title: \"Benefits\",\n    icon: <Sparkles className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"customers\",\n    title: \"Customers\",\n    icon: <Users className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"sales\",\n    title: \"Sales\",\n    icon: <ShoppingBag className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      {\n        title: \"Orders\",\n        link: \"#\",\n        icon: <ShoppingBag className=\"size-4\" />,\n      },\n      {\n        title: \"Subscriptions\",\n        link: \"#\",\n        icon: <Infinity className=\"size-4\" />,\n      },\n    ],\n  },\n  {\n    id: \"storefront\",\n    title: \"Storefront\",\n    icon: <Store className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"analytics\",\n    title: \"Analytics\",\n    icon: <TrendingUp className=\"size-4\" />,\n    link: \"#\",\n  },\n  {\n    id: \"finance\",\n    title: \"Finance\",\n    icon: <DollarSign className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      { title: \"Incoming\", link: \"#\" },\n      { title: \"Outgoing\", link: \"#\" },\n      { title: \"Payout Account\", link: \"#\" },\n    ],\n  },\n  {\n    id: \"settings\",\n    title: \"Settings\",\n    icon: <Settings className=\"size-4\" />,\n    link: \"#\",\n    subs: [\n      { title: \"General\", link: \"#\" },\n      { title: \"Webhooks\", link: \"#\" },\n      { title: \"Custom Fields\", link: \"#\" },\n    ],\n  },\n];\n\nconst teams = [\n  { id: \"1\", name: \"Alpha Inc.\", logo: Logo, plan: \"Free\" },\n  { id: \"2\", name: \"Beta Corp.\", logo: Logo, plan: \"Free\" },\n  { id: \"3\", name: \"Gamma Tech\", logo: Logo, plan: \"Free\" },\n];\n\nexport function DashboardSidebar() {\n  const { state } = useSidebar();\n  const isCollapsed = state === \"collapsed\";\n\n  return (\n    <Sidebar variant=\"floating\" collapsible=\"icon\">\n      <SidebarHeader\n        className={cn(\n          \"flex md:pt-3.5\",\n          isCollapsed\n            ? \"flex-row items-center justify-between gap-y-4 md:flex-col md:items-start md:justify-start\"\n            : \"flex-row items-center justify-between\"\n        )}\n      >\n        <a href=\"#\" className=\"flex items-center gap-2\">\n          <Logo className=\"h-8 w-8\" />\n          {!isCollapsed && (\n            <span className=\"font-semibold text-black dark:text-white\">\n              Acme\n            </span>\n          )}\n        </a>\n\n        <motion.div\n          key={isCollapsed ? \"header-collapsed\" : \"header-expanded\"}\n          className={cn(\n            \"flex items-center gap-2\",\n            isCollapsed ? \"flex-row md:flex-col-reverse\" : \"flex-row\"\n          )}\n          initial={{ opacity: 0 }}\n          animate={{ opacity: 1 }}\n          transition={{ duration: 0.8 }}\n        >\n          <NotificationsPopover notifications={sampleNotifications} />\n          <SidebarTrigger />\n        </motion.div>\n      </SidebarHeader>\n      <SidebarContent className=\"gap-4 px-2 py-4\">\n        <DashboardNavigation routes={dashboardRoutes} />\n      </SidebarContent>\n      <SidebarFooter className=\"px-2\">\n        <TeamSwitcher teams={teams} />\n      </SidebarFooter>\n    </Sidebar>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-03/logo.tsx",
          "type": "registry:component",
          "target": "components/sidebar-03/logo.tsx",
          "content": "import type { SVGProps } from \"react\";\n\nexport const Logo = (props: SVGProps<SVGSVGElement>) => (\n  <svg\n    fill=\"currentColor\"\n    height=\"48\"\n    viewBox=\"0 0 40 48\"\n    width=\"40\"\n    {...props}\n  >\n    <title>Logo</title>\n    <clipPath id=\"a\">\n      <path d=\"m0 0h40v48h-40z\" />\n    </clipPath>\n    <g clipPath=\"url(#a)\">\n      <path d=\"m25.0887 5.05386-3.933-1.05386-3.3145 12.3696-2.9923-11.16736-3.9331 1.05386 3.233 12.0655-8.05262-8.0526-2.87919 2.8792 8.83271 8.8328-10.99975-2.9474-1.05385625 3.933 12.01860625 3.2204c-.1376-.5935-.2104-1.2119-.2104-1.8473 0-4.4976 3.646-8.1436 8.1437-8.1436 4.4976 0 8.1436 3.646 8.1436 8.1436 0 .6313-.0719 1.2459-.2078 1.8359l10.9227 2.9267 1.0538-3.933-12.0664-3.2332 11.0005-2.9476-1.0539-3.933-12.0659 3.233 8.0526-8.0526-2.8792-2.87916-8.7102 8.71026z\" />\n      <path d=\"m27.8723 26.2214c-.3372 1.4256-1.0491 2.7063-2.0259 3.7324l7.913 7.9131 2.8792-2.8792z\" />\n      <path d=\"m25.7665 30.0366c-.9886 1.0097-2.2379 1.7632-3.6389 2.1515l2.8794 10.746 3.933-1.0539z\" />\n      <path d=\"m21.9807 32.2274c-.65.1671-1.3313.2559-2.0334.2559-.7522 0-1.4806-.102-2.1721-.2929l-2.882 10.7558 3.933 1.0538z\" />\n      <path d=\"m17.6361 32.1507c-1.3796-.4076-2.6067-1.1707-3.5751-2.1833l-7.9325 7.9325 2.87919 2.8792z\" />\n      <path d=\"m13.9956 29.8973c-.9518-1.019-1.6451-2.2826-1.9751-3.6862l-10.95836 2.9363 1.05385 3.933z\" />\n    </g>\n  </svg>\n);\n"
        },
        {
          "path": "content/components/sidebar/sidebar-03/nav-main.tsx",
          "type": "registry:component",
          "target": "components/sidebar-03/nav-main.tsx",
          "content": "\"use client\";\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarMenuSub,\n  SidebarMenuSubButton,\n  SidebarMenuItem as SidebarMenuSubItem,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\nimport { cn } from \"@/lib/utils\";\nimport { ChevronDown, ChevronUp } from \"lucide-react\";\nimport Link from \"next/link\";\nimport type React from \"react\";\nimport { useState } from \"react\";\n\nexport type Route = {\n  id: string;\n  title: string;\n  icon?: React.ReactNode;\n  link: string;\n  subs?: {\n    title: string;\n    link: string;\n    icon?: React.ReactNode;\n  }[];\n};\n\nexport default function DashboardNavigation({ routes }: { routes: Route[] }) {\n  const { state } = useSidebar();\n  const isCollapsed = state === \"collapsed\";\n  const [openCollapsible, setOpenCollapsible] = useState<string | null>(null);\n\n  return (\n    <SidebarMenu>\n      {routes.map((route) => {\n        const isOpen = !isCollapsed && openCollapsible === route.id;\n        const hasSubRoutes = !!route.subs?.length;\n\n        return (\n          <SidebarMenuItem key={route.id}>\n            {hasSubRoutes ? (\n              <Collapsible\n                open={isOpen}\n                onOpenChange={(open) =>\n                  setOpenCollapsible(open ? route.id : null)\n                }\n                className=\"w-full\"\n              >\n                <CollapsibleTrigger asChild>\n                  <SidebarMenuButton\n                    className={cn(\n                      \"flex w-full items-center rounded-lg px-2 transition-colors\",\n                      isOpen\n                        ? \"bg-sidebar-muted text-foreground\"\n                        : \"text-muted-foreground hover:bg-sidebar-muted hover:text-foreground\",\n                      isCollapsed && \"justify-center\"\n                    )}\n                  >\n                    {route.icon}\n                    {!isCollapsed && (\n                      <span className=\"ml-2 flex-1 text-sm font-medium\">\n                        {route.title}\n                      </span>\n                    )}\n                    {!isCollapsed && hasSubRoutes && (\n                      <span className=\"ml-auto\">\n                        {isOpen ? (\n                          <ChevronUp className=\"size-4\" />\n                        ) : (\n                          <ChevronDown className=\"size-4\" />\n                        )}\n                      </span>\n                    )}\n                  </SidebarMenuButton>\n                </CollapsibleTrigger>\n\n                {!isCollapsed && (\n                  <CollapsibleContent>\n                    <SidebarMenuSub className=\"my-1 ml-3.5 \">\n                      {route.subs?.map((subRoute) => (\n                        <SidebarMenuSubItem\n                          key={`${route.id}-${subRoute.title}`}\n                          className=\"h-auto\"\n                        >\n                          <SidebarMenuSubButton asChild>\n                            <Link\n                              href={subRoute.link}\n                              prefetch={true}\n                              className=\"flex items-center rounded-md px-4 py-1.5 text-sm font-medium text-muted-foreground hover:bg-sidebar-muted hover:text-foreground\"\n                            >\n                              {subRoute.title}\n                            </Link>\n                          </SidebarMenuSubButton>\n                        </SidebarMenuSubItem>\n                      ))}\n                    </SidebarMenuSub>\n                  </CollapsibleContent>\n                )}\n              </Collapsible>\n            ) : (\n              <SidebarMenuButton tooltip={route.title} asChild>\n                <Link\n                  href={route.link}\n                  prefetch={true}\n                  className={cn(\n                    \"flex items-center rounded-lg px-2 transition-colors text-muted-foreground hover:bg-sidebar-muted hover:text-foreground\",\n                    isCollapsed && \"justify-center\"\n                  )}\n                >\n                  {route.icon}\n                  {!isCollapsed && (\n                    <span className=\"ml-2 text-sm font-medium\">\n                      {route.title}\n                    </span>\n                  )}\n                </Link>\n              </SidebarMenuButton>\n            )}\n          </SidebarMenuItem>\n        );\n      })}\n    </SidebarMenu>\n  );\n}\n"
        }
      ],
      "categories": [
        "sidebar"
      ]
    },
    {
      "name": "sidebar-04",
      "type": "registry:block",
      "title": "Sidebar Double-Sided Mail",
      "description": "A sidebar double-sided mail block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "dropdown-menu",
        "sidebar"
      ],
      "dependencies": [
        "@tabler/icons-react",
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/sidebar/sidebar-04/app-sidebar.tsx",
          "type": "registry:component",
          "target": "components/sidebar-04/app-sidebar.tsx",
          "content": "\"use client\";\n\nimport { Archive, Flag } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarGroupLabel,\n  SidebarHeader,\n  SidebarInput,\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\nimport {\n  IconBrandAmongUs,\n  IconCarambola,\n  IconHourglassHigh,\n  IconMailbox,\n} from \"@tabler/icons-react\";\nimport { useMail } from \"@/components/sidebar-04/mail-context\";\nimport { NavUser } from \"@/components/sidebar-04/nav-user\";\n\n// This is sample data\nconst data = {\n  user: {\n    name: \"ephraim\",\n    email: \"ephraim@blocks.so\",\n    avatar: \"/avatar-01.png\",\n  },\n  navMain: [\n    {\n      title: \"Inbox\",\n      url: \"#\",\n      icon: IconMailbox,\n      isActive: true,\n    },\n    {\n      title: \"Starred\",\n      url: \"#\",\n      icon: IconCarambola,\n      isActive: false,\n    },\n    {\n      title: \"Important\",\n      url: \"#\",\n      icon: Flag,\n      isActive: false,\n    },\n    {\n      title: \"Scheduled\",\n      url: \"#\",\n      icon: IconHourglassHigh,\n      isActive: false,\n    },\n    {\n      title: \"Archive\",\n      url: \"#\",\n      icon: Archive,\n      isActive: false,\n    },\n  ],\n  labels: [\n    { title: \"Personal\", color: \"bg-green-400 dark:bg-green-300\" },\n    { title: \"Work\", color: \"bg-blue-400 dark:bg-blue-300\" },\n    { title: \"Travel\", color: \"bg-orange-400 dark:bg-orange-300\" },\n    { title: \"Receipts\", color: \"bg-purple-400 dark:bg-purple-300\" },\n  ],\n  mails: [\n    {\n      name: \"Nora Patel\",\n      email: \"nora@acme.co\",\n      subject: \"Welcome to Acme Mail\",\n      date: \"08:15 AM\",\n      teaser:\n        \"Hi there — here's a quick tour of your new inbox.\\nPin, label, and schedule messages to stay organized.\",\n    },\n    {\n      name: \"Stripe\",\n      email: \"no-reply@stripe.com\",\n      subject: \"Your payout has arrived\",\n      date: \"Yesterday\",\n      teaser:\n        \"A payout of $3,245.90 was sent to your bank account.\\nView details in your dashboard.\",\n    },\n    {\n      name: \"GitHub\",\n      email: \"noreply@github.com\",\n      subject: \"New activity on acme/app\",\n      date: \"Tue\",\n      teaser:\n        \"3 pull requests need your review. CI passed on main.\\nClick to open the review queue.\",\n    },\n    {\n      name: \"Ava Chen\",\n      email: \"ava.chen@example.com\",\n      subject: \"Agenda for Friday standup\",\n      date: \"Mon\",\n      teaser:\n        \"Let's cover onboarding, billing bugs, and Q4 goals.\\nReply with anything you want to add.\",\n    },\n    {\n      name: \"Figma\",\n      email: \"updates@figma.com\",\n      subject: \"What's new in Figma\",\n      date: \"Sep 12\",\n      teaser:\n        \"Variables, auto layout improvements, and dev mode updates.\\nWatch the recap to learn more.\",\n    },\n    {\n      name: \"Linear\",\n      email: \"bot@linear.app\",\n      subject: \"[ACME-432] Edit modal broken\",\n      date: \"Sep 11\",\n      teaser:\n        \"Issue created by Wendy. Repro steps included.\\nSeverity: high, priority: P1.\",\n    },\n    {\n      name: \"Airbnb\",\n      email: \"booking@airbnb.com\",\n      subject: \"Your trip to Kyoto\",\n      date: \"Sep 10\",\n      teaser:\n        \"Get ready for your stay. Check-in details and local recommendations inside.\",\n    },\n    {\n      name: \"Notion\",\n      email: \"team@notion.so\",\n      subject: \"Weekly team recap\",\n      date: \"Sep 09\",\n      teaser:\n        \"Marketing shipped pricing page revamp. Eng closed 14 issues.\\nSee full notes in the doc.\",\n    },\n    {\n      name: \"Google Calendar\",\n      email: \"calendar@google.com\",\n      subject: \"Design sync moved\",\n      date: \"Sep 09\",\n      teaser:\n        \"Event 'Design sync' moved to 3:30 PM. Meet link updated in the invite.\",\n    },\n    {\n      name: \"HN Daily\",\n      email: \"digest@ycombinator.com\",\n      subject: \"Top stories today\",\n      date: \"Sep 08\",\n      teaser:\n        \"OpenAI releases new API, SQLite 3.46, and why we left Kubernetes.\\nRead the full digest.\",\n    },\n  ],\n};\n\nexport function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {\n  // Note: I'm using state to show active item.\n  // IRL you should use the url/router.\n  const [activeItem, setActiveItem] = React.useState(data.navMain[0]);\n  const [mails, setMails] = React.useState(data.mails);\n  const [query, setQuery] = React.useState(\"\");\n  const { setOpen } = useSidebar();\n  const { setSelectedMail } = useMail();\n\n  const filteredMails = React.useMemo(() => {\n    const q = query.trim().toLowerCase();\n    if (!q) return mails;\n    return mails.filter((m) =>\n      [m.name, m.email, m.subject, m.teaser]\n        .join(\"\\n\")\n        .toLowerCase()\n        .includes(q)\n    );\n  }, [mails, query]);\n\n  return (\n    <div className=\"flex\">\n      {/* This is the first sidebar */}\n      <Sidebar\n        style={{ \"--sidebar-width\": \"12rem\" } as React.CSSProperties}\n        collapsible=\"none\"\n        className=\"border-r p-2 px-1\"\n      >\n        <SidebarHeader>\n          <SidebarMenu>\n            <SidebarMenuItem>\n              <SidebarMenuButton size=\"lg\" asChild className=\"md:h-8 md:p-0\">\n                <a href=\"#\">\n                  <div className=\"bg-sidebar-accent text-sidebar-accent-foreground flex aspect-square size-8 items-center justify-center rounded-lg\">\n                    <IconBrandAmongUs className=\"size-4\" />\n                  </div>\n                  <div className=\"grid flex-1 text-left text-sm leading-tight\">\n                    <span className=\"truncate font-medium\">Acme Inc</span>\n                    <span className=\"truncate text-xs\">Enterprise</span>\n                  </div>\n                </a>\n              </SidebarMenuButton>\n            </SidebarMenuItem>\n          </SidebarMenu>\n        </SidebarHeader>\n        <SidebarContent>\n          <SidebarGroup>\n            <SidebarGroupContent className=\"px-1.5 md:px-0\">\n              <SidebarMenu>\n                {data.navMain.map((item) => (\n                  <SidebarMenuItem key={item.title}>\n                    <SidebarMenuButton\n                      onClick={() => {\n                        setActiveItem(item);\n                        const mail = data.mails.sort(() => Math.random() - 0.5);\n                        setMails(\n                          mail.slice(\n                            0,\n                            Math.max(5, Math.floor(Math.random() * 10) + 1)\n                          )\n                        );\n                        setOpen(true);\n                      }}\n                      isActive={activeItem?.title === item.title}\n                      className=\"px-2.5 md:px-2\"\n                    >\n                      <item.icon />\n                      <span>{item.title}</span>\n                    </SidebarMenuButton>\n                  </SidebarMenuItem>\n                ))}\n              </SidebarMenu>\n            </SidebarGroupContent>\n          </SidebarGroup>\n          <SidebarGroup>\n            <SidebarGroupLabel className=\"px-1.5 md:px-0 text-xs\">\n              Labels\n            </SidebarGroupLabel>\n            <SidebarGroupContent className=\"px-1.5 md:px-0\">\n              <SidebarMenu>\n                {data.labels.map((label) => (\n                  <SidebarMenuItem key={label.title}>\n                    <SidebarMenuButton asChild className=\"px-2.5 md:px-2\">\n                      <div className=\"flex items-center gap-3\">\n                        <div\n                          className={`h-3 w-3 rounded ${label.color}`}\n                        ></div>\n                        <span>{label.title}</span>\n                      </div>\n                    </SidebarMenuButton>\n                  </SidebarMenuItem>\n                ))}\n              </SidebarMenu>\n            </SidebarGroupContent>\n          </SidebarGroup>\n        </SidebarContent>\n        <SidebarFooter>\n          <NavUser user={data.user} />\n        </SidebarFooter>\n      </Sidebar>\n\n      {/* This is the second sidebar */}\n      {/* We disable collapsible and let it fill remaining space */}\n      <Sidebar\n        collapsible=\"none\"\n        className=\"hidden flex-1 border-r md:flex min-w-96\"\n      >\n        <SidebarHeader className=\"gap-3.5 border-b p-4\">\n          <div className=\"flex w-full items-center justify-between\">\n            <div className=\"text-foreground text-base font-medium\">\n              {activeItem?.title}\n            </div>\n          </div>\n          <SidebarInput\n            placeholder=\"Type to search...\"\n            value={query}\n            onChange={(e) => setQuery(e.target.value)}\n          />\n        </SidebarHeader>\n        <SidebarContent>\n          <SidebarGroup className=\"px-0 pt-0\">\n            <SidebarGroupContent>\n              {filteredMails.length === 0 && (\n                <div className=\"text-muted-foreground p-4 text-sm\">\n                  No results\n                </div>\n              )}\n              {filteredMails.map((mail) => (\n                <a\n                  href=\"#\"\n                  key={mail.email}\n                  onClick={(e) => {\n                    e.preventDefault();\n                    setSelectedMail(mail);\n                  }}\n                  className=\"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground flex flex-col items-start gap-2 border-b p-4 text-sm leading-tight whitespace-nowrap\"\n                >\n                  <div className=\"flex w-full items-center gap-2\">\n                    <span>{mail.name}</span>{\" \"}\n                    <span className=\"ml-auto text-xs\">{mail.date}</span>\n                  </div>\n                  <span className=\"font-medium\">{mail.subject}</span>\n                  <span className=\"line-clamp-2 w-[260px] text-xs whitespace-break-spaces\">\n                    {mail.teaser}\n                  </span>\n                </a>\n              ))}\n            </SidebarGroupContent>\n          </SidebarGroup>\n        </SidebarContent>\n      </Sidebar>\n    </div>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-04/mail-context.tsx",
          "type": "registry:component",
          "target": "components/sidebar-04/mail-context.tsx",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nexport type Mail = {\n  name: string;\n  email: string;\n  subject: string;\n  date: string;\n  teaser: string;\n  labels?: string[];\n};\n\ntype MailContextValue = {\n  selectedMail: Mail | null;\n  setSelectedMail: (mail: Mail | null) => void;\n};\n\nconst MailContext = React.createContext<MailContextValue | undefined>(\n  undefined\n);\n\nexport function MailProvider({ children }: { children: React.ReactNode }) {\n  const [selectedMail, setSelectedMail] = React.useState<Mail | null>(null);\n  const value = React.useMemo(\n    () => ({ selectedMail, setSelectedMail }),\n    [selectedMail]\n  );\n  return <MailContext.Provider value={value}>{children}</MailContext.Provider>;\n}\n\nexport function useMail() {\n  const ctx = React.useContext(MailContext);\n  if (!ctx) throw new Error(\"useMail must be used within MailProvider\");\n  return ctx;\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-04/app/page.tsx",
          "type": "registry:page",
          "target": "app/page.tsx",
          "content": "\"use client\";\n\nimport { SidebarInset, SidebarProvider } from \"@/components/ui/sidebar\";\nimport { AppSidebar } from \"@/components/sidebar-04/app-sidebar\";\nimport { MailProvider, useMail } from \"@/components/sidebar-04/mail-context\";\n\nfunction MailPreview() {\n  const { selectedMail } = useMail();\n  if (!selectedMail) {\n    return (\n      <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n        Select an email to preview\n      </div>\n    );\n  }\n  return (\n    <div className=\"flex h-full flex-col\">\n      <div className=\"border-b p-4\">\n        <div className=\"text-lg font-semibold\">{selectedMail.subject}</div>\n        <div className=\"text-sm text-muted-foreground\">\n          From: {selectedMail.name} ({selectedMail.email})\n        </div>\n      </div>\n      <div className=\"p-4 text-sm whitespace-pre-wrap\">{`${selectedMail.teaser}\\n\\nThis is a sample message body for the selected email.\\nIt demonstrates the preview area on the right side.`}</div>\n    </div>\n  );\n}\n\nexport default function Page() {\n  return (\n    <SidebarProvider>\n      <MailProvider>\n        <div className=\"flex h-dvh w-full\">\n          <AppSidebar />\n          <SidebarInset>\n            <div className=\"flex-1 rounded-xl border m-2\">\n              <MailPreview />\n            </div>\n          </SidebarInset>\n        </div>\n      </MailProvider>\n    </SidebarProvider>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-04/nav-user.tsx",
          "type": "registry:component",
          "target": "components/sidebar-04/nav-user.tsx",
          "content": "\"use client\";\n\nimport {\n  BadgeCheck,\n  Bell,\n  ChevronsUpDown,\n  CreditCard,\n  LogOut,\n  Sparkles,\n} from \"lucide-react\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\n\nexport function NavUser({\n  user,\n}: {\n  user: {\n    name: string;\n    email: string;\n    avatar: string;\n  };\n}) {\n  const { isMobile } = useSidebar();\n\n  return (\n    <SidebarMenu>\n      <SidebarMenuItem>\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <SidebarMenuButton\n              size=\"lg\"\n              className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground md:h-8 md:p-0\"\n            >\n              <Avatar className=\"h-8 w-8 rounded-lg\">\n                <AvatarImage src={user.avatar} alt={user.name} />\n                <AvatarFallback className=\"rounded-lg\">CN</AvatarFallback>\n              </Avatar>\n              <div className=\"grid flex-1 text-left text-sm leading-tight\">\n                <span className=\"truncate font-medium\">{user.name}</span>\n                <span className=\"truncate text-xs\">{user.email}</span>\n              </div>\n              <ChevronsUpDown className=\"ml-auto size-4\" />\n            </SidebarMenuButton>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            className=\"w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg\"\n            side={isMobile ? \"bottom\" : \"right\"}\n            align=\"end\"\n            sideOffset={4}\n          >\n            <DropdownMenuLabel className=\"p-0 font-normal\">\n              <div className=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n                <Avatar className=\"h-8 w-8 rounded-lg\">\n                  <AvatarImage src={user.avatar} alt={user.name} />\n                  <AvatarFallback className=\"rounded-lg\">CN</AvatarFallback>\n                </Avatar>\n                <div className=\"grid flex-1 text-left text-sm leading-tight\">\n                  <span className=\"truncate font-medium\">{user.name}</span>\n                  <span className=\"truncate text-xs\">{user.email}</span>\n                </div>\n              </div>\n            </DropdownMenuLabel>\n            <DropdownMenuSeparator />\n            <DropdownMenuGroup>\n              <DropdownMenuItem>\n                <Sparkles />\n                Upgrade to Pro\n              </DropdownMenuItem>\n            </DropdownMenuGroup>\n            <DropdownMenuSeparator />\n            <DropdownMenuGroup>\n              <DropdownMenuItem>\n                <BadgeCheck />\n                Account\n              </DropdownMenuItem>\n              <DropdownMenuItem>\n                <CreditCard />\n                Billing\n              </DropdownMenuItem>\n              <DropdownMenuItem>\n                <Bell />\n                Notifications\n              </DropdownMenuItem>\n            </DropdownMenuGroup>\n            <DropdownMenuSeparator />\n            <DropdownMenuItem>\n              <LogOut />\n              Log out\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </SidebarMenuItem>\n    </SidebarMenu>\n  );\n}\n"
        }
      ],
      "categories": [
        "sidebar"
      ]
    },
    {
      "name": "sidebar-05",
      "type": "registry:block",
      "title": "Sidebar Double-Sided",
      "description": "A sidebar double-sided block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "dropdown-menu",
        "sidebar"
      ],
      "dependencies": [
        "@tabler/icons-react",
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/sidebar/sidebar-05/team-switcher.tsx",
          "type": "registry:component",
          "target": "components/sidebar-05/team-switcher.tsx",
          "content": "\"use client\";\n\nimport { ChevronsUpDown, Plus } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\n\nexport function TeamSwitcher({\n  teams,\n}: {\n  teams: {\n    name: string;\n    logo: React.ElementType;\n    plan: string;\n  }[];\n}) {\n  const { isMobile } = useSidebar();\n  const [activeTeam, setActiveTeam] = React.useState(teams[0]);\n\n  if (!activeTeam) {\n    return null;\n  }\n\n  return (\n    <SidebarMenu>\n      <SidebarMenuItem>\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <SidebarMenuButton\n              size=\"lg\"\n              className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n            >\n              <div className=\"bg-sidebar-accent text-sidebar-accent-foreground flex aspect-square size-8 items-center justify-center rounded-lg\">\n                <activeTeam.logo className=\"size-4\" />\n              </div>\n              <div className=\"grid flex-1 text-left text-sm leading-tight\">\n                <span className=\"truncate font-medium\">{activeTeam.name}</span>\n                <span className=\"truncate text-xs\">{activeTeam.plan}</span>\n              </div>\n              <ChevronsUpDown className=\"ml-auto\" />\n            </SidebarMenuButton>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            className=\"w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg\"\n            align=\"start\"\n            side={isMobile ? \"bottom\" : \"right\"}\n            sideOffset={4}\n          >\n            <DropdownMenuLabel className=\"text-muted-foreground text-xs\">\n              Teams\n            </DropdownMenuLabel>\n            {teams.map((team, index) => (\n              <DropdownMenuItem\n                key={team.name}\n                onClick={() => setActiveTeam(team)}\n                className=\"gap-2 p-2\"\n              >\n                <div className=\"flex size-6 items-center justify-center rounded-md border\">\n                  <team.logo className=\"size-3.5 shrink-0\" />\n                </div>\n                {team.name}\n                <DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>\n              </DropdownMenuItem>\n            ))}\n            <DropdownMenuSeparator />\n            <DropdownMenuItem className=\"gap-2 p-2\">\n              <div className=\"flex size-6 items-center justify-center rounded-md border bg-transparent\">\n                <Plus className=\"size-4\" />\n              </div>\n              <div className=\"text-muted-foreground font-medium\">Add team</div>\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </SidebarMenuItem>\n    </SidebarMenu>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-05/app-sidebar.tsx",
          "type": "registry:component",
          "target": "components/sidebar-05/app-sidebar.tsx",
          "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarHeader,\n  SidebarMenu,\n  SidebarMenuBadge,\n  SidebarMenuButton,\n  SidebarMenuItem,\n} from \"@/components/ui/sidebar\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  IconActivityHeartbeat,\n  IconArchive,\n  IconBackground,\n  IconBellRinging,\n  IconBrandGoogle,\n  IconBrandMeta,\n  IconBrandNpm,\n  IconBrandOpenai,\n  IconBug,\n  IconChartBar,\n  IconChevronRight,\n  IconCloud,\n  IconDatabase,\n  IconFileText,\n  IconFolder,\n  IconFolders,\n  IconGitCommit,\n  IconGitMerge,\n  IconGitPullRequest,\n  IconHome,\n  IconKey,\n  IconLockExclamation,\n  IconLockPassword,\n  IconLogout,\n  IconNorthStar,\n  IconPackageExport,\n  IconPackages,\n  IconPasswordFingerprint,\n  IconPlayerPlay,\n  IconScanEye,\n  IconSettings,\n  IconShieldLock,\n  IconStar,\n  IconTarget,\n  IconTerminal2,\n  IconUser,\n  IconUserPlus,\n  IconWebhook,\n  IconX,\n} from \"@tabler/icons-react\";\nimport type React from \"react\";\nimport { useState } from \"react\";\nimport { TeamSwitcher } from \"@/components/sidebar-05/team-switcher\";\n\nconst data = {\n  teams: [\n    {\n      name: \"OpenAI\",\n      logo: IconBrandOpenai,\n      plan: \"Enterprise\",\n    },\n    {\n      name: \"Anthropic\",\n      logo: IconNorthStar,\n      plan: \"Pro\",\n    },\n    {\n      name: \"Google\",\n      logo: IconBrandGoogle,\n      plan: \"Free\",\n    },\n    {\n      name: \"Meta\",\n      logo: IconBrandMeta,\n      plan: \"Free\",\n    },\n  ],\n};\n\ninterface SidebarItem {\n  id: string;\n  label: string;\n  icon: React.ComponentType<{ className?: string }>;\n  badge?: string;\n  hasSubItems?: boolean;\n  route?: string;\n  subItems?: {\n    id: string;\n    label: string;\n    icon: React.ComponentType<{ className?: string }>;\n    description?: string;\n    route?: string;\n  }[];\n}\n\nconst sidebarItems: SidebarItem[] = [\n  {\n    id: \"overview\",\n    label: \"Overview\",\n    icon: IconHome,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"dashboard\",\n        label: \"Dashboard\",\n        icon: IconChartBar,\n        description: \"Project overview and activity\",\n        route: \"/overview/dashboard\",\n      },\n      {\n        id: \"activity\",\n        label: \"Activity\",\n        icon: IconActivityHeartbeat,\n        description: \"Recent commits and changes\",\n        route: \"/overview/activity\",\n      },\n      {\n        id: \"insights\",\n        label: \"Insights\",\n        icon: IconTarget,\n        description: \"Code analytics and metrics\",\n        route: \"/overview/insights\",\n      },\n    ],\n  },\n  {\n    id: \"repositories\",\n    label: \"Repositories\",\n    icon: IconFolders,\n    badge: \"12\",\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"all-repos\",\n        label: \"All Repositories\",\n        icon: IconFolder,\n        description: \"Browse all your repositories\",\n        route: \"/repositories\",\n      },\n      {\n        id: \"starred\",\n        label: \"Starred\",\n        icon: IconStar,\n        description: \"Your starred repositories\",\n        route: \"/repositories/starred\",\n      },\n      {\n        id: \"archived\",\n        label: \"Archived\",\n        icon: IconArchive,\n        description: \"Archived repositories\",\n        route: \"/repositories/archived\",\n      },\n    ],\n  },\n  {\n    id: \"pull-requests\",\n    label: \"Pull Requests\",\n    icon: IconGitPullRequest,\n    badge: \"3\",\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"open-prs\",\n        label: \"Open\",\n        icon: IconGitPullRequest,\n        description: \"Open pull requests\",\n        route: \"/pull-requests/open\",\n      },\n      {\n        id: \"review-requests\",\n        label: \"Review Requests\",\n        icon: IconScanEye,\n        description: \"PRs awaiting your review\",\n        route: \"/pull-requests/review\",\n      },\n      {\n        id: \"merged\",\n        label: \"Merged\",\n        icon: IconGitMerge,\n        description: \"Recently merged PRs\",\n        route: \"/pull-requests/merged\",\n      },\n    ],\n  },\n  {\n    id: \"issues\",\n    label: \"Issues\",\n    icon: IconBug,\n    badge: \"7\",\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"open-issues\",\n        label: \"Open Issues\",\n        icon: IconBug,\n        description: \"Active issues and bugs\",\n        route: \"/issues/open\",\n      },\n      {\n        id: \"assigned\",\n        label: \"Assigned to Me\",\n        icon: IconUserPlus,\n        description: \"Issues assigned to you\",\n        route: \"/issues/assigned\",\n      },\n      {\n        id: \"created\",\n        label: \"Created by Me\",\n        icon: IconGitCommit,\n        description: \"Issues you've created\",\n        route: \"/issues/created\",\n      },\n    ],\n  },\n  {\n    id: \"actions\",\n    label: \"Actions\",\n    icon: IconBackground,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"workflows\",\n        label: \"Workflows\",\n        icon: IconPlayerPlay,\n        description: \"CI/CD workflows and pipelines\",\n        route: \"/actions/workflows\",\n      },\n      {\n        id: \"runners\",\n        label: \"Runners\",\n        icon: IconTerminal2,\n        description: \"Self-hosted runners\",\n        route: \"/actions/runners\",\n      },\n      {\n        id: \"deployments\",\n        label: \"Deployments\",\n        icon: IconCloud,\n        description: \"Deployment history\",\n        route: \"/actions/deployments\",\n      },\n    ],\n  },\n  {\n    id: \"packages\",\n    label: \"Packages\",\n    icon: IconPackages,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"published\",\n        label: \"Published\",\n        icon: IconPackageExport,\n        description: \"Your published packages\",\n        route: \"/packages/published\",\n      },\n      {\n        id: \"container-registry\",\n        label: \"Container Registry\",\n        icon: IconDatabase,\n        description: \"Docker images and containers\",\n        route: \"/packages/containers\",\n      },\n      {\n        id: \"npm-packages\",\n        label: \"npm Packages\",\n        icon: IconBrandNpm,\n        description: \"Node.js packages\",\n        route: \"/packages/npm\",\n      },\n    ],\n  },\n  {\n    id: \"security\",\n    label: \"Security\",\n    icon: IconLockPassword,\n    badge: \"2\",\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"alerts\",\n        label: \"Security Alerts\",\n        icon: IconLockExclamation,\n        description: \"Vulnerability alerts\",\n        route: \"/security/alerts\",\n      },\n      {\n        id: \"advisories\",\n        label: \"Advisories\",\n        icon: IconShieldLock,\n        description: \"Security advisories\",\n        route: \"/security/advisories\",\n      },\n      {\n        id: \"secrets\",\n        label: \"Secrets\",\n        icon: IconPasswordFingerprint,\n        description: \"Repository secrets\",\n        route: \"/security/secrets\",\n      },\n    ],\n  },\n  {\n    id: \"settings\",\n    label: \"Settings\",\n    icon: IconSettings,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"profile\",\n        label: \"Profile\",\n        icon: IconUser,\n        description: \"Your profile settings\",\n        route: \"/settings/profile\",\n      },\n      {\n        id: \"notifications\",\n        label: \"Notifications\",\n        icon: IconBellRinging,\n        description: \"Notification preferences\",\n        route: \"/settings/notifications\",\n      },\n      {\n        id: \"webhooks\",\n        label: \"Webhooks\",\n        icon: IconWebhook,\n        description: \"Webhook configurations\",\n        route: \"/settings/webhooks\",\n      },\n      {\n        id: \"api-keys\",\n        label: \"API Keys\",\n        icon: IconKey,\n        description: \"Personal access tokens\",\n        route: \"/settings/api-keys\",\n      },\n    ],\n  },\n  {\n    id: \"docs\",\n    label: \"Documentation\",\n    icon: IconFileText,\n    hasSubItems: false,\n    route: \"/docs\",\n  },\n];\n\nexport function AppSidebar() {\n  const [activeItem, setActiveItem] = useState<string | null>(\"overview\");\n  const [selectedSubItem, setSelectedSubItem] = useState<string | null>(null);\n\n  const activeItemData = sidebarItems.find((item) => item.id === activeItem);\n\n  const handleItemClick = (item: SidebarItem) => {\n    if (item.hasSubItems) {\n      const isActive = activeItem === item.id;\n      setActiveItem(isActive ? null : item.id);\n      if (isActive) {\n        setSelectedSubItem(null);\n      }\n    } else {\n      if (activeItem) {\n        setActiveItem(null);\n        setSelectedSubItem(null);\n      }\n      console.log(`[v0] Navigating to: ${item.route}`);\n    }\n  };\n\n  const handleSubItemClick = (subItem: { id: string; route?: string }) => {\n    setSelectedSubItem(selectedSubItem === subItem.id ? null : subItem.id);\n    if (subItem.route) {\n      console.log(`[v0] Navigating to: ${subItem.route}`);\n    }\n  };\n\n  return (\n    <div className=\"flex h-dvh bg-background\">\n      <Sidebar\n        side=\"left\"\n        variant=\"sidebar\"\n        collapsible=\"none\"\n        className=\"w-64 border-r\"\n      >\n        <SidebarHeader>\n          <TeamSwitcher teams={data.teams} />\n        </SidebarHeader>\n\n        <SidebarContent>\n          <SidebarGroup>\n            <SidebarGroupContent>\n              <SidebarMenu>\n                {sidebarItems.map((item) => {\n                  const Icon = item.icon;\n                  const isActive = activeItem === item.id;\n                  const chevronIndicator = (\n                    <IconChevronRight\n                      className={cn(\n                        \"h-4 w-4 transition-transform shrink-0\",\n                        isActive && \"rotate-90\"\n                      )}\n                    />\n                  );\n\n                  return (\n                    <SidebarMenuItem key={item.id}>\n                      <SidebarMenuButton\n                        isActive={isActive}\n                        className=\"w-full h-10 px-3\"\n                        onClick={() => handleItemClick(item)}\n                      >\n                        <div className=\"flex items-center gap-3 flex-1 min-w-0\">\n                          <Icon className=\"h-4 w-4 shrink-0\" />\n                          <span className=\"truncate\">{item.label}</span>\n                        </div>\n                        <div className=\"flex items-center gap-1 shrink-0 ml-auto min-w-fit\">\n                          {(item.badge || item.hasSubItems) &&\n                            (item.badge ? (\n                              <SidebarMenuBadge\n                                className={cn(\n                                  \"min-w-fit\",\n                                  item.hasSubItems && \"gap-x-3\"\n                                )}\n                              >\n                                {item.badge}\n                                {item.hasSubItems && chevronIndicator}\n                              </SidebarMenuBadge>\n                            ) : (\n                              chevronIndicator\n                            ))}\n                        </div>\n                      </SidebarMenuButton>\n                    </SidebarMenuItem>\n                  );\n                })}\n              </SidebarMenu>\n            </SidebarGroupContent>\n          </SidebarGroup>\n        </SidebarContent>\n\n        <SidebarFooter>\n          <SidebarMenu>\n            <SidebarMenuItem>\n              <SidebarMenuButton className=\"w-full h-12 px-3\">\n                <div className=\"flex items-center gap-3 flex-1 min-w-0\">\n                  <Avatar className=\"h-8 w-8 rounded-full\">\n                    <AvatarImage src=\"/avatar-01.png\" alt=\"ephraim\" />\n                    <AvatarFallback className=\"rounded-full\">E</AvatarFallback>\n                  </Avatar>\n                  <div className=\"flex-1 text-left min-w-0\">\n                    <div className=\"text-sm font-medium truncate\">ephraim</div>\n                    <div className=\"text-xs text-muted-foreground truncate\">\n                      ephraim@blocks.so\n                    </div>\n                  </div>\n                </div>\n                <IconLogout className=\"h-4 w-4 shrink-0\" />\n              </SidebarMenuButton>\n            </SidebarMenuItem>\n          </SidebarMenu>\n        </SidebarFooter>\n      </Sidebar>\n\n      {activeItem && activeItemData?.subItems && (\n        <Sidebar\n          side=\"left\"\n          variant=\"sidebar\"\n          collapsible=\"none\"\n          className=\"w-72 animate-in slide-in-from-left-5 duration-200 border-r\"\n        >\n          <SidebarHeader className=\"flex flex-row items-center justify-between border-b px-4\">\n            <h3 className=\"font-medium\">{activeItemData.label}</h3>\n            <button\n              onClick={() => setActiveItem(null)}\n              className=\"h-6 w-6 p-0 rounded-md hover:bg-sidebar-accent flex items-center justify-center\"\n            >\n              <IconX className=\"h-4 w-4\" />\n            </button>\n          </SidebarHeader>\n\n          <SidebarContent>\n            <SidebarGroup>\n              <SidebarGroupContent>\n                <SidebarMenu>\n                  {activeItemData.subItems.map((subItem) => {\n                    const SubIcon = subItem.icon;\n                    const isSelected = selectedSubItem === subItem.id;\n\n                    return (\n                      <SidebarMenuItem key={subItem.id}>\n                        <SidebarMenuButton\n                          isActive={isSelected}\n                          className=\"w-full justify-start gap-3 h-auto py-2 px-3\"\n                          onClick={() => handleSubItemClick(subItem)}\n                        >\n                          <SubIcon className=\"h-5 w-5 shrink-0 self-start mt-0.5\" />\n\n                          <div className=\"flex-1 text-left min-w-0\">\n                            <div className=\"font-medium\">{subItem.label}</div>\n                            {subItem.description && (\n                              <div className=\"text-xs text-muted-foreground mt-0.5\">\n                                {subItem.description}\n                              </div>\n                            )}\n                          </div>\n                        </SidebarMenuButton>\n                      </SidebarMenuItem>\n                    );\n                  })}\n                </SidebarMenu>\n              </SidebarGroupContent>\n            </SidebarGroup>\n          </SidebarContent>\n        </Sidebar>\n      )}\n    </div>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-05/app/page.tsx",
          "type": "registry:page",
          "target": "app/page.tsx",
          "content": "\"use client\";\n\nimport { SidebarProvider } from \"@/components/ui/sidebar\";\nimport { AppSidebar } from \"@/components/sidebar-05/app-sidebar\";\n\nexport default function Page() {\n  return (\n    <SidebarProvider>\n      <div className=\"flex h-dvh w-full\">\n        <AppSidebar />\n      </div>\n    </SidebarProvider>\n  );\n}\n"
        }
      ],
      "categories": [
        "sidebar"
      ]
    },
    {
      "name": "sidebar-06",
      "type": "registry:block",
      "title": "Sidebar Replacement",
      "description": "A sidebar replacement block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "dropdown-menu",
        "sidebar"
      ],
      "dependencies": [
        "@tabler/icons-react",
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/sidebar/sidebar-06/team-switcher.tsx",
          "type": "registry:component",
          "target": "components/sidebar-06/team-switcher.tsx",
          "content": "\"use client\";\n\nimport { ChevronsUpDown, Plus } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  useSidebar,\n} from \"@/components/ui/sidebar\";\n\nexport function TeamSwitcher({\n  teams,\n}: {\n  teams: {\n    name: string;\n    logo: React.ElementType;\n    plan: string;\n  }[];\n}) {\n  const { isMobile } = useSidebar();\n  const [activeTeam, setActiveTeam] = React.useState(teams[0]);\n\n  if (!activeTeam) {\n    return null;\n  }\n\n  return (\n    <SidebarMenu>\n      <SidebarMenuItem>\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <SidebarMenuButton\n              size=\"lg\"\n              className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n            >\n              <div className=\"bg-sidebar-accent text-sidebar-accent-foreground flex aspect-square size-8 items-center justify-center rounded-lg\">\n                <activeTeam.logo className=\"size-4\" />\n              </div>\n              <div className=\"grid flex-1 text-left text-sm leading-tight\">\n                <span className=\"truncate font-medium\">{activeTeam.name}</span>\n                <span className=\"truncate text-xs\">{activeTeam.plan}</span>\n              </div>\n              <ChevronsUpDown className=\"ml-auto\" />\n            </SidebarMenuButton>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            className=\"w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg\"\n            align=\"start\"\n            side={isMobile ? \"bottom\" : \"right\"}\n            sideOffset={4}\n          >\n            <DropdownMenuLabel className=\"text-muted-foreground text-xs\">\n              Teams\n            </DropdownMenuLabel>\n            {teams.map((team, index) => (\n              <DropdownMenuItem\n                key={team.name}\n                onClick={() => setActiveTeam(team)}\n                className=\"gap-2 p-2\"\n              >\n                <div className=\"flex size-6 items-center justify-center rounded-md border\">\n                  <team.logo className=\"size-3.5 shrink-0\" />\n                </div>\n                {team.name}\n                <DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>\n              </DropdownMenuItem>\n            ))}\n            <DropdownMenuSeparator />\n            <DropdownMenuItem className=\"gap-2 p-2\">\n              <div className=\"flex size-6 items-center justify-center rounded-md border bg-transparent\">\n                <Plus className=\"size-4\" />\n              </div>\n              <div className=\"text-muted-foreground font-medium\">Add team</div>\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </SidebarMenuItem>\n    </SidebarMenu>\n  );\n}\n"
        },
        {
          "path": "content/components/sidebar/sidebar-06/app-sidebar.tsx",
          "type": "registry:component",
          "target": "components/sidebar-06/app-sidebar.tsx",
          "content": "\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarHeader,\n  SidebarMenu,\n  SidebarMenuBadge,\n  SidebarMenuButton,\n  SidebarMenuItem,\n} from \"@/components/ui/sidebar\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  IconActivityHeartbeat,\n  IconArchive,\n  IconArrowLeft,\n  IconBackground,\n  IconBellRinging,\n  IconBrandGoogle,\n  IconBrandMeta,\n  IconBrandNpm,\n  IconBrandOpenai,\n  IconBug,\n  IconChartBar,\n  IconChevronRight,\n  IconCloud,\n  IconDatabase,\n  IconFileText,\n  IconFolder,\n  IconFolders,\n  IconGitCommit,\n  IconGitMerge,\n  IconGitPullRequest,\n  IconHome,\n  IconKey,\n  IconLockExclamation,\n  IconLockPassword,\n  IconLogout,\n  IconNorthStar,\n  IconPackageExport,\n  IconPackages,\n  IconPasswordFingerprint,\n  IconPlayerPlay,\n  IconScanEye,\n  IconSettings,\n  IconShieldLock,\n  IconStar,\n  IconTarget,\n  IconTerminal2,\n  IconUser,\n  IconUserPlus,\n  IconWebhook,\n} from \"@tabler/icons-react\";\nimport type React from \"react\";\nimport { useState } from \"react\";\nimport { TeamSwitcher } from \"@/components/sidebar-06/team-switcher\";\n\nconst data = {\n  teams: [\n    {\n      name: \"OpenAI\",\n      logo: IconBrandOpenai,\n      plan: \"Enterprise\",\n    },\n    {\n      name: \"Anthropic\",\n      logo: IconNorthStar,\n      plan: \"Pro\",\n    },\n    {\n      name: \"Google\",\n      logo: IconBrandGoogle,\n      plan: \"Free\",\n    },\n    {\n      name: \"Meta\",\n      logo: IconBrandMeta,\n      plan: \"Free\",\n    },\n  ],\n};\n\ninterface SidebarItem {\n  id: string;\n  label: string;\n  icon: React.ComponentType<{ className?: string }>;\n  badge?: string;\n  hasSubItems?: boolean;\n  route?: string;\n  subItems?: {\n    id: string;\n    label: string;\n    icon: React.ComponentType<{ className?: string }>;\n    route?: string;\n  }[];\n}\n\nconst sidebarItems: SidebarItem[] = [\n  {\n    id: \"overview\",\n    label: \"Overview\",\n    icon: IconHome,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"dashboard\",\n        label: \"Dashboard\",\n        icon: IconChartBar,\n        route: \"/overview/dashboard\",\n      },\n      {\n        id: \"activity\",\n        label: \"Activity\",\n        icon: IconActivityHeartbeat,\n        route: \"/overview/activity\",\n      },\n      {\n        id: \"insights\",\n        label: \"Insights\",\n        icon: IconTarget,\n        route: \"/overview/insights\",\n      },\n    ],\n  },\n  {\n    id: \"repositories\",\n    label: \"Repositories\",\n    icon: IconFolders,\n    badge: \"12\",\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"all-repos\",\n        label: \"All Repositories\",\n        icon: IconFolder,\n        route: \"/repositories\",\n      },\n      {\n        id: \"starred\",\n        label: \"Starred\",\n        icon: IconStar,\n        route: \"/repositories/starred\",\n      },\n      {\n        id: \"archived\",\n        label: \"Archived\",\n        icon: IconArchive,\n        route: \"/repositories/archived\",\n      },\n    ],\n  },\n  {\n    id: \"pull-requests\",\n    label: \"Pull Requests\",\n    icon: IconGitPullRequest,\n    badge: \"3\",\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"open-prs\",\n        label: \"Open\",\n        icon: IconGitPullRequest,\n        route: \"/pull-requests/open\",\n      },\n      {\n        id: \"review-requests\",\n        label: \"Review Requests\",\n        icon: IconScanEye,\n        route: \"/pull-requests/review\",\n      },\n      {\n        id: \"merged\",\n        label: \"Merged\",\n        icon: IconGitMerge,\n        route: \"/pull-requests/merged\",\n      },\n    ],\n  },\n  {\n    id: \"issues\",\n    label: \"Issues\",\n    icon: IconBug,\n    badge: \"7\",\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"open-issues\",\n        label: \"Open Issues\",\n        icon: IconBug,\n        route: \"/issues/open\",\n      },\n      {\n        id: \"assigned\",\n        label: \"Assigned to Me\",\n        icon: IconUserPlus,\n        route: \"/issues/assigned\",\n      },\n      {\n        id: \"created\",\n        label: \"Created by Me\",\n        icon: IconGitCommit,\n        route: \"/issues/created\",\n      },\n    ],\n  },\n  {\n    id: \"actions\",\n    label: \"Actions\",\n    icon: IconBackground,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"workflows\",\n        label: \"Workflows\",\n        icon: IconPlayerPlay,\n        route: \"/actions/workflows\",\n      },\n      {\n        id: \"runners\",\n        label: \"Runners\",\n        icon: IconTerminal2,\n        route: \"/actions/runners\",\n      },\n      {\n        id: \"deployments\",\n        label: \"Deployments\",\n        icon: IconCloud,\n        route: \"/actions/deployments\",\n      },\n    ],\n  },\n  {\n    id: \"packages\",\n    label: \"Packages\",\n    icon: IconPackages,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"published\",\n        label: \"Published\",\n        icon: IconPackageExport,\n        route: \"/packages/published\",\n      },\n      {\n        id: \"container-registry\",\n        label: \"Container Registry\",\n        icon: IconDatabase,\n        route: \"/packages/containers\",\n      },\n      {\n        id: \"npm-packages\",\n        label: \"npm Packages\",\n        icon: IconBrandNpm,\n        route: \"/packages/npm\",\n      },\n    ],\n  },\n  {\n    id: \"security\",\n    label: \"Security\",\n    icon: IconLockPassword,\n    badge: \"2\",\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"alerts\",\n        label: \"Security Alerts\",\n        icon: IconLockExclamation,\n        route: \"/security/alerts\",\n      },\n      {\n        id: \"advisories\",\n        label: \"Advisories\",\n        icon: IconShieldLock,\n        route: \"/security/advisories\",\n      },\n      {\n        id: \"secrets\",\n        label: \"Secrets\",\n        icon: IconPasswordFingerprint,\n        route: \"/security/secrets\",\n      },\n    ],\n  },\n  {\n    id: \"settings\",\n    label: \"Settings\",\n    icon: IconSettings,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: \"profile\",\n        label: \"Profile\",\n        icon: IconUser,\n        route: \"/settings/profile\",\n      },\n      {\n        id: \"notifications\",\n        label: \"Notifications\",\n        icon: IconBellRinging,\n        route: \"/settings/notifications\",\n      },\n      {\n        id: \"webhooks\",\n        label: \"Webhooks\",\n        icon: IconWebhook,\n        route: \"/settings/webhooks\",\n      },\n      {\n        id: \"api-keys\",\n        label: \"API Keys\",\n        icon: IconKey,\n        route: \"/settings/api-keys\",\n      },\n    ],\n  },\n  {\n    id: \"docs\",\n    label: \"Documentation\",\n    icon: IconFileText,\n    hasSubItems: false,\n    route: \"/docs\",\n  },\n];\n\nexport function AppSidebar() {\n  const [activeItem, setActiveItem] = useState<string | null>(null);\n  const [selectedSubItem, setSelectedSubItem] = useState<string | null>(null);\n\n  const activeItemData = sidebarItems.find((item) => item.id === activeItem);\n\n  const handleItemClick = (item: SidebarItem) => {\n    if (item.hasSubItems) {\n      setActiveItem(item.id);\n      setSelectedSubItem(null);\n    } else {\n      console.log(`[v0] Navigating to: ${item.route}`);\n    }\n  };\n\n  const handleSubItemClick = (subItem: { id: string; route?: string }) => {\n    setSelectedSubItem(selectedSubItem === subItem.id ? null : subItem.id);\n    if (subItem.route) {\n      console.log(`[v0] Navigating to: ${subItem.route}`);\n    }\n  };\n\n  const handleBackToMain = () => {\n    setActiveItem(null);\n    setSelectedSubItem(null);\n  };\n\n  return (\n    <div className=\"flex h-dvh bg-background\">\n      <Sidebar\n        side=\"left\"\n        variant=\"sidebar\"\n        collapsible=\"none\"\n        className=\"w-64 border-r\"\n      >\n        {!activeItem ? (\n          <>\n            <SidebarHeader>\n              <TeamSwitcher teams={data.teams} />\n            </SidebarHeader>\n\n            <SidebarContent>\n              <SidebarGroup>\n                <SidebarGroupContent>\n                  <SidebarMenu>\n                    {sidebarItems.map((item) => {\n                      const Icon = item.icon;\n                      const chevronIndicator = (\n                        <IconChevronRight className=\"h-4 w-4 transition-transform shrink-0\" />\n                      );\n\n                      return (\n                        <SidebarMenuItem key={item.id}>\n                          <SidebarMenuButton\n                            className=\"w-full h-10 px-3\"\n                            onClick={() => handleItemClick(item)}\n                          >\n                            <div className=\"flex items-center gap-3 flex-1 min-w-0\">\n                              <Icon className=\"h-4 w-4 shrink-0\" />\n                              <span className=\"truncate\">{item.label}</span>\n                            </div>\n                            <div className=\"flex items-center gap-1 shrink-0 ml-auto min-w-fit\">\n                              {(item.badge || item.hasSubItems) &&\n                                (item.badge ? (\n                                  <SidebarMenuBadge\n                                    className={cn(\n                                      \"min-w-fit\",\n                                      item.hasSubItems && \"gap-x-3\"\n                                    )}\n                                  >\n                                    {item.badge}\n                                    {item.hasSubItems && chevronIndicator}\n                                  </SidebarMenuBadge>\n                                ) : (\n                                  chevronIndicator\n                                ))}\n                            </div>\n                          </SidebarMenuButton>\n                        </SidebarMenuItem>\n                      );\n                    })}\n                  </SidebarMenu>\n                </SidebarGroupContent>\n              </SidebarGroup>\n            </SidebarContent>\n\n            <SidebarFooter>\n              <SidebarMenu>\n                <SidebarMenuItem>\n                  <SidebarMenuButton className=\"w-full h-12 px-3\">\n                    <div className=\"flex items-center gap-3 flex-1 min-w-0\">\n                      <Avatar className=\"h-8 w-8 rounded-full\">\n                        <AvatarImage src=\"/avatar-01.png\" alt=\"ephraim\" />\n                        <AvatarFallback className=\"rounded-full\">E</AvatarFallback>\n                      </Avatar>\n                      <div className=\"flex-1 text-left min-w-0\">\n                        <div className=\"text-sm font-medium truncate\">ephraim</div>\n                        <div className=\"text-xs text-muted-foreground truncate\">\n                          ephraim@blocks.so\n                        </div>\n                      </div>\n                    </div>\n                    <IconLogout className=\"h-4 w-4 shrink-0\" />\n                  </SidebarMenuButton>\n                </SidebarMenuItem>\n              </SidebarMenu>\n            </SidebarFooter>\n          </>\n        ) : (\n          activeItemData?.subItems && (\n            <>\n              <SidebarHeader className=\"flex flex-row items-center justify-between border-b px-4\">\n                <button\n                  onClick={handleBackToMain}\n                  className=\"h-8 w-8 p-0 rounded-md hover:bg-sidebar-accent flex items-center justify-center\"\n                >\n                  <IconArrowLeft className=\"h-4 w-4\" />\n                </button>\n                <h3 className=\"font-medium flex-1 text-center\">{activeItemData.label}</h3>\n                <div className=\"w-8\" />\n              </SidebarHeader>\n\n              <SidebarContent>\n                <SidebarGroup>\n                  <SidebarGroupContent>\n                    <SidebarMenu>\n                      {activeItemData.subItems.map((subItem) => {\n                        const SubIcon = subItem.icon;\n                        const isSelected = selectedSubItem === subItem.id;\n\n                        return (\n                          <SidebarMenuItem key={subItem.id}>\n                            <SidebarMenuButton\n                              isActive={isSelected}\n                              className=\"w-full h-10 px-3\"\n                              onClick={() => handleSubItemClick(subItem)}\n                            >\n                              <div className=\"flex items-center gap-3 flex-1 min-w-0\">\n                                <SubIcon className=\"h-4 w-4 shrink-0\" />\n                                <span className=\"truncate\">{subItem.label}</span>\n                              </div>\n                            </SidebarMenuButton>\n                          </SidebarMenuItem>\n                        );\n                      })}\n                    </SidebarMenu>\n                  </SidebarGroupContent>\n                </SidebarGroup>\n              </SidebarContent>\n            </>\n          )\n        )}\n      </Sidebar>\n    </div>\n  );\n}"
        },
        {
          "path": "content/components/sidebar/sidebar-06/app/page.tsx",
          "type": "registry:page",
          "target": "app/page.tsx",
          "content": "\"use client\";\n\nimport { SidebarProvider } from \"@/components/ui/sidebar\";\nimport { AppSidebar } from \"@/components/sidebar-06/app-sidebar\";\n\nexport default function Page() {\n  return (\n    <SidebarProvider>\n      <div className=\"flex h-dvh w-full\">\n        <AppSidebar />\n      </div>\n    </SidebarProvider>\n  );\n}"
        }
      ],
      "categories": [
        "sidebar"
      ]
    },
    {
      "name": "stats-01",
      "type": "registry:block",
      "title": "Stats with Trending",
      "description": "A stats with trending block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/stats/stats-01.tsx",
          "type": "registry:component",
          "target": "components/stats-01.tsx",
          "content": "import { Card, CardContent } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\n\nconst data = [\n  {\n    name: \"Profit\",\n    value: \"$287,654.00\",\n    change: \"+8.32%\",\n    changeType: \"positive\",\n  },\n  {\n    name: \"Late payments\",\n    value: \"$9,435.00\",\n    change: \"-12.64%\",\n    changeType: \"negative\",\n  },\n  {\n    name: \"Pending orders\",\n    value: \"$173,229.00\",\n    change: \"+2.87%\",\n    changeType: \"positive\",\n  },\n  {\n    name: \"Operating costs\",\n    value: \"$52,891.00\",\n    change: \"-5.73%\",\n    changeType: \"negative\",\n  },\n];\n\nexport default function Stats01() {\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <div className=\"mx-auto grid grid-cols-1 gap-px rounded-xl bg-border sm:grid-cols-2 lg:grid-cols-4\">\n        {data.map((stat, index) => (\n          <Card\n            key={stat.name}\n            className={cn(\n              \"rounded-none border-0 shadow-none py-0\",\n              index === 0 && \"rounded-l-xl\",\n              index === data.length - 1 && \"rounded-r-xl\"\n            )}\n          >\n            <CardContent className=\"flex flex-wrap items-baseline justify-between gap-x-4 gap-y-2 p-4 sm:p-6\">\n              <div className=\"text-sm font-medium text-muted-foreground\">\n                {stat.name}\n              </div>\n              <div\n                className={cn(\n                  \"tabular-nums text-xs font-medium\",\n                  stat.changeType === \"positive\"\n                    ? \"text-green-800 dark:text-green-400\"\n                    : \"text-red-800 dark:text-red-400\"\n                )}\n              >\n                {stat.change}\n              </div>\n              <div className=\"tabular-nums w-full flex-none text-3xl font-medium tracking-tight text-foreground\">\n                {stat.value}\n              </div>\n            </CardContent>\n          </Card>\n        ))}\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-02",
      "type": "registry:block",
      "title": "Stats with Borders",
      "description": "A stats with borders block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "card"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/stats/stats-02.tsx",
          "type": "registry:component",
          "target": "components/stats-02.tsx",
          "content": "import { Badge } from \"@/components/ui/badge\";\nimport { Card, CardContent, CardTitle } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\nimport { TrendingDown, TrendingUp } from \"lucide-react\";\n\nconst stats = [\n  {\n    metric: \"Active Users\",\n    current: \"128,456\",\n    previous: \"115,789\",\n    difference: \"10.9%\",\n    trend: \"up\",\n  },\n  {\n    metric: \"Conversion Rate\",\n    current: \"5.32%\",\n    previous: \"6.18%\",\n    difference: \"0.86%\",\n    trend: \"down\",\n  },\n  {\n    metric: \"Avg. Session Duration\",\n    current: \"3m 42s\",\n    previous: \"3m 15s\",\n    difference: \"13.8%\",\n    trend: \"up\",\n  },\n];\n\nexport default function Stats02() {\n  return (\n    <div className=\"flex items-center justify-center p-10\">\n      <div className=\"grid grid-cols-1 divide-y bg-border divide-border overflow-hidden rounded-lg md:grid-cols-3 md:divide-x md:divide-y-0\">\n        {stats.map((item) => (\n          <Card\n            key={item.metric}\n            className=\"rounded-none border-0 shadow-sm py-0\"\n          >\n            <CardContent className=\"p-4 sm:p-6\">\n              <CardTitle className=\"text-base font-normal\">\n                {item.metric}\n              </CardTitle>\n              <div className=\"mt-1 flex items-baseline gap-2 md:block lg:flex\">\n                <div className=\"tabular-nums flex items-baseline text-2xl font-semibold text-primary\">\n                  {item.current}\n                  <span className=\"tabular-nums ml-2 text-sm font-medium text-muted-foreground\">\n                    from {item.previous}\n                  </span>\n                </div>\n\n                <Badge\n                  variant=\"outline\"\n                  className={cn(\n                    \"tabular-nums inline-flex items-center px-1.5 ps-2.5 py-0.5 text-xs font-medium md:mt-2 lg:mt-0\",\n                    item.trend === \"up\"\n                      ? \"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400\"\n                      : \"bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400\"\n                  )}\n                >\n                  {item.trend === \"up\" ? (\n                    <TrendingUp className=\"mr-0.5 -ml-1 h-5 w-5 shrink-0 self-center text-green-500\" />\n                  ) : (\n                    <TrendingDown className=\"mr-0.5 -ml-1 h-5 w-5 shrink-0 self-center text-red-500\" />\n                  )}\n\n                  <span className=\"sr-only\">\n                    {\" \"}\n                    {item.trend === \"up\" ? \"Increased\" : \"Decreased\"} by{\" \"}\n                  </span>\n                  {item.difference}\n                </Badge>\n              </div>\n            </CardContent>\n          </Card>\n        ))}\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-03",
      "type": "registry:block",
      "title": "Stats with Card Layout",
      "description": "A stats with card layout block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/stats/stats-03.tsx",
          "type": "registry:component",
          "target": "components/stats-03.tsx",
          "content": "\"use client\";\n\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\n\nconst data = [\n  {\n    name: \"Unique visitors\",\n    stat: \"10,450\",\n    change: \"-12.5%\",\n    changeType: \"negative\",\n  },\n  {\n    name: \"Bounce rate\",\n    stat: \"56.1%\",\n    change: \"+1.8%\",\n    changeType: \"positive\",\n  },\n  {\n    name: \"Visit duration\",\n    stat: \"5.2min\",\n    change: \"+19.7%\",\n    changeType: \"positive\",\n  },\n  {\n    name: \"Conversion rate\",\n    stat: \"3.2%\",\n    change: \"-2.4%\",\n    changeType: \"negative\",\n  },\n];\n\nexport default function Stats03() {\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full\">\n      <dl className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4 w-full\">\n        {data.map((item) => (\n          <Card key={item.name} className=\"p-6 py-4 shadow-2xs\">\n            <CardContent className=\"p-0\">\n              <dt className=\"text-sm font-medium text-muted-foreground\">{item.name}</dt>\n              <dd className=\"mt-2 flex items-baseline space-x-2.5\">\n                <span className=\"tabular-nums text-3xl font-semibold text-foreground\">\n                  {item.stat}\n                </span>\n                <span\n                  className={cn(\n                    item.changeType === \"positive\"\n                      ? \"text-green-800 dark:text-green-400\"\n                      : \"text-red-800 dark:text-red-400\",\n                    \"text-sm font-medium\",\n                  )}\n                >\n                  {item.change}\n                </span>\n              </dd>\n            </CardContent>\n          </Card>\n        ))}\n      </dl>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-04",
      "type": "registry:block",
      "title": "Stats with Badges",
      "description": "A stats with badges block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "card"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/stats/stats-04.tsx",
          "type": "registry:component",
          "target": "components/stats-04.tsx",
          "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\nimport { TrendingDown, TrendingUp } from \"lucide-react\";\n\nconst data = [\n  {\n    name: \"Daily active users\",\n    stat: \"3,450\",\n    change: \"+12.1%\",\n    changeType: \"positive\",\n  },\n  {\n    name: \"Weekly sessions\",\n    stat: \"1,342\",\n    change: \"-9.8%\",\n    changeType: \"negative\",\n  },\n  {\n    name: \"Duration\",\n    stat: \"5.2min\",\n    change: \"+7.7%\",\n    changeType: \"positive\",\n  },\n];\n\nexport default function Stats04() {\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full\">\n      <dl className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 w-full\">\n        {data.map((item) => (\n          <Card key={item.name} className=\"p-6 py-4 w-full shadow-2xs\">\n            <CardContent className=\"p-0\">\n              <div className=\"flex items-center justify-between\">\n                <dt className=\"text-sm font-medium text-muted-foreground\">{item.name}</dt>\n                <Badge\n                  variant=\"outline\"\n                  className={cn(\n                    \"font-medium inline-flex items-center px-1.5 ps-2.5 py-0.5 text-xs\",\n                    item.changeType === \"positive\"\n                      ? \"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400\"\n                      : \"bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400\",\n                  )}\n                >\n                  {item.changeType === \"positive\" ? (\n                    <TrendingUp className=\"mr-0.5 -ml-1 h-5 w-5 shrink-0 self-center text-green-500\" />\n                  ) : (\n                    <TrendingDown className=\"mr-0.5 -ml-1 h-5 w-5 shrink-0 self-center text-red-500\" />\n                  )}\n                  <span className=\"sr-only\">\n                    {\" \"}\n                    {item.changeType === \"positive\" ? \"Increased\" : \"Decreased\"} by{\" \"}\n                  </span>\n                  {item.change}\n                </Badge>\n              </div>\n              <dd className=\"tabular-nums text-3xl font-semibold text-foreground mt-2\">\n                {item.stat}\n              </dd>\n            </CardContent>\n          </Card>\n        ))}\n      </dl>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-05",
      "type": "registry:block",
      "title": "Stats with Links",
      "description": "A stats with links block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/stats/stats-05.tsx",
          "type": "registry:component",
          "target": "components/stats-05.tsx",
          "content": "\"use client\";\n\nimport { Card, CardContent, CardFooter } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\n\nconst data = [\n  {\n    name: \"Monthly recurring revenue\",\n    value: \"$34.1K\",\n    change: \"+6.1%\",\n    changeType: \"positive\",\n    href: \"#\",\n  },\n  {\n    name: \"Users\",\n    value: \"500.1K\",\n    change: \"+19.2%\",\n    changeType: \"positive\",\n    href: \"#\",\n  },\n  {\n    name: \"User growth\",\n    value: \"11.3%\",\n    change: \"-1.2%\",\n    changeType: \"negative\",\n    href: \"#\",\n  },\n];\n\nexport default function Stats05() {\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full\">\n      <dl className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 w-full\">\n        {data.map((item) => (\n          <Card key={item.name} className=\"p-0 gap-0 shadow-2xs\">\n            <CardContent className=\"p-6\">\n              <dd className=\"flex items-start justify-between space-x-2\">\n                <span className=\"truncate text-sm text-muted-foreground\">{item.name}</span>\n                <span\n                  className={cn(\n                    \"text-sm font-medium\",\n                    item.changeType === \"positive\"\n                      ? \"text-emerald-700 dark:text-emerald-500\"\n                      : \"text-red-700 dark:text-red-500\",\n                  )}\n                >\n                  {item.change}\n                </span>\n              </dd>\n              <dd className=\"tabular-nums mt-1 text-3xl font-semibold text-foreground\">\n                {item.value}\n              </dd>\n            </CardContent>\n            <CardFooter className=\"flex justify-end border-t border-border p-0!\">\n              <a\n                href={item.href}\n                className=\"px-6 py-3 text-sm font-medium text-primary hover:text-primary/90\"\n              >\n                View more &#8594;\n              </a>\n            </CardFooter>\n          </Card>\n        ))}\n      </dl>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-06",
      "type": "registry:block",
      "title": "Stats with Status",
      "description": "A stats with status block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/stats/stats-06.tsx",
          "type": "registry:component",
          "target": "components/stats-06.tsx",
          "content": "\"use client\";\n\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\nimport { AlertTriangle, Check, ChevronRight, Eye } from \"lucide-react\";\nimport Link from \"next/link\";\n\nconst data = [\n  {\n    name: \"Europe\",\n    stat: \"$10,023\",\n    goalsAchieved: 3,\n    status: \"observe\",\n    href: \"#\",\n  },\n  {\n    name: \"North America\",\n    stat: \"$14,092\",\n    goalsAchieved: 5,\n    status: \"within\",\n    href: \"#\",\n  },\n  {\n    name: \"Asia\",\n    stat: \"$113,232\",\n    goalsAchieved: 1,\n    status: \"critical\",\n    href: \"#\",\n  },\n];\n\nexport default function Stats06() {\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full\">\n      <dl className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 w-full\">\n        {data.map((item) => (\n          <Card key={item.name} className=\"p-6 relative shadow-2xs\">\n            <CardContent className=\"p-0\">\n              <dt className=\"text-sm font-medium text-muted-foreground\">{item.name}</dt>\n              <dd className=\"tabular-nums text-3xl font-semibold text-foreground\">{item.stat}</dd>\n              <div className=\"group relative mt-6 flex items-center space-x-4 rounded-md bg-muted/60 p-2 hover:bg-muted\">\n                <div className=\"flex w-full items-center justify-between truncate\">\n                  <div className=\"flex items-center space-x-3\">\n                    <span\n                      className={cn(\n                        \"flex h-9 w-9 shrink-0 items-center justify-center rounded\",\n                        item.status === \"within\"\n                          ? \"bg-emerald-500 text-white\"\n                          : item.status === \"observe\"\n                            ? \"bg-yellow-500 text-white\"\n                            : \"bg-red-500 text-white\",\n                      )}\n                    >\n                      {item.status === \"within\" ? (\n                        <Check className=\"size-4 shrink-0\" aria-hidden={true} />\n                      ) : item.status === \"observe\" ? (\n                        <Eye className=\"size-4 shrink-0\" aria-hidden={true} />\n                      ) : (\n                        <AlertTriangle className=\"size-4 shrink-0\" aria-hidden={true} />\n                      )}\n                    </span>\n                    <dd>\n                      <p className=\"text-pretty text-sm text-muted-foreground\">\n                        <Link href={item.href} className=\"focus:outline-none\">\n                          {/* Extend link to entire card */}\n                          <span className=\"absolute inset-0\" aria-hidden={true} />\n                          {item.goalsAchieved}/5 goals\n                        </Link>\n                      </p>\n                      <p\n                        className={cn(\n                          \"text-sm font-medium\",\n                          item.status === \"within\"\n                            ? \"text-emerald-800 dark:text-emerald-500\"\n                            : item.status === \"observe\"\n                              ? \"text-yellow-800 dark:text-yellow-500\"\n                              : \"text-red-800 dark:text-red-500\",\n                        )}\n                      >\n                        {item.status}\n                      </p>\n                    </dd>\n                  </div>\n                  <ChevronRight\n                    className=\"size-5 shrink-0 text-muted-foreground/60 group-hover:text-muted-foreground\"\n                    aria-hidden={true}\n                  />\n                </div>\n              </div>\n            </CardContent>\n          </Card>\n        ))}\n      </dl>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-07",
      "type": "registry:block",
      "title": "Stats with Circular Progress",
      "description": "A stats with circular progress block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card",
        "chart"
      ],
      "dependencies": [
        "lucide-react",
        "recharts"
      ],
      "files": [
        {
          "path": "content/components/stats/stats-07.tsx",
          "type": "registry:component",
          "target": "components/stats-07.tsx",
          "content": "\"use client\";\n\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { type ChartConfig, ChartContainer } from \"@/components/ui/chart\";\nimport { ExternalLink } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { PolarAngleAxis, RadialBar, RadialBarChart } from \"recharts\";\n\nconst data = [\n  {\n    name: \"Workspaces\",\n    capacity: 20,\n    current: 1,\n    allowed: 5,\n    fill: \"var(--chart-1)\",\n  },\n  {\n    name: \"Dashboards\",\n    capacity: 10,\n    current: 2,\n    allowed: 20,\n    fill: \"var(--chart-2)\",\n  },\n  {\n    name: \"Chart widgets\",\n    capacity: 30,\n    current: 15,\n    allowed: 50,\n    fill: \"var(--chart-3)\",\n  },\n  {\n    name: \"Storage\",\n    capacity: 50,\n    current: 25,\n    allowed: 100,\n    fill: \"var(--chart-4)\",\n  },\n];\n\nconst chartConfig = {\n  capacity: {\n    label: \"Capacity\",\n    color: \"hsl(var(--primary))\",\n  },\n} satisfies ChartConfig;\n\nexport default function Stats07() {\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full\">\n      <div className=\"w-full\">\n        <h2 className=\"text-balance text-xl font-medium text-foreground\">Plan overview</h2>\n        <p className=\"text-pretty mt-1 text-sm leading-6 text-muted-foreground\">\n          You are currently on the <span className=\"font-medium text-foreground\">starter plan</span>\n          .{\" \"}\n          <Link\n            href=\"#\"\n            className=\"inline-flex items-center gap-1 text-primary hover:underline hover:underline-offset-4\"\n          >\n            View other plans\n            <ExternalLink className=\"size-4\" aria-hidden={true} />\n          </Link>\n        </p>\n        <dl className=\"mt-6 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4\">\n          {data.map((item) => (\n            <Card key={item.name} className=\"p-4 shadow-2xs\">\n              <CardContent className=\"p-0 flex items-center space-x-4\">\n                <div className=\"relative flex items-center justify-center\">\n                  <ChartContainer config={chartConfig} className=\"h-[80px] w-[80px]\">\n                    <RadialBarChart\n                      data={[item]}\n                      innerRadius={30}\n                      outerRadius={60}\n                      barSize={6}\n                      startAngle={90}\n                      endAngle={-270}\n                    >\n                      <PolarAngleAxis\n                        type=\"number\"\n                        domain={[0, 100]}\n                        angleAxisId={0}\n                        tick={false}\n                        axisLine={false}\n                      />\n                      <RadialBar\n                        dataKey=\"capacity\"\n                        background\n                        cornerRadius={10}\n                        fill=\"var(--primary)\"\n                        angleAxisId={0}\n                      />\n                    </RadialBarChart>\n                  </ChartContainer>\n                  <div className=\"absolute inset-0 flex items-center justify-center\">\n                    <span className=\"text-base font-medium text-foreground\">{item.capacity}%</span>\n                  </div>\n                </div>\n                <div>\n                  <dt className=\"text-sm font-medium text-foreground\">{item.name}</dt>\n                  <dd className=\"text-sm text-muted-foreground\">\n                    {item.current} of {item.allowed} used\n                  </dd>\n                </div>\n              </CardContent>\n            </Card>\n          ))}\n        </dl>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-08",
      "type": "registry:block",
      "title": "Stats with Circular Progress and Links",
      "description": "A stats with circular progress and links block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card",
        "chart"
      ],
      "dependencies": [
        "recharts"
      ],
      "files": [
        {
          "path": "content/components/stats/stats-08.tsx",
          "type": "registry:component",
          "target": "components/stats-08.tsx",
          "content": "\"use client\";\n\nimport { Card, CardContent, CardFooter } from \"@/components/ui/card\";\nimport { type ChartConfig, ChartContainer } from \"@/components/ui/chart\";\nimport { PolarAngleAxis, RadialBar, RadialBarChart } from \"recharts\";\n\nconst data = [\n  {\n    name: \"HR\",\n    progress: 25,\n    budget: \"$1,000\",\n    current: \"$250\",\n    href: \"#\",\n    fill: \"var(--chart-1)\",\n  },\n  {\n    name: \"Marketing\",\n    progress: 55,\n    budget: \"$1,000\",\n    current: \"$550\",\n    href: \"#\",\n    fill: \"var(--chart-2)\",\n  },\n  {\n    name: \"Finance\",\n    progress: 85,\n    budget: \"$1,000\",\n    current: \"$850\",\n    href: \"#\",\n    fill: \"var(--chart-3)\",\n  },\n  {\n    name: \"Engineering\",\n    progress: 70,\n    budget: \"$2,000\",\n    current: \"$1,400\",\n    href: \"#\",\n    fill: \"var(--chart-4)\",\n  },\n];\n\nconst chartConfig = {\n  progress: {\n    label: \"Progress\",\n    color: \"var(--primary)\",\n  },\n} satisfies ChartConfig;\n\nexport default function Stats08() {\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full\">\n      <dl className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4 w-full\">\n        {data.map((item) => (\n          <Card key={item.name} className=\"p-0 gap-0 shadow-2xs\">\n            <CardContent className=\"p-4\">\n              <div className=\"flex items-center space-x-3\">\n                <div className=\"relative flex items-center justify-center\">\n                  <ChartContainer config={chartConfig} className=\"h-[80px] w-[80px]\">\n                    <RadialBarChart\n                      data={[item]}\n                      innerRadius={30}\n                      outerRadius={60}\n                      barSize={6}\n                      startAngle={90}\n                      endAngle={-270}\n                    >\n                      <PolarAngleAxis\n                        type=\"number\"\n                        domain={[0, 100]}\n                        angleAxisId={0}\n                        tick={false}\n                        axisLine={false}\n                      />\n                      <RadialBar\n                        dataKey=\"progress\"\n                        background\n                        cornerRadius={10}\n                        fill={item.fill}\n                        angleAxisId={0}\n                      />\n                    </RadialBarChart>\n                  </ChartContainer>\n                  <div className=\"absolute inset-0 flex items-center justify-center\">\n                    <span className=\"text-base font-medium text-foreground\">{item.progress}%</span>\n                  </div>\n                </div>\n                <div>\n                  <dd className=\"text-base font-medium text-foreground\">\n                    {item.current} / {item.budget}\n                  </dd>\n                  <dt className=\"text-sm text-muted-foreground\">Budget {item.name}</dt>\n                </div>\n              </div>\n            </CardContent>\n            <CardFooter className=\"flex items-center justify-end border-t border-border p-0!\">\n              <a\n                href={item.href}\n                className=\"text-sm font-medium text-primary px-6 py-3 hover:text-primary/90\"\n              >\n                View more &#8594;\n              </a>\n            </CardFooter>\n          </Card>\n        ))}\n      </dl>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-09",
      "type": "registry:block",
      "title": "Stats with Progress",
      "description": "A stats with progress block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card",
        "progress"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/stats/stats-09.tsx",
          "type": "registry:component",
          "target": "components/stats-09.tsx",
          "content": "\"use client\";\n\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Progress } from \"@/components/ui/progress\";\n\nconst data = [\n  {\n    name: \"Requests\",\n    stat: \"996\",\n    limit: \"10,000\",\n    percentage: 9.96,\n  },\n  {\n    name: \"Credits\",\n    stat: \"$672\",\n    limit: \"$1,000\",\n    percentage: 67.2,\n  },\n  {\n    name: \"Storage\",\n    stat: \"1.85\",\n    limit: \"10GB\",\n    percentage: 18.5,\n  },\n  {\n    name: \"API Calls\",\n    stat: \"4,328\",\n    limit: \"5,000\",\n    percentage: 86.56,\n  },\n];\n\nexport default function Stats09() {\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full\">\n      <dl className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4 w-full\">\n        {data.map((item) => (\n          <Card key={item.name} className=\"py-4 shadow-2xs\">\n            <CardContent className=\"\">\n              <dt className=\"text-sm text-muted-foreground\">{item.name}</dt>\n              <dd className=\"tabular-nums text-2xl font-semibold text-foreground\">{item.stat}</dd>\n              <Progress value={item.percentage} className=\"mt-6 h-2\" />\n              <dd className=\"mt-2 flex items-center justify-between text-sm\">\n                <span className=\"text-primary\">{item.percentage}&#37;</span>\n                <span className=\"text-muted-foreground\">\n                  {item.stat} of {item.limit}\n                </span>\n              </dd>\n            </CardContent>\n          </Card>\n        ))}\n      </dl>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-10",
      "type": "registry:block",
      "title": "Stats with Area Chart",
      "description": "A stats with area chart block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card",
        "chart"
      ],
      "dependencies": [
        "recharts"
      ],
      "files": [
        {
          "path": "content/components/stats/stats-10.tsx",
          "type": "registry:component",
          "target": "components/stats-10.tsx",
          "content": "\"use client\";\n\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { ChartContainer } from \"@/components/ui/chart\";\nimport { cn } from \"@/lib/utils\";\nimport { Area, AreaChart, XAxis } from \"recharts\";\n\nconst data = [\n  {\n    date: \"Nov 24, 2023\",\n    \"Alpha Corp\": 142.87,\n    \"Beta Solutions\": 65.32,\n    \"Gamma Industries\": 83.25,\n  },\n  {\n    date: \"Nov 25, 2023\",\n    \"Alpha Corp\": 151.43,\n    \"Beta Solutions\": 59.78,\n    \"Gamma Industries\": 79.64,\n  },\n  {\n    date: \"Nov 26, 2023\",\n    \"Alpha Corp\": 157.28,\n    \"Beta Solutions\": 64.21,\n    \"Gamma Industries\": 76.19,\n  },\n  {\n    date: \"Nov 27, 2023\",\n    \"Alpha Corp\": 162.94,\n    \"Beta Solutions\": 57.46,\n    \"Gamma Industries\": 72.84,\n  },\n  {\n    date: \"Nov 28, 2023\",\n    \"Alpha Corp\": 148.37,\n    \"Beta Solutions\": 49.82,\n    \"Gamma Industries\": 81.56,\n  },\n  {\n    date: \"Nov 29, 2023\",\n    \"Alpha Corp\": 139.56,\n    \"Beta Solutions\": 55.63,\n    \"Gamma Industries\": 92.38,\n  },\n  {\n    date: \"Nov 30, 2023\",\n    \"Alpha Corp\": 145.83,\n    \"Beta Solutions\": 61.27,\n    \"Gamma Industries\": 88.75,\n  },\n  {\n    date: \"Dec 01, 2023\",\n    \"Alpha Corp\": 138.29,\n    \"Beta Solutions\": 68.94,\n    \"Gamma Industries\": 93.42,\n  },\n  {\n    date: \"Dec 02, 2023\",\n    \"Alpha Corp\": 129.64,\n    \"Beta Solutions\": 74.56,\n    \"Gamma Industries\": 97.18,\n  },\n  {\n    date: \"Dec 03, 2023\",\n    \"Alpha Corp\": 119.82,\n    \"Beta Solutions\": 71.38,\n    \"Gamma Industries\": 89.43,\n  },\n  {\n    date: \"Dec 04, 2023\",\n    \"Alpha Corp\": 128.54,\n    \"Beta Solutions\": 63.95,\n    \"Gamma Industries\": 92.76,\n  },\n  {\n    date: \"Dec 05, 2023\",\n    \"Alpha Corp\": 137.21,\n    \"Beta Solutions\": 58.47,\n    \"Gamma Industries\": 84.29,\n  },\n  {\n    date: \"Dec 06, 2023\",\n    \"Alpha Corp\": 134.68,\n    \"Beta Solutions\": 69.12,\n    \"Gamma Industries\": 79.38,\n  },\n  {\n    date: \"Dec 07, 2023\",\n    \"Alpha Corp\": 152.73,\n    \"Beta Solutions\": 73.89,\n    \"Gamma Industries\": 81.42,\n  },\n  {\n    date: \"Dec 08, 2023\",\n    \"Alpha Corp\": 168.59,\n    \"Beta Solutions\": 78.54,\n    \"Gamma Industries\": 75.68,\n  },\n];\n\nconst summary = [\n  {\n    name: \"Alpha Corp\",\n    tickerSymbol: \"ACP\",\n    value: \"$168.59\",\n    change: \"+15.86\",\n    percentageChange: \"+10.4%\",\n    changeType: \"positive\",\n  },\n  {\n    name: \"Beta Solutions\",\n    tickerSymbol: \"BTS\",\n    value: \"$78.54\",\n    change: \"+4.65\",\n    percentageChange: \"+6.3%\",\n    changeType: \"positive\",\n  },\n  {\n    name: \"Gamma Industries\",\n    tickerSymbol: \"GMI\",\n    value: \"$75.68\",\n    change: \"-5.74\",\n    percentageChange: \"-7.1%\",\n    changeType: \"negative\",\n  },\n];\n\nconst sanitizeName = (name: string) => {\n  return name\n    .replace(/\\\\s+/g, \"-\")\n    .replace(/[^a-zA-Z0-9-]/g, \"_\")\n    .toLowerCase();\n};\n\nexport default function Stats10() {\n  return (\n    <div className=\"flex items-center justify-center p-10 w-full\">\n      <dl className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 w-full\">\n        {summary.map((item) => {\n          const sanitizedName = sanitizeName(item.name);\n          const gradientId = `gradient-${sanitizedName}`;\n\n          const color =\n            item.changeType === \"positive\" ? \"hsl(142.1 76.2% 36.3%)\" : \"hsl(0 72.2% 50.6%)\";\n\n          return (\n            <Card key={item.name} className=\"p-0 shadow-2xs\">\n              <CardContent className=\"p-4 pb-0\">\n                <div>\n                  <dt className=\"text-sm font-medium text-foreground\">\n                    {item.name}{\" \"}\n                    <span className=\"font-normal text-muted-foreground\">({item.tickerSymbol})</span>\n                  </dt>\n                  <div className=\"flex items-baseline justify-between\">\n                    <dd\n                      className={cn(\n                        item.changeType === \"positive\"\n                          ? \"text-green-600 dark:text-green-500\"\n                          : \"text-red-600 dark:text-red-500\",\n                        \"text-lg font-semibold\",\n                      )}\n                    >\n                      {item.value}\n                    </dd>\n                    <dd className=\"flex items-center space-x-1 text-sm\">\n                      <span className=\"font-medium text-foreground\">{item.change}</span>\n                      <span\n                        className={cn(\n                          item.changeType === \"positive\"\n                            ? \"text-green-600 dark:text-green-500\"\n                            : \"text-red-600 dark:text-red-500\",\n                        )}\n                      >\n                        ({item.percentageChange})\n                      </span>\n                    </dd>\n                  </div>\n                </div>\n\n                <div className=\"mt-2 h-16 overflow-hidden\">\n                  <ChartContainer\n                    className=\"w-full h-full\"\n                    config={{\n                      [item.name]: {\n                        label: item.name,\n                        color: color,\n                      },\n                    }}\n                  >\n                    <AreaChart data={data}>\n                      <defs>\n                        <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n                          <stop offset=\"5%\" stopColor={color} stopOpacity={0.3} />\n                          <stop offset=\"95%\" stopColor={color} stopOpacity={0} />\n                        </linearGradient>\n                      </defs>\n                      <XAxis dataKey=\"date\" hide={true} />\n                      <Area\n                        dataKey={item.name}\n                        stroke={color}\n                        fill={`url(#${gradientId})`}\n                        fillOpacity={0.4}\n                        strokeWidth={1.5}\n                        type=\"monotone\"\n                      />\n                    </AreaChart>\n                  </ChartContainer>\n                </div>\n              </CardContent>\n            </Card>\n          );\n        })}\n      </dl>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-11",
      "type": "registry:block",
      "title": "Stats Dashboard with Progress Bars",
      "description": "A stats dashboard with progress bars block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "dialog",
        "input",
        "label"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/stats/stats-11.tsx",
          "type": "registry:component",
          "target": "components/stats-11.tsx",
          "content": "\"use client\";\n\nimport type React from \"react\";\nimport { useState } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { Box, Edit } from \"lucide-react\";\n\ninterface MetricCardProps {\n  title: string;\n  value: string;\n  limit: string;\n  percentage: number;\n  status?: string;\n  statusColor?: string;\n  progressColor: string;\n  details?: Array<{ label: string; value: string; color: string }>;\n  actionLabel: string;\n  actionIcon: React.ReactNode;\n  warningMessage?: string;\n  onActionClick?: () => void;\n}\n\nfunction MetricCard({\n  title,\n  value,\n  limit,\n  percentage,\n  status,\n  statusColor = \"text-emerald-600 dark:text-emerald-400\",\n  progressColor,\n  details,\n  actionLabel,\n  actionIcon,\n  warningMessage,\n  onActionClick,\n}: MetricCardProps) {\n  const renderProgressBar = () => {\n    if (details && title === \"Commands\") {\n      const writes = Number.parseInt(details[0].value.replace(/,/g, \"\"));\n      const reads = Number.parseInt(details[1].value.replace(/,/g, \"\"));\n      const total = writes + reads;\n      const writesPercentage = (writes / total) * 100;\n      const readsPercentage = (reads / total) * 100;\n\n      return (\n        <div className=\"relative h-1 w-full overflow-hidden rounded-full bg-muted\">\n          <div\n            className=\"absolute left-0 h-full w-full origin-left bg-emerald-500 transition-transform duration-200 ease-out\"\n            style={{ transform: `scaleX(${writesPercentage / 100})` }}\n          />\n          <div\n            className=\"absolute left-0 h-full w-full origin-left bg-blue-500 transition-transform duration-200 ease-out\"\n            style={{\n              transform: `translateX(${writesPercentage}%) scaleX(${readsPercentage / 100})`,\n            }}\n          />\n        </div>\n      );\n    }\n\n    return (\n      <div className=\"relative h-1 w-full overflow-hidden rounded-full bg-muted\">\n        <div\n          className={`h-full w-full origin-left transition-transform duration-200 ease-out ${progressColor}`}\n          style={{ transform: `scaleX(${Math.min(percentage, 100) / 100})` }}\n        />\n      </div>\n    );\n  };\n\n  return (\n    <Card className=\"relative overflow-hidden max-w-[280px] shadow-2xs\">\n      <CardContent className=\"p-4 py-0\">\n        <h5 className=\"text-xs font-normal leading-none tracking-wide text-muted-foreground dark:text-foreground/80 uppercase\">\n          {title}\n        </h5>\n\n        <div className=\"mt-2 flex items-baseline gap-1\">\n          <div className=\"text-[1.2rem] font-medium leading-none text-foreground tabular-nums\">\n            {value}\n          </div>\n          <div className=\"text-xs leading-none text-muted-foreground\">/ {limit}</div>\n        </div>\n\n        <div className=\"mt-3\">\n          {renderProgressBar()}\n\n          {details && (\n            <div className=\"my-6 mb-8\">\n              <div className=\"flex flex-col gap-3\">\n                {details.map((detail, index) => (\n                  <div\n                    key={index}\n                    className=\"flex w-full items-center text-xs leading-none text-muted-foreground dark:text-foreground/70\"\n                  >\n                    <div className={`mr-[6px] h-2 w-2 rounded-full ${detail.color}`} />\n                    <div className=\"mr-1\">{detail.label}</div>\n                    <div className=\"h-[9px] flex-1 border-b-2 border-dotted border-border\" />\n                    <div className=\"ml-1 tabular-nums\">{detail.value}</div>\n                  </div>\n                ))}\n              </div>\n            </div>\n          )}\n\n          {status && (\n            <div className=\"pt-2\">\n              <div className={statusColor}>{status}</div>\n            </div>\n          )}\n\n          {warningMessage && (\n            <div className=\"pt-2\">\n              <div className=\"text-sm text-amber-700 dark:text-amber-400\">{warningMessage}</div>\n            </div>\n          )}\n        </div>\n\n        <div className=\"absolute bottom-0 left-0 right-0\">\n          <Button\n            variant=\"ghost\"\n            className=\"h-8 w-full rounded-none text-blue-500 gap-0 justify-start hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 bg-muted/50\"\n            onClick={onActionClick}\n          >\n            {actionIcon}\n            <span className=\"ml-1 text-xs\">{actionLabel}</span>\n          </Button>\n        </div>\n      </CardContent>\n    </Card>\n  );\n}\n\nfunction BudgetDialog({\n  open,\n  onOpenChange,\n}: {\n  open: boolean;\n  onOpenChange: (open: boolean) => void;\n}) {\n  const [budget, setBudget] = useState(\"150\");\n\n  const handleUpdate = () => {\n    onOpenChange(false);\n  };\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent className=\"sm:max-w-md\">\n        <DialogHeader>\n          <DialogTitle>Update budget</DialogTitle>\n          <DialogDescription>\n            When your monthly cost reaches the max budget, we send an email and throttle your\n            database. You will not be charged beyond your set budget for this database.\n          </DialogDescription>\n        </DialogHeader>\n\n        <div className=\"space-y-2\">\n          <Label htmlFor=\"budget\">Max budget per month</Label>\n          <Input\n            id=\"budget\"\n            value={budget}\n            onChange={(e) => setBudget(e.target.value)}\n            type=\"number\"\n            placeholder=\"150\"\n          />\n        </div>\n\n        <DialogFooter className=\"pt-2\">\n          <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n            Cancel\n          </Button>\n          <Button onClick={handleUpdate}>Update</Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  );\n}\n\nexport default function Stats11() {\n  const [budgetDialogOpen, setBudgetDialogOpen] = useState(false);\n\n  return (\n    <>\n      <div className=\"grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-4\">\n        <MetricCard\n          title=\"Commands\"\n          value=\"13.8M\"\n          limit=\"Unlimited\"\n          percentage={67}\n          progressColor=\"bg-blue-500\"\n          details={[\n            { label: \"Writes\", value: \"11,276,493\", color: \"bg-emerald-500\" },\n            { label: \"Reads\", value: \"2,548,921\", color: \"bg-blue-500\" },\n          ]}\n          actionLabel=\"Upgrade\"\n          actionIcon={<Box className=\"h-4 w-4\" />}\n        />\n\n        <MetricCard\n          title=\"Bandwidth\"\n          value=\"141 GB\"\n          limit=\"150 GB\"\n          percentage={94}\n          progressColor=\"bg-orange-500\"\n          warningMessage=\"There will be a charge for the excessive bandwidth over the limit.\"\n          actionLabel=\"Upgrade\"\n          actionIcon={<Box className=\"h-4 w-4\" />}\n        />\n\n        <MetricCard\n          title=\"Storage\"\n          value=\"37 GB\"\n          limit=\"500 GB\"\n          percentage={7.4}\n          progressColor=\"bg-emerald-500\"\n          status=\"It's all right.\"\n          actionLabel=\"Upgrade\"\n          actionIcon={<Box className=\"h-4 w-4\" />}\n        />\n\n        <MetricCard\n          title=\"Cost\"\n          value=\"$73.42\"\n          limit=\"$150 Budget\"\n          percentage={48.95}\n          progressColor=\"bg-emerald-500\"\n          status=\"It's all right.\"\n          actionLabel=\"Change Budget\"\n          actionIcon={<Edit className=\"h-4 w-4\" />}\n          onActionClick={() => setBudgetDialogOpen(true)}\n        />\n      </div>\n\n      <BudgetDialog open={budgetDialogOpen} onOpenChange={setBudgetDialogOpen} />\n    </>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-12",
      "type": "registry:block",
      "title": "Stats Usage Dashboard",
      "description": "A stats usage dashboard block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "card",
        "chart"
      ],
      "dependencies": [
        "recharts"
      ],
      "files": [
        {
          "path": "content/components/stats/stats-12.tsx",
          "type": "registry:component",
          "target": "components/stats-12.tsx",
          "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardHeader } from \"@/components/ui/card\";\nimport { ChartContainer, type ChartConfig } from \"@/components/ui/chart\";\nimport { Cell, Pie, PieChart } from \"recharts\";\n\ninterface UsageItem {\n  name: string;\n  current: string;\n  limit: string;\n  percentage: number;\n  href?: string;\n}\n\nconst usageData: UsageItem[] = [\n  { name: \"ISR Reads\", current: \"358K\", limit: \"1M\", percentage: 35.8 },\n  { name: \"Edge Requests\", current: \"317K\", limit: \"1M\", percentage: 31.7 },\n  {\n    name: \"Fast Origin Transfer\",\n    current: \"3.07 GB\",\n    limit: \"10 GB\",\n    percentage: 30.7,\n  },\n  {\n    name: \"Speed Insights Data Points\",\n    current: \"791\",\n    limit: \"10K\",\n    percentage: 7.9,\n  },\n  {\n    name: \"Fast Data Transfer\",\n    current: \"4.98 GB\",\n    limit: \"100 GB\",\n    percentage: 5.0,\n  },\n  {\n    name: \"Function Duration\",\n    current: \"3.1 GB-Hrs\",\n    limit: \"100 GB-Hrs\",\n    percentage: 3.1,\n  },\n  {\n    name: \"Web Analytics Events\",\n    current: \"1.3K\",\n    limit: \"50K\",\n    percentage: 2.6,\n  },\n  { name: \"ISR Writes\", current: \"4.8K\", limit: \"200K\", percentage: 2.4 },\n  {\n    name: \"Function Invocations\",\n    current: \"19K\",\n    limit: \"1M\",\n    percentage: 1.9,\n  },\n  {\n    name: \"Image Optimization - Cache Reads\",\n    current: \"4.3K\",\n    limit: \"300K\",\n    percentage: 1.4,\n  },\n];\n\nconst chartConfig = {\n  used: {\n    label: \"Used\",\n    color: \"hsl(var(--primary))\",\n  },\n  remaining: {\n    label: \"Remaining\",\n    color: \"hsl(var(--muted))\",\n  },\n} satisfies ChartConfig;\n\nfunction DonutChart({ percentage }: { percentage: number }) {\n  const backgroundData = [{ name: \"background\", value: 100, fill: \"#E5E7EB\" }];\n  const foregroundData = [\n    {\n      name: \"used\",\n      value: Math.max(0, Math.min(100, Number(percentage))),\n      fill: \"#3B82F6\",\n    },\n    {\n      name: \"empty\",\n      value: 100 - Math.max(0, Math.min(100, Number(percentage))),\n      fill: \"transparent\",\n    },\n  ];\n\n  return (\n    <ChartContainer config={chartConfig} className=\"w-6 h-6 shrink-0 aspect-square\">\n      <PieChart>\n        <Pie\n          data={backgroundData}\n          dataKey=\"value\"\n          nameKey=\"name\"\n          cx=\"50%\"\n          cy=\"50%\"\n          innerRadius={6}\n          outerRadius={10}\n          isAnimationActive={false}\n        >\n          {backgroundData.map((entry, index) => (\n            <Cell key={`bg-cell-${index}`} fill={entry.fill} />\n          ))}\n        </Pie>\n        <Pie\n          data={foregroundData}\n          dataKey=\"value\"\n          nameKey=\"name\"\n          cx=\"50%\"\n          cy=\"50%\"\n          innerRadius={6}\n          outerRadius={10}\n          startAngle={90}\n          endAngle={-270}\n        >\n          {foregroundData.map((entry, index) => (\n            <Cell key={`fg-cell-${index}`} fill={entry.fill} />\n          ))}\n        </Pie>\n      </PieChart>\n    </ChartContainer>\n  );\n}\n\nexport default function Stats12() {\n  return (\n    <Card className=\"w-full max-w-md gap-3 py-5 shadow-2xs\">\n      <CardHeader className=\"px-5\">\n        <div className=\"flex items-center justify-between\">\n          <div className=\"flex flex-col\">\n            <h3 className=\"text-balance text-sm font-medium\">Last 30 days</h3>\n            <p className=\"text-pretty text-xs text-muted-foreground font-medium\">\n              Updated just now\n            </p>\n          </div>\n          <Button size=\"sm\" className=\"h-6 text-xs font-medium\">\n            Upgrade\n          </Button>\n        </div>\n      </CardHeader>\n\n      <CardContent className=\"pt-0 px-3\">\n        <div className=\"space-y-0\">\n          {usageData.map((item, index) => (\n            <div\n              key={item.name}\n              className={`flex items-center gap-3 p-2 rounded-sm transition-colors hover:bg-muted/50 ${\n                index % 2 === 1 ? \"bg-muted/20\" : \"\"\n              }`}\n            >\n              <DonutChart percentage={item.percentage} />\n              <span className=\"text-sm flex-1 truncate leading-4\">{item.name}</span>\n              <span className=\"text-xs font-medium tabular-nums tracking-tighter text-muted-foreground\">\n                {item.current} / <span className=\"text-foreground\">{item.limit}</span>\n              </span>\n            </div>\n          ))}\n        </div>\n      </CardContent>\n    </Card>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-13",
      "type": "registry:block",
      "title": "Stats with Segmented Progress",
      "description": "A stats with segmented progress block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "card"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/stats/stats-13.tsx",
          "type": "registry:component",
          "target": "components/stats-13.tsx",
          "content": "\"use client\";\n\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\n\ninterface Props {\n  title?: string;\n  used?: number;\n  total?: number;\n  usedLabel?: string;\n  totalLabel?: string;\n  segments?: {\n    label: string;\n    value: number;\n    color: string;\n  }[];\n  className?: string;\n}\n\nconst defaultSegments: NonNullable<Props[\"segments\"]> = [\n  { label: \"Documents\", value: 2400, color: \"bg-blue-500\" },\n  { label: \"Photos\", value: 1800, color: \"bg-emerald-500\" },\n  { label: \"Videos\", value: 3200, color: \"bg-amber-500\" },\n  { label: \"Music\", value: 900, color: \"bg-purple-500\" },\n];\n\nexport default function Stats13({\n  title = \"Using Storage\",\n  used = 8300,\n  total = 15,\n  usedLabel = \"MB\",\n  totalLabel = \"GB\",\n  segments = defaultSegments,\n  className,\n}: Props) {\n  const totalValue = total * 1000;\n  const freeValue = totalValue - used;\n\n  return (\n    <Card className={cn(\"w-full max-w-4xl shadow-sm\", className)}>\n      <CardContent className=\"py-0\">\n        <p className=\"text-pretty mb-4 text-base text-muted-foreground\">\n          {title}{\" \"}\n          <span className=\"font-semibold tabular-nums text-foreground\">\n            {used.toLocaleString(undefined, {\n              minimumFractionDigits: 0,\n              maximumFractionDigits: 2,\n            })}{\" \"}\n            {usedLabel}\n          </span>{\" \"}\n          of {total} {totalLabel}\n        </p>\n\n        <div className=\"mb-4 flex h-2.5 w-full overflow-hidden rounded-full bg-muted\">\n          {segments.map((segment) => {\n            const percentage = (segment.value / totalValue) * 100;\n            return (\n              <div\n                key={segment.label}\n                className={cn(\"h-full\", segment.color)}\n                style={{ width: `${percentage}%` }}\n                role=\"progressbar\"\n                aria-label={segment.label}\n                aria-valuenow={segment.value}\n                aria-valuemin={0}\n                aria-valuemax={totalValue}\n              />\n            );\n          })}\n        </div>\n\n        <div className=\"flex flex-wrap items-center gap-x-8 gap-y-2\">\n          {segments.map((segment) => (\n            <div key={segment.label} className=\"flex items-center gap-2\">\n              <span\n                className={cn(\"size-3 shrink-0 rounded\", segment.color)}\n                aria-hidden=\"true\"\n              />\n              <span className=\"text-sm text-muted-foreground\">\n                {segment.label}\n              </span>\n              <span className=\"text-sm tabular-nums text-muted-foreground\">\n                {Math.round(segment.value)}\n                {usedLabel}\n              </span>\n            </div>\n          ))}\n          <div className=\"flex items-center gap-2\">\n            <span\n              className=\"size-3 shrink-0 rounded-sm bg-muted\"\n              aria-hidden=\"true\"\n            />\n            <span className=\"text-sm text-muted-foreground\">Free</span>\n            <span className=\"text-sm tabular-nums text-muted-foreground\">\n              {Math.round(freeValue)}\n              {usedLabel}\n            </span>\n          </div>\n        </div>\n      </CardContent>\n    </Card>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-14",
      "type": "registry:block",
      "title": "Stats with Usage Breakdown",
      "description": "A stats with usage breakdown block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "card"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/stats/stats-14.tsx",
          "type": "registry:component",
          "target": "components/stats-14.tsx",
          "content": "import { Badge } from \"@/components/ui/badge\";\nimport { Card, CardContent } from \"@/components/ui/card\";\n\ninterface UsageItem {\n  label: string;\n  amount: number;\n  percentage: number;\n  color: \"emerald\" | \"amber\" | \"rose\";\n}\n\nconst data: UsageItem[] = [\n  { label: \"Compute\", amount: 450, percentage: 52.3, color: \"emerald\" },\n  { label: \"Storage\", amount: 285, percentage: 33.1, color: \"amber\" },\n  { label: \"Bandwidth\", amount: 125, percentage: 14.6, color: \"rose\" },\n];\n\nconst colorClasses = {\n  emerald: \"bg-emerald-500 dark:bg-emerald-400\",\n  amber: \"bg-amber-500 dark:bg-amber-400\",\n  rose: \"bg-rose-500 dark:bg-rose-400\",\n};\n\nexport function Stats14() {\n  return (\n    <Card className=\"w-full max-w-sm shadow-none\">\n      <CardContent className=\"flex flex-col justify-between pt-0\">\n        <div>\n          <div className=\"flex items-center gap-2\">\n            <h3 className=\"text-balance text-sm font-bold text-foreground\">Usage</h3>\n            <Badge\n              variant=\"secondary\"\n              className=\"bg-amber-50 text-amber-700 ring-1 ring-amber-500/30 dark:bg-amber-400/10 dark:text-amber-300 dark:ring-amber-400/20\"\n            >\n              +12.5%\n            </Badge>\n          </div>\n\n          <p className=\"text-pretty mt-2 flex items-baseline gap-2\">\n            <span className=\"text-xl text-foreground\">$860</span>\n            <span className=\"text-sm text-muted-foreground\">this month</span>\n          </p>\n\n          <div className=\"mt-4\">\n            <p className=\"text-pretty text-sm font-medium text-foreground\">\n              Resource breakdown\n            </p>\n            <div className=\"mt-2 flex items-center gap-0.5\">\n              {data.map((item, index) => (\n                <div\n                  key={index}\n                  className={`${colorClasses[item.color]} h-1.5 rounded-xs`}\n                  style={{ width: `${item.percentage}%` }}\n                />\n              ))}\n            </div>\n          </div>\n\n          <ul role=\"list\" className=\"mt-5 space-y-2\">\n            {data.map((item, index) => (\n              <li key={index} className=\"flex items-center gap-2 text-xs\">\n                <span\n                  className={`${colorClasses[item.color]} size-2.5 rounded-xs`}\n                  aria-hidden=\"true\"\n                />\n                <span className=\"text-foreground\">{item.label}</span>\n                <span className=\"text-muted-foreground\">\n                  (${item.amount} / {item.percentage}%)\n                </span>\n              </li>\n            ))}\n          </ul>\n        </div>\n\n        <p className=\"text-pretty mt-6 text-xs text-muted-foreground\">\n          Configure limits in{\" \"}\n          <a\n            href=\"#\"\n            className=\"text-emerald-600 hover:underline dark:text-emerald-400\"\n          >\n            resource settings.\n          </a>\n        </p>\n      </CardContent>\n    </Card>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "stats-15",
      "type": "registry:block",
      "title": "Stats with Value Breakdown",
      "description": "A stats with value breakdown block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/stats/stats-15.tsx",
          "type": "registry:component",
          "target": "components/stats-15.tsx",
          "content": "import { cn } from \"@/lib/utils\";\n\nconst data = [\n  {\n    label: \"After 1 year\",\n    value: \"$2,400\",\n    percentage: \"+8.2%\",\n  },\n  {\n    label: \"After 5 years\",\n    value: \"$14,800\",\n    percentage: \"+24.6%\",\n  },\n  {\n    label: \"After 10 years\",\n    value: \"$38,500\",\n    percentage: \"+52.1%\",\n  },\n];\n\nexport function Stats15() {\n  return (\n    <div className=\"w-full max-w-2xs\">\n      <h3 className=\"text-balance text-sm font-medium text-foreground\">\n        Investment growth projection\n      </h3>\n      <ul role=\"list\" className=\"mt-2 divide-y divide-border text-sm\">\n        {data.map((item, index) => (\n          <li key={index} className=\"flex items-center justify-between py-3\">\n            <span className=\"text-muted-foreground\">{item.label}</span>\n            <span className=\"flex items-center gap-3 tabular-nums\">\n              <span className=\"text-right font-medium text-foreground\">\n                {item.value}\n              </span>\n              <span className=\"h-5 w-px bg-border\" aria-hidden=\"true\" />\n              <span\n                className={cn(\n                  \"rounded px-1.5 py-1 text-center text-xs font-semibold w-15\",\n                  \"bg-emerald-50 text-emerald-600 dark:bg-emerald-400/10 dark:text-emerald-400\"\n                )}\n              >\n                {item.percentage}\n              </span>\n            </span>\n          </li>\n        ))}\n      </ul>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "stats"
      ]
    },
    {
      "name": "table-01",
      "type": "registry:block",
      "title": "Table with Accordion",
      "description": "A table with accordion block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "button",
        "collapsible",
        "table"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/tables/table-01.tsx",
          "type": "registry:component",
          "target": "components/table-01.tsx",
          "content": "'use client';\n\nimport { Button } from '@/components/ui/button';\nimport {\n  Collapsible,\n  CollapsibleContent,\n} from '@/components/ui/collapsible';\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@/components/ui/table';\nimport { cn } from '@/lib/utils';\nimport { ChevronDown, ChevronRight } from 'lucide-react';\nimport { useState } from 'react';\n\ninterface TableRowData {\n  id: string;\n  name: string;\n  category: string;\n  value: number;\n  date: string;\n  children?: TableRowData[];\n}\n\nconst sampleData: TableRowData[] = [\n  {\n    id: '001',\n    name: 'Project Alpha',\n    category: 'Development',\n    value: 45_000,\n    date: '2024-01-15',\n    children: [\n      {\n        id: '001-01',\n        name: 'Frontend Module',\n        category: 'Development',\n        value: 15_000,\n        date: '2024-01-16',\n      },\n      {\n        id: '001-02',\n        name: 'Backend Module',\n        category: 'Development',\n        value: 20_000,\n        date: '2024-01-21',\n      },\n      {\n        id: '001-03',\n        name: 'Testing Suite',\n        category: 'Development',\n        value: 10_000,\n        date: '2024-01-24',\n      },\n    ],\n  },\n  {\n    id: '002',\n    name: 'Marketing Campaign',\n    category: 'Marketing',\n    value: 28_500,\n    date: '2024-01-18',\n    children: [\n      {\n        id: '002-01',\n        name: 'Social Media',\n        category: 'Marketing',\n        value: 12_000,\n        date: '2024-01-19',\n      },\n      {\n        id: '002-02',\n        name: 'Email Marketing',\n        category: 'Marketing',\n        value: 8500,\n        date: '2024-01-22',\n      },\n      {\n        id: '002-03',\n        name: 'SEO Optimization',\n        category: 'Marketing',\n        value: 8000,\n        date: '2024-01-23',\n      },\n    ],\n  },\n  {\n    id: '003',\n    name: 'Infrastructure Upgrade',\n    category: 'Operations',\n    value: 67_200,\n    date: '2024-01-20',\n    children: [\n      {\n        id: '003-01',\n        name: 'Cloud Migration',\n        category: 'Operations',\n        value: 35_000,\n        date: '2024-01-21',\n      },\n      {\n        id: '003-02',\n        name: 'Security Enhancement',\n        category: 'Operations',\n        value: 32_200,\n        date: '2024-01-24',\n      },\n    ],\n  },\n  {\n    id: '004',\n    name: 'Customer Support',\n    category: 'Service',\n    value: 19_800,\n    date: '2024-01-25',\n  },\n];\n\ninterface AccordionRowProps {\n  row: TableRowData;\n  defaultOpen?: boolean;\n}\n\nfunction AccordionRow({ row, defaultOpen = false }: AccordionRowProps) {\n  const [isOpen, setIsOpen] = useState(defaultOpen);\n  const hasChildren = row.children && row.children.length > 0;\n\n  return (\n    <Collapsible asChild open={isOpen} onOpenChange={setIsOpen}>\n      <TableBody className=\"[&_tr:last-child]:border-b last:[&_tr:last-child]:border-0\">\n        <TableRow\n          className={cn(\n            'grid grid-cols-[40px_80px_180px_110px_100px_110px] bg-muted/50 hover:bg-muted/50',\n            isOpen && 'border-b-0'\n          )}\n        >\n          <TableCell className=\"p-0\">\n            <Button\n              aria-label={isOpen ? 'Collapse row' : 'Expand row'}\n              className={cn(\n                'h-full w-full rounded-none p-3 text-muted-foreground transition-colors',\n                hasChildren && 'hover:bg-transparent hover:text-foreground',\n                !hasChildren && 'cursor-default opacity-30'\n              )}\n              disabled={!hasChildren}\n              onClick={() => setIsOpen(!isOpen)}\n              size=\"icon\"\n              variant=\"ghost\"\n            >\n              {hasChildren ? (\n                isOpen ? (\n                  <ChevronDown className=\"h-4 w-4 transition-transform duration-200\" />\n                ) : (\n                  <ChevronRight className=\"h-4 w-4 transition-transform duration-200\" />\n                )\n              ) : (\n                <div className=\"h-4 w-4\" />\n              )}\n            </Button>\n          </TableCell>\n          <TableCell className=\"p-3 font-medium font-mono text-muted-foreground text-sm\">\n            {row.id}\n          </TableCell>\n          <TableCell className=\"p-3 font-medium text-sm\">{row.name}</TableCell>\n          <TableCell className=\"p-3 text-muted-foreground text-sm\">\n            {row.category}\n          </TableCell>\n          <TableCell className=\"tabular-nums p-3 text-right font-mono font-semibold text-sm\">\n            ${row.value.toLocaleString()}\n          </TableCell>\n          <TableCell className=\"p-3 text-muted-foreground text-sm\">\n            {row.date}\n          </TableCell>\n        </TableRow>\n\n        {hasChildren && (\n          <TableRow className=\"grid grid-cols-[40px_80px_180px_110px_100px_110px] border-b-0 hover:bg-transparent\">\n            <TableCell className=\"col-span-6 p-0\" colSpan={6}>\n              <CollapsibleContent>\n                <div className=\"w-full border-border border-b bg-muted/20\">\n                  <Table>\n                    <TableHeader>\n                      <TableRow className=\"grid grid-cols-[40px_80px_180px_110px_100px_110px] border-b-0 bg-muted/30\">\n                        <TableHead className=\"flex h-7 items-center border-border border-y px-3 py-1.5\" />\n                        <TableHead className=\"flex h-7 items-center border-border border-y px-3 py-1.5 text-xs\">\n                          ID\n                        </TableHead>\n                        <TableHead className=\"flex h-7 items-center border-border border-y px-3 py-1.5 text-xs\">\n                          Name\n                        </TableHead>\n                        <TableHead className=\"flex h-7 items-center border-border border-y px-3 py-1.5 text-xs\">\n                          Category\n                        </TableHead>\n                        <TableHead className=\"flex h-7 items-center justify-end border-border border-y px-3 py-1.5 text-right text-xs\">\n                          Value\n                        </TableHead>\n                        <TableHead className=\"flex h-7 items-center border-border border-y px-3 py-1.5 text-xs\">\n                          Date\n                        </TableHead>\n                      </TableRow>\n                    </TableHeader>\n                    <TableBody>\n                      {row.children?.map((childRow) => (\n                        <TableRow\n                          className=\"grid grid-cols-[40px_80px_180px_110px_100px_110px]\"\n                          key={childRow.id}\n                        >\n                          <TableCell className=\"px-3 py-2\" />\n                          <TableCell className=\"tabular-nums px-3 py-2 font-mono text-muted-foreground text-xs\">\n                            {childRow.id}\n                          </TableCell>\n                          <TableCell className=\"px-3 py-2 font-medium text-xs\">\n                            {childRow.name}\n                          </TableCell>\n                          <TableCell className=\"px-3 py-2 text-muted-foreground text-xs\">\n                            {childRow.category}\n                          </TableCell>\n                          <TableCell className=\"tabular-nums px-3 py-2 text-right font-mono font-semibold text-xs\">\n                            ${childRow.value.toLocaleString()}\n                          </TableCell>\n                          <TableCell className=\"px-3 py-2 text-muted-foreground text-xs\">\n                            {childRow.date}\n                          </TableCell>\n                        </TableRow>\n                      ))}\n                    </TableBody>\n                  </Table>\n                </div>\n              </CollapsibleContent>\n            </TableCell>\n          </TableRow>\n        )}\n      </TableBody>\n    </Collapsible>\n  );\n}\n\nexport default function Table01() {\n  return (\n    <div className=\"max-w-fit overflow-hidden rounded-lg border border-border bg-card shadow-sm\">\n      <div className=\"overflow-x-auto\">\n        <Table>\n          <TableHeader>\n            <TableRow className=\"grid grid-cols-[40px_80px_180px_110px_100px_110px] bg-muted/50\">\n              <TableHead className=\"p-3\" />\n              <TableHead className=\"p-3 font-semibold text-foreground text-sm\">\n                ID\n              </TableHead>\n              <TableHead className=\"p-3 font-semibold text-foreground text-sm\">\n                Name\n              </TableHead>\n              <TableHead className=\"p-3 font-semibold text-foreground text-sm\">\n                Category\n              </TableHead>\n              <TableHead className=\"p-3 text-right font-semibold text-foreground text-sm\">\n                Value\n              </TableHead>\n              <TableHead className=\"p-3 font-semibold text-foreground text-sm\">\n                Date\n              </TableHead>\n            </TableRow>\n          </TableHeader>\n          {sampleData.map((row, index) => (\n            <AccordionRow defaultOpen={index === 0} key={row.id} row={row} />\n          ))}\n        </Table>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "tables"
      ]
    },
    {
      "name": "table-02",
      "type": "registry:block",
      "title": "Table with Actions",
      "description": "A table with actions block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "button",
        "table",
        "tooltip"
      ],
      "dependencies": [
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/tables/table-02.tsx",
          "type": "registry:component",
          "target": "components/table-02.tsx",
          "content": "\"use client\";\n\nimport {\n  CheckCircle,\n  FileTextIcon,\n  Loader2,\n  PauseIcon,\n  PlayIcon,\n  Trash2Icon,\n} from \"lucide-react\";\nimport { useState } from \"react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from \"@/components/ui/table\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\n\ninterface Task {\n  id: string;\n  title: string;\n  assignee: string;\n  status: \"pending\" | \"in-progress\" | \"completed\" | \"blocked\";\n  priority: \"low\" | \"medium\" | \"high\" | \"urgent\";\n  dueDate: string;\n  notes: string;\n}\n\ntype TaskActionType = \"start\" | \"pause\" | \"complete\" | \"delete\" | \"view\";\n\nconst tasks: Task[] = [\n  {\n    id: \"TASK-001\",\n    title: \"Implement User Authentication\",\n    assignee: \"Sarah Chen\",\n    status: \"in-progress\",\n    priority: \"high\",\n    dueDate: \"2024-03-25\",\n    notes: \"OAuth 2.0 integration with Google and GitHub providers\",\n  },\n  {\n    id: \"TASK-002\",\n    title: \"Design Dashboard UI\",\n    assignee: \"Michael Torres\",\n    status: \"completed\",\n    priority: \"medium\",\n    dueDate: \"2024-03-20\",\n    notes: \"Finalize dashboard layout with responsive grid system\",\n  },\n  {\n    id: \"TASK-003\",\n    title: \"API Performance Optimization\",\n    assignee: \"Emma Rodriguez\",\n    status: \"pending\",\n    priority: \"urgent\",\n    dueDate: \"2024-03-22\",\n    notes: \"Reduce API response time by implementing caching strategy\",\n  },\n  {\n    id: \"TASK-004\",\n    title: \"Write Unit Tests\",\n    assignee: \"James Wilson\",\n    status: \"in-progress\",\n    priority: \"medium\",\n    dueDate: \"2024-03-28\",\n    notes: \"Achieve 80% code coverage for authentication module\",\n  },\n  {\n    id: \"TASK-005\",\n    title: \"Database Migration\",\n    assignee: \"Olivia Martinez\",\n    status: \"blocked\",\n    priority: \"high\",\n    dueDate: \"2024-03-24\",\n    notes: \"Waiting for infrastructure team approval before proceeding\",\n  },\n  {\n    id: \"TASK-006\",\n    title: \"Update Documentation\",\n    assignee: \"Lucas Anderson\",\n    status: \"pending\",\n    priority: \"low\",\n    dueDate: \"2024-03-30\",\n    notes: \"Document new API endpoints and authentication flow\",\n  },\n  {\n    id: \"TASK-007\",\n    title: \"Security Audit\",\n    assignee: \"Sophia Taylor\",\n    status: \"completed\",\n    priority: \"urgent\",\n    dueDate: \"2024-03-19\",\n    notes:\n      \"Conducted comprehensive security review and vulnerability assessment\",\n  },\n];\n\nfunction getStatusBadge(status: Task[\"status\"]) {\n  switch (status) {\n    case \"pending\":\n      return (\n        <Badge\n          variant=\"outline\"\n          className=\"bg-amber-500/15 text-amber-700 hover:bg-amber-500/25 dark:bg-amber-500/10 dark:text-amber-300 dark:hover:bg-amber-500/20 border-0\"\n        >\n          Pending\n        </Badge>\n      );\n    case \"in-progress\":\n      return (\n        <Badge\n          variant=\"outline\"\n          className=\"bg-blue-500/15 text-blue-700 hover:bg-blue-500/25 dark:bg-blue-500/10 dark:text-blue-400 dark:hover:bg-blue-500/20 border-0\"\n        >\n          In Progress\n        </Badge>\n      );\n    case \"completed\":\n      return (\n        <Badge\n          variant=\"outline\"\n          className=\"bg-green-500/15 text-green-700 hover:bg-green-500/25 dark:bg-green-500/10 dark:text-green-400 dark:hover:bg-green-500/20 border-0\"\n        >\n          Completed\n        </Badge>\n      );\n    case \"blocked\":\n      return (\n        <Badge\n          variant=\"outline\"\n          className=\"bg-rose-500/15 text-rose-700 hover:bg-rose-500/25 dark:bg-rose-500/10 dark:text-rose-400 dark:hover:bg-rose-500/20 border-0\"\n        >\n          Blocked\n        </Badge>\n      );\n    default:\n      return <Badge variant=\"secondary\">{status}</Badge>;\n  }\n}\n\nexport default function Table02() {\n  const [pendingAction, setPendingAction] = useState<{\n    id: string;\n    type: TaskActionType;\n  } | null>(null);\n\n  const isTaskActionPending = (action: TaskActionType, taskId: string) =>\n    pendingAction?.id === taskId && pendingAction.type === action;\n\n  const isTaskBusy = (taskId: string) => pendingAction?.id === taskId;\n\n  const handleAction = (task: Task, actionType: TaskActionType) => {\n    setPendingAction({ id: task.id, type: actionType });\n    setTimeout(() => {\n      setPendingAction(null);\n      console.log(`Action \"${actionType}\" completed for task:`, task.title);\n    }, 1000);\n  };\n\n  const renderTaskRow = (task: Task) => {\n    const busy = isTaskBusy(task.id);\n    const startPending = isTaskActionPending(\"start\", task.id);\n    const pausePending = isTaskActionPending(\"pause\", task.id);\n    const completePending = isTaskActionPending(\"complete\", task.id);\n    const deletePending = isTaskActionPending(\"delete\", task.id);\n\n    return (\n      <TableRow key={task.id} className=\"hover:bg-muted/50\">\n        <TableCell className=\"h-16 px-4 font-medium\">{task.title}</TableCell>\n        <TableCell className=\"h-16 px-4 text-sm text-muted-foreground\">\n          {task.assignee}\n        </TableCell>\n        <TableCell className=\"h-16 px-4\">\n          {getStatusBadge(task.status)}\n        </TableCell>\n\n        <TableCell className=\"h-16 px-4 text-sm text-muted-foreground\">\n          {task.dueDate}\n        </TableCell>\n        <TableCell className=\"h-16 px-4 max-w-[300px] text-sm text-muted-foreground\">\n          <TooltipProvider>\n            <Tooltip>\n              <TooltipTrigger asChild>\n                <span className=\"block cursor-help truncate\">{task.notes}</span>\n              </TooltipTrigger>\n              <TooltipContent className=\"max-w-md\">{task.notes}</TooltipContent>\n            </Tooltip>\n          </TooltipProvider>\n        </TableCell>\n        <TableCell className=\"h-16 px-4\">\n          <TooltipProvider>\n            <div className=\"flex items-center gap-1\">\n              {(task.status === \"pending\" || task.status === \"blocked\") && (\n                <Tooltip>\n                  <TooltipTrigger asChild>\n                    <Button\n                      variant=\"outline\"\n                      size=\"icon\"\n                      className=\"h-8 w-8\"\n                      onClick={() => handleAction(task, \"start\")}\n                      disabled={busy}\n                      aria-label=\"Start\"\n                    >\n                      {startPending ? (\n                        <Loader2 className=\"size-4 animate-spin\" />\n                      ) : (\n                        <PlayIcon className=\"size-4\" />\n                      )}\n                    </Button>\n                  </TooltipTrigger>\n                  <TooltipContent>Start</TooltipContent>\n                </Tooltip>\n              )}\n              {task.status === \"in-progress\" && (\n                <>\n                  <Tooltip>\n                    <TooltipTrigger asChild>\n                      <Button\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"h-8 w-8\"\n                        onClick={() => handleAction(task, \"pause\")}\n                        disabled={busy}\n                        aria-label=\"Pause\"\n                      >\n                        {pausePending ? (\n                          <Loader2 className=\"size-4 animate-spin\" />\n                        ) : (\n                          <PauseIcon className=\"size-4\" />\n                        )}\n                      </Button>\n                    </TooltipTrigger>\n                    <TooltipContent>Pause</TooltipContent>\n                  </Tooltip>\n                  <Tooltip>\n                    <TooltipTrigger asChild>\n                      <Button\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"h-8 w-8\"\n                        onClick={() => handleAction(task, \"complete\")}\n                        disabled={busy}\n                        aria-label=\"Complete\"\n                      >\n                        {completePending ? (\n                          <Loader2 className=\"size-4 animate-spin\" />\n                        ) : (\n                          <CheckCircle className=\"size-4\" />\n                        )}\n                      </Button>\n                    </TooltipTrigger>\n                    <TooltipContent>Complete</TooltipContent>\n                  </Tooltip>\n                </>\n              )}\n              <Tooltip>\n                <TooltipTrigger asChild>\n                  <Button\n                    variant=\"outline\"\n                    size=\"icon\"\n                    className=\"h-8 w-8 text-destructive hover:bg-destructive hover:text-white\"\n                    onClick={() => handleAction(task, \"delete\")}\n                    disabled={busy}\n                    aria-label=\"Delete\"\n                  >\n                    {deletePending ? (\n                      <Loader2 className=\"size-4 animate-spin\" />\n                    ) : (\n                      <Trash2Icon className=\"size-4\" />\n                    )}\n                  </Button>\n                </TooltipTrigger>\n                <TooltipContent>Delete</TooltipContent>\n              </Tooltip>\n              <Tooltip>\n                <TooltipTrigger asChild>\n                  <Button\n                    variant=\"outline\"\n                    size=\"icon\"\n                    className=\"h-8 w-8\"\n                    onClick={() => handleAction(task, \"view\")}\n                    disabled={busy}\n                    aria-label=\"View details\"\n                  >\n                    <FileTextIcon className=\"size-4\" />\n                  </Button>\n                </TooltipTrigger>\n                <TooltipContent>View Details</TooltipContent>\n              </Tooltip>\n            </div>\n          </TooltipProvider>\n        </TableCell>\n      </TableRow>\n    );\n  };\n\n  return (\n    <div className=\"rounded-lg border bg-card w-[95%]\">\n      <Table>\n        <TableHeader>\n          <TableRow className=\"hover:bg-transparent border-b\">\n            <TableHead className=\"h-12 px-4 font-medium\">Title</TableHead>\n            <TableHead className=\"h-12 px-4 font-medium\">Assignee</TableHead>\n            <TableHead className=\"h-12 px-4 font-medium w-[120px]\">\n              Status\n            </TableHead>\n\n            <TableHead className=\"h-12 px-4 font-medium\">Due Date</TableHead>\n            <TableHead className=\"h-12 px-4 font-medium\">Notes</TableHead>\n            <TableHead className=\"h-12 px-4 font-medium w-[180px]\">\n              Actions\n            </TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>{tasks.map(renderTaskRow)}</TableBody>\n      </Table>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "tables"
      ]
    },
    {
      "name": "table-03",
      "type": "registry:block",
      "title": "Table with Filters",
      "description": "A table with filters block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "select",
        "table"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/tables/table-03.tsx",
          "type": "registry:component",
          "target": "components/table-03.tsx",
          "content": "'use client';\n\nimport { useState } from 'react';\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from '@/components/ui/select';\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@/components/ui/table';\nimport { Badge } from '@/components/ui/badge';\nimport { cn } from '@/lib/utils';\n\ntype Status = 'active' | 'pending' | 'discontinued' | 'on-hold';\n\ninterface Product {\n  sku: string;\n  productName: string;\n  stockLevel: number;\n  category: string;\n  status: Status;\n  unitPrice: string;\n  lastRestocked: string;\n}\n\nconst data: Product[] = [\n  {\n    sku: 'SKU-8472',\n    productName: 'Wireless Mouse Pro',\n    stockLevel: 245,\n    category: 'Electronics',\n    status: 'active',\n    unitPrice: '$24.99',\n    lastRestocked: 'Oct 15, 2024',\n  },\n  {\n    sku: 'SKU-3391',\n    productName: 'Ergonomic Keyboard',\n    stockLevel: 89,\n    category: 'Electronics',\n    status: 'active',\n    unitPrice: '$79.99',\n    lastRestocked: 'Oct 18, 2024',\n  },\n  {\n    sku: 'SKU-7156',\n    productName: 'Office Chair Deluxe',\n    stockLevel: 12,\n    category: 'Furniture',\n    status: 'pending',\n    unitPrice: '$299.99',\n    lastRestocked: 'Oct 12, 2024',\n  },\n  {\n    sku: 'SKU-9204',\n    productName: 'USB-C Hub Adapter',\n    stockLevel: 456,\n    category: 'Accessories',\n    status: 'active',\n    unitPrice: '$34.50',\n    lastRestocked: 'Oct 19, 2024',\n  },\n  {\n    sku: 'SKU-1638',\n    productName: 'Standing Desk Frame',\n    stockLevel: 5,\n    category: 'Furniture',\n    status: 'on-hold',\n    unitPrice: '$449.00',\n    lastRestocked: 'Oct 10, 2024',\n  },\n  {\n    sku: 'SKU-5529',\n    productName: 'Laptop Stand Aluminum',\n    stockLevel: 178,\n    category: 'Accessories',\n    status: 'active',\n    unitPrice: '$45.99',\n    lastRestocked: 'Oct 17, 2024',\n  },\n  {\n    sku: 'SKU-4817',\n    productName: 'Mechanical Keyboard RGB',\n    stockLevel: 0,\n    category: 'Electronics',\n    status: 'discontinued',\n    unitPrice: '$129.99',\n    lastRestocked: 'Oct 05, 2024',\n  },\n];\n\nfunction getStatusBadge(status: Status) {\n  switch (status) {\n    case 'active':\n      return (\n        <Badge\n          variant=\"outline\"\n          className=\"border-0 bg-green-500/15 text-green-700 hover:bg-green-500/25 dark:bg-green-500/10 dark:text-green-400 dark:hover:bg-green-500/20\"\n        >\n          Active\n        </Badge>\n      );\n    case 'pending':\n      return (\n        <Badge\n          variant=\"outline\"\n          className=\"border-0 bg-amber-500/15 text-amber-700 hover:bg-amber-500/25 dark:bg-amber-500/10 dark:text-amber-300 dark:hover:bg-amber-500/20\"\n        >\n          Pending\n        </Badge>\n      );\n    case 'discontinued':\n      return (\n        <Badge\n          variant=\"outline\"\n          className=\"border-0 bg-rose-500/15 text-rose-700 hover:bg-rose-500/25 dark:bg-rose-500/10 dark:text-rose-400 dark:hover:bg-rose-500/20\"\n        >\n          Discontinued\n        </Badge>\n      );\n    case 'on-hold':\n      return (\n        <Badge\n          variant=\"outline\"\n          className=\"border-0 bg-blue-500/15 text-blue-700 hover:bg-blue-500/25 dark:bg-blue-500/10 dark:text-blue-400 dark:hover:bg-blue-500/20\"\n        >\n          On Hold\n        </Badge>\n      );\n    default:\n      return null;\n  }\n}\n\nexport default function Table03() {\n  const [selectedCategory, setSelectedCategory] = useState<string>('all');\n\n  const filteredData = data.filter((item) => {\n    const categoryMatch =\n      selectedCategory === 'all' || item.category === selectedCategory;\n    return categoryMatch;\n  });\n\n  const uniqueCategories = Array.from(\n    new Set(data.map((item) => item.category))\n  );\n\n  return (\n    <div className=\"space-y-6\">\n      <div className=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\">\n        <div>\n          <h3 className=\"text-balance text-lg font-semibold text-foreground\">\n            Product Inventory\n          </h3>\n          <p className=\"text-pretty mt-1 text-sm text-muted-foreground\">\n            Track and manage product stock levels across all warehouse\n            locations.\n          </p>\n        </div>\n        <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n          <Select value={selectedCategory} onValueChange={setSelectedCategory}>\n            <SelectTrigger className=\"w-full sm:w-[180px]\">\n              <SelectValue placeholder=\"Filter by category\" />\n            </SelectTrigger>\n            <SelectContent>\n              <SelectItem value=\"all\">All Categories</SelectItem>\n              {uniqueCategories.map((category) => (\n                <SelectItem key={category} value={category}>\n                  {category}\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n        </div>\n      </div>\n\n      <div className=\"rounded-lg border bg-card\">\n        <Table>\n          <TableHeader>\n            <TableRow className=\"border-b hover:bg-transparent\">\n              <TableHead className=\"h-12 px-4 font-medium\">SKU</TableHead>\n              <TableHead className=\"h-12 px-4 font-medium\">\n                Product Name\n              </TableHead>\n              <TableHead className=\"h-12 px-4 font-medium\">Category</TableHead>\n              <TableHead className=\"h-12 px-4 font-medium\">Status</TableHead>\n              <TableHead className=\"h-12 px-4 text-right font-medium\">\n                Unit Price\n              </TableHead>\n              <TableHead className=\"h-12 px-4 text-right font-medium\">\n                Last Restocked\n              </TableHead>\n            </TableRow>\n          </TableHeader>\n          <TableBody>\n            {filteredData.length > 0 ? (\n              filteredData.map((item) => (\n                <TableRow key={item.sku} className=\"hover:bg-muted/50\">\n                  <TableCell className=\"tabular-nums h-14 px-4 font-mono text-sm font-medium\">\n                    {item.sku}\n                  </TableCell>\n                  <TableCell className=\"h-14 px-4 font-medium\">\n                    {item.productName}\n                  </TableCell>\n                  <TableCell className=\"h-14 px-4 text-sm text-muted-foreground\">\n                    {item.category}\n                  </TableCell>\n                  <TableCell className=\"h-14 px-4\">\n                    {getStatusBadge(item.status)}\n                  </TableCell>\n                  <TableCell className=\"tabular-nums h-14 px-4 text-right font-mono text-sm font-semibold\">\n                    {item.unitPrice}\n                  </TableCell>\n                  <TableCell className=\"h-14 px-4 text-right text-sm text-muted-foreground\">\n                    {item.lastRestocked}\n                  </TableCell>\n                </TableRow>\n              ))\n            ) : (\n              <TableRow>\n                <TableCell\n                  colSpan={6}\n                  className=\"h-24 text-center text-muted-foreground\"\n                >\n                  No products found matching the selected filters.\n                </TableCell>\n              </TableRow>\n            )}\n          </TableBody>\n        </Table>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "tables"
      ]
    },
    {
      "name": "table-04",
      "type": "registry:block",
      "title": "Table with Grouped Rows",
      "description": "A table with grouped rows block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "avatar",
        "badge",
        "table"
      ],
      "dependencies": [],
      "files": [
        {
          "path": "content/components/tables/table-04.tsx",
          "type": "registry:component",
          "target": "components/table-04.tsx",
          "content": "'use client';\n\nimport { Fragment } from 'react';\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@/components/ui/table';\nimport { Badge } from '@/components/ui/badge';\nimport { Avatar, AvatarFallback } from '@/components/ui/avatar';\nimport { cn } from '@/lib/utils';\n\ninterface AssignedPerson {\n  name: string;\n  initials: string;\n}\n\ninterface TaskItem {\n  id: string;\n  task: string;\n  budget: string;\n  deadline: string;\n  assigned: AssignedPerson[];\n  status: string;\n}\n\ninterface TaskGroup {\n  name: string;\n  items: TaskItem[];\n}\n\ntype StatusVariant = 'success' | 'warning' | 'default' | 'secondary';\n\nconst avatarColors = [\n  'bg-blue-500',\n  'bg-purple-500',\n  'bg-emerald-500',\n  'bg-cyan-500',\n  'bg-rose-500',\n  'bg-indigo-500',\n];\n\nfunction getAvatarColor(initials: string) {\n  const seed = initials\n    .split('')\n    .reduce((acc, char) => acc + char.charCodeAt(0), 0);\n  return avatarColors[seed % avatarColors.length];\n}\n\nfunction AvatarStack({ people }: { people: AssignedPerson[] }) {\n  return (\n    <div className=\"flex -space-x-2\">\n      {people.map((person, index) => (\n        <Avatar\n          key={index}\n          className={cn(\n            'h-6 w-6 border-2 border-background text-[10px]',\n            getAvatarColor(person.initials)\n          )}\n        >\n          <AvatarFallback\n            className={cn('font-medium text-white', getAvatarColor(person.initials))}\n          >\n            {person.initials}\n          </AvatarFallback>\n        </Avatar>\n      ))}\n    </div>\n  );\n}\n\nconst statusStyles: Record<StatusVariant, { badge: string; dot: string }> = {\n  success: {\n    badge:\n      'bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300',\n    dot: 'bg-emerald-500',\n  },\n  warning: {\n    badge: 'bg-amber-50 text-amber-700 dark:bg-amber-950 dark:text-amber-300',\n    dot: 'bg-amber-500',\n  },\n  default: {\n    badge: 'bg-blue-50 text-blue-700 dark:bg-blue-950 dark:text-blue-300',\n    dot: 'bg-blue-500',\n  },\n  secondary: {\n    badge: 'bg-muted text-muted-foreground',\n    dot: 'bg-muted-foreground',\n  },\n};\n\nfunction StatusBadge({\n  status,\n  variant = 'default',\n}: {\n  status: string;\n  variant?: StatusVariant;\n}) {\n  const styles = statusStyles[variant];\n  return (\n    <Badge variant=\"outline\" className={cn('gap-1.5 rounded-full', styles.badge)}>\n      <span className={cn('size-1.5 rounded-full', styles.dot)} aria-hidden=\"true\" />\n      {status}\n    </Badge>\n  );\n}\n\nconst data: TaskGroup[] = [\n  {\n    name: 'Engineering',\n    items: [\n      {\n        id: '1',\n        task: 'API Integration Overhaul',\n        budget: '$32,000',\n        deadline: 'Dec 15, 2024',\n        assigned: [\n          { name: 'Marcus Chen', initials: 'MC' },\n          { name: 'Priya Sharma', initials: 'PS' },\n        ],\n        status: 'In Progress',\n      },\n      {\n        id: '2',\n        task: 'Database Migration',\n        budget: '$18,500',\n        deadline: 'Jan 20, 2025',\n        assigned: [{ name: 'David Kim', initials: 'DK' }],\n        status: 'Completed',\n      },\n      {\n        id: '3',\n        task: 'Mobile App Redesign',\n        budget: '$55,000',\n        deadline: 'Feb 28, 2025',\n        assigned: [\n          { name: 'Lena Rodriguez', initials: 'LR' },\n          { name: 'Tom Anderson', initials: 'TA' },\n          { name: 'Nina Patel', initials: 'NP' },\n        ],\n        status: 'Planning',\n      },\n    ],\n  },\n  {\n    name: 'Marketing',\n    items: [\n      {\n        id: '4',\n        task: 'Q1 Campaign Launch',\n        budget: '$24,000',\n        deadline: 'Jan 5, 2025',\n        assigned: [\n          { name: 'Rachel Green', initials: 'RG' },\n          { name: 'Chris Evans', initials: 'CE' },\n        ],\n        status: 'In Progress',\n      },\n      {\n        id: '5',\n        task: 'Brand Refresh Project',\n        budget: '$42,000',\n        deadline: 'Mar 1, 2025',\n        assigned: [{ name: 'Monica Geller', initials: 'MG' }],\n        status: 'Planning',\n      },\n    ],\n  },\n  {\n    name: 'Operations',\n    items: [\n      {\n        id: '6',\n        task: 'Vendor Contract Review',\n        budget: '$8,000',\n        deadline: 'Dec 30, 2024',\n        assigned: [\n          { name: 'Joe Tribbiani', initials: 'JT' },\n          { name: 'Phoebe Buffay', initials: 'PB' },\n        ],\n        status: 'Completed',\n      },\n      {\n        id: '7',\n        task: 'Office Expansion Setup',\n        budget: '$120,000',\n        deadline: 'Apr 15, 2025',\n        assigned: [{ name: 'Ross Geller', initials: 'RG' }],\n        status: 'On Hold',\n      },\n    ],\n  },\n];\n\nfunction getStatusVariant(status: string): StatusVariant {\n  switch (status) {\n    case 'Completed':\n      return 'success';\n    case 'In Progress':\n      return 'default';\n    case 'Planning':\n      return 'secondary';\n    case 'On Hold':\n      return 'warning';\n    default:\n      return 'default';\n  }\n}\n\nexport default function Table04() {\n  return (\n    <div className=\"rounded-lg border\">\n      <Table>\n        <TableHeader>\n          <TableRow>\n            <TableHead className=\"w-48 font-medium\">Task</TableHead>\n            <TableHead className=\"font-medium\">Budget</TableHead>\n            <TableHead className=\"font-medium\">Deadline</TableHead>\n            <TableHead className=\"font-medium\">Assigned</TableHead>\n            <TableHead className=\"w-28 font-medium\">Status</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          {data.map((group) => (\n            <Fragment key={group.name}>\n              <TableRow\n                className=\"bg-muted/50 hover:bg-muted/50\"\n              >\n                <TableCell colSpan={5} className=\"py-2 font-semibold\">\n                  {group.name}\n                  <span className=\"ml-2 font-normal text-muted-foreground\">\n                    {group.items.length}\n                  </span>\n                </TableCell>\n              </TableRow>\n              {group.items.map((item) => (\n                <TableRow key={item.id}>\n                  <TableCell className=\"font-medium\">{item.task}</TableCell>\n                  <TableCell>{item.budget}</TableCell>\n                  <TableCell>{item.deadline}</TableCell>\n                  <TableCell>\n                    <AvatarStack people={item.assigned} />\n                  </TableCell>\n                  <TableCell>\n                    <StatusBadge\n                      status={item.status}\n                      variant={getStatusVariant(item.status)}\n                    />\n                  </TableCell>\n                </TableRow>\n              ))}\n            </Fragment>\n          ))}\n        </TableBody>\n      </Table>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "tables"
      ]
    },
    {
      "name": "table-05",
      "type": "registry:block",
      "title": "Data Table",
      "description": "A data table block.",
      "author": "ephraim duncan <https://ephraimduncan.com>",
      "registryDependencies": [
        "badge",
        "button",
        "checkbox",
        "dropdown-menu",
        "input",
        "select",
        "table"
      ],
      "dependencies": [
        "@tanstack/react-table",
        "lucide-react"
      ],
      "files": [
        {
          "path": "content/components/tables/table-05.tsx",
          "type": "registry:component",
          "target": "components/table-05.tsx",
          "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport {\n  type ColumnDef,\n  type SortingState,\n  flexRender,\n  getCoreRowModel,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  useReactTable,\n} from \"@tanstack/react-table\";\nimport {\n  ChevronLeft,\n  ChevronRight,\n  Eye,\n  Pencil,\n  Trash2,\n  MoreHorizontal,\n} from \"lucide-react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\";\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from \"@/components/ui/table\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { cn } from \"@/lib/utils\";\n\ntype Status = \"completed\" | \"pending\" | \"processing\" | \"cancelled\";\n\ninterface Item {\n  id: string;\n  name: string;\n  date: string;\n  status: Status;\n  amount: string;\n}\n\nconst statusConfig: Record<Status, { label: string; className: string }> = {\n  completed: {\n    label: \"Completed\",\n    className:\n      \"bg-emerald-500/15 text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-400\",\n  },\n  pending: {\n    label: \"Pending\",\n    className:\n      \"bg-amber-500/15 text-amber-700 dark:bg-amber-500/10 dark:text-amber-400\",\n  },\n  processing: {\n    label: \"Processing\",\n    className:\n      \"bg-blue-500/15 text-blue-700 dark:bg-blue-500/10 dark:text-blue-400\",\n  },\n  cancelled: {\n    label: \"Cancelled\",\n    className:\n      \"bg-rose-500/15 text-rose-700 dark:bg-rose-500/10 dark:text-rose-400\",\n  },\n};\n\nfunction StatusBadge({ status }: { status: Status }) {\n  const config = statusConfig[status];\n  return (\n    <Badge variant=\"outline\" className={cn(\"border-0\", config.className)}>\n      {config.label}\n    </Badge>\n  );\n}\n\nconst columns: ColumnDef<Item>[] = [\n  {\n    id: \"select\",\n    header: ({ table }) => (\n      <Checkbox\n        checked={\n          table.getIsAllPageRowsSelected() ||\n          (table.getIsSomePageRowsSelected() && \"indeterminate\")\n        }\n        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}\n        aria-label=\"Select all\"\n      />\n    ),\n    cell: ({ row }) => (\n      <Checkbox\n        checked={row.getIsSelected()}\n        onCheckedChange={(value) => row.toggleSelected(!!value)}\n        aria-label=\"Select row\"\n      />\n    ),\n    enableSorting: false,\n    enableHiding: false,\n  },\n  {\n    accessorKey: \"name\",\n    header: \"Name\",\n    cell: ({ row }) => (\n      <span className=\"font-medium\">{row.getValue(\"name\")}</span>\n    ),\n  },\n  {\n    accessorKey: \"date\",\n    header: \"Date\",\n  },\n  {\n    accessorKey: \"status\",\n    header: \"Status\",\n    cell: ({ row }) => <StatusBadge status={row.getValue(\"status\")} />,\n  },\n  {\n    accessorKey: \"amount\",\n    header: () => <div className=\"text-right\">Amount</div>,\n    cell: ({ row }) => (\n      <div className=\"text-right font-medium\">{row.getValue(\"amount\")}</div>\n    ),\n  },\n  {\n    id: \"actions\",\n    cell: () => (\n      <div className=\"text-right\">\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\">\n              <MoreHorizontal className=\"h-4 w-4\" />\n              <span className=\"sr-only\">Open menu</span>\n            </Button>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent align=\"end\">\n            <DropdownMenuItem>\n              <Eye className=\"mr-2 h-4 w-4\" />\n              View details\n            </DropdownMenuItem>\n            <DropdownMenuItem>\n              <Pencil className=\"mr-2 h-4 w-4\" />\n              Edit\n            </DropdownMenuItem>\n            <DropdownMenuSeparator />\n            <DropdownMenuItem className=\"text-destructive\">\n              <Trash2 className=\"mr-2 h-4 w-4\" />\n              Delete\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </div>\n    ),\n  },\n];\n\nconst data: Item[] = [\n  {\n    id: \"1\",\n    name: \"Project Alpha\",\n    date: \"Jan 15, 2024\",\n    status: \"completed\",\n    amount: \"$2,500\",\n  },\n  {\n    id: \"2\",\n    name: \"Website Redesign\",\n    date: \"Feb 3, 2024\",\n    status: \"processing\",\n    amount: \"$4,200\",\n  },\n  {\n    id: \"3\",\n    name: \"Mobile App MVP\",\n    date: \"Feb 18, 2024\",\n    status: \"pending\",\n    amount: \"$8,750\",\n  },\n  {\n    id: \"4\",\n    name: \"Brand Identity\",\n    date: \"Mar 5, 2024\",\n    status: \"completed\",\n    amount: \"$1,800\",\n  },\n  {\n    id: \"5\",\n    name: \"Marketing Campaign\",\n    date: \"Mar 22, 2024\",\n    status: \"cancelled\",\n    amount: \"$3,400\",\n  },\n  {\n    id: \"6\",\n    name: \"Analytics Dashboard\",\n    date: \"Apr 8, 2024\",\n    status: \"processing\",\n    amount: \"$5,600\",\n  },\n  {\n    id: \"7\",\n    name: \"E-commerce Platform\",\n    date: \"Apr 25, 2024\",\n    status: \"pending\",\n    amount: \"$12,000\",\n  },\n  {\n    id: \"8\",\n    name: \"API Integration\",\n    date: \"May 10, 2024\",\n    status: \"completed\",\n    amount: \"$3,200\",\n  },\n];\n\nexport default function Table05() {\n  const [sorting, setSorting] = useState<SortingState>([]);\n  const [rowSelection, setRowSelection] = useState({});\n  const [globalFilter, setGlobalFilter] = useState(\"\");\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    getSortedRowModel: getSortedRowModel(),\n    getFilteredRowModel: getFilteredRowModel(),\n    onSortingChange: setSorting,\n    onRowSelectionChange: setRowSelection,\n    onGlobalFilterChange: setGlobalFilter,\n    globalFilterFn: \"includesString\",\n    state: {\n      sorting,\n      rowSelection,\n      globalFilter,\n    },\n    initialState: {\n      pagination: { pageSize: 5 },\n    },\n  });\n\n  const pageCount = table.getPageCount();\n  const currentPage = table.getState().pagination.pageIndex + 1;\n\n  return (\n    <div className=\"max-w-3xl w-full space-y-4\">\n      <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        <div className=\"flex items-center gap-2\">\n          <span className=\"text-sm text-muted-foreground\">Show</span>\n          <Select\n            value={String(table.getState().pagination.pageSize)}\n            onValueChange={(value) => table.setPageSize(Number(value))}\n          >\n            <SelectTrigger className=\"h-8 w-16\">\n              <SelectValue />\n            </SelectTrigger>\n            <SelectContent>\n              {[5, 10, 20].map((size) => (\n                <SelectItem key={size} value={String(size)}>\n                  {size}\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n          <span className=\"text-sm text-muted-foreground\">entries</span>\n        </div>\n        <Input\n          placeholder=\"Search...\"\n          value={globalFilter}\n          onChange={(e) => setGlobalFilter(e.target.value)}\n          className=\"h-8 w-full sm:w-64\"\n        />\n      </div>\n\n      <div className=\"rounded-lg border\">\n        <Table>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => (\n                  <TableHead key={header.id}>\n                    {header.isPlaceholder\n                      ? null\n                      : flexRender(\n                          header.column.columnDef.header,\n                          header.getContext()\n                        )}\n                  </TableHead>\n                ))}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {table.getRowModel().rows.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow\n                  key={row.id}\n                  data-state={row.getIsSelected() && \"selected\"}\n                >\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell key={cell.id}>\n                      {flexRender(\n                        cell.column.columnDef.cell,\n                        cell.getContext()\n                      )}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableRow>\n                <TableCell\n                  colSpan={columns.length}\n                  className=\"h-24 text-center\"\n                >\n                  No results.\n                </TableCell>\n              </TableRow>\n            )}\n          </TableBody>\n        </Table>\n      </div>\n\n      <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        <p className=\"text-pretty text-sm text-muted-foreground\">\n          Showing{\" \"}\n          {table.getState().pagination.pageIndex *\n            table.getState().pagination.pageSize +\n            1}{\" \"}\n          to{\" \"}\n          {Math.min(\n            (table.getState().pagination.pageIndex + 1) *\n              table.getState().pagination.pageSize,\n            table.getFilteredRowModel().rows.length\n          )}{\" \"}\n          of {table.getFilteredRowModel().rows.length} entries\n        </p>\n        <div className=\"flex items-center gap-1\">\n          <Button\n            variant=\"outline\"\n            size=\"icon\"\n            className=\"h-8 w-8\"\n            onClick={() => table.previousPage()}\n            disabled={!table.getCanPreviousPage()}\n            aria-label=\"Previous page\"\n          >\n            <ChevronLeft className=\"h-4 w-4\" />\n            <span className=\"sr-only\">Previous page</span>\n          </Button>\n          {Array.from({ length: pageCount }, (_, i) => i + 1).map((page) => (\n            <Button\n              key={page}\n              variant={currentPage === page ? \"default\" : \"outline\"}\n              size=\"icon\"\n              className=\"h-8 w-8\"\n              onClick={() => table.setPageIndex(page - 1)}\n              aria-label={`Go to page ${page}`}\n            >\n              {page}\n            </Button>\n          ))}\n          <Button\n            variant=\"outline\"\n            size=\"icon\"\n            className=\"h-8 w-8\"\n            onClick={() => table.nextPage()}\n            disabled={!table.getCanNextPage()}\n            aria-label=\"Next page\"\n          >\n            <ChevronRight className=\"h-4 w-4\" />\n            <span className=\"sr-only\">Next page</span>\n          </Button>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        }
      ],
      "categories": [
        "tables"
      ]
    }
  ]
}