{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "waitlist-form",
  "title": "Waitlist Form",
  "description": "Email waitlist form with editable CONTENT; posts to your API.",
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "path": "registry/default/blocks/waitlist-form.tsx",
      "content": "\"use client\"\n\nimport { ArrowRight, CheckCircle2, Loader2 } from \"lucide-react\"\nimport { useState, type FormEvent } from \"react\"\n\n/**\n * Edit CONTENT to change copy and API endpoint.\n * Wire CONTENT.endpoint to your own route (Host API).\n */\nconst CONTENT = {\n  label: \"Email\",\n  placeholder: \"you@company.com\",\n  submitLabel: \"Join waitlist\",\n  successMessage: \"You're on the list. We'll reach out soon.\",\n  footnote: \"Zero spam. Early-bird invite when seats open.\",\n  endpoint: \"/api/waitlist\",\n  source: \"waitlist\",\n}\n\nexport function WaitlistForm() {\n  const [email, setEmail] = useState(\"\")\n  const [status, setStatus] = useState<\n    \"idle\" | \"loading\" | \"success\" | \"error\"\n  >(\"idle\")\n  const [message, setMessage] = useState(\"\")\n\n  async function handleSubmit(e: FormEvent) {\n    e.preventDefault()\n    if (!email) return\n    setStatus(\"loading\")\n    try {\n      const response = await fetch(CONTENT.endpoint, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({ email, source: CONTENT.source }),\n      })\n      const data = (await response.json().catch(() => ({}))) as {\n        error?: string\n      }\n      if (!response.ok) throw new Error(data.error || \"Something went wrong\")\n      setStatus(\"success\")\n      setMessage(CONTENT.successMessage)\n      setEmail(\"\")\n    } catch (err) {\n      setStatus(\"error\")\n      setMessage(err instanceof Error ? err.message : \"Failed to join waitlist\")\n    }\n  }\n\n  if (status === \"success\") {\n    return (\n      <div className=\"flex items-start gap-3 border border-emerald-500/25 bg-emerald-500/5 px-4 py-3 text-sm font-medium text-emerald-700 dark:text-emerald-400\">\n        <CheckCircle2 className=\"mt-0.5 size-4 shrink-0\" aria-hidden />\n        <p>{message}</p>\n      </div>\n    )\n  }\n\n  return (\n    <div>\n      <form onSubmit={handleSubmit} className=\"space-y-3\">\n        <label\n          htmlFor=\"waitlist-email\"\n          className=\"block font-mono text-[11px] tracking-wide text-muted-foreground uppercase\"\n        >\n          {CONTENT.label}\n        </label>\n        <input\n          id=\"waitlist-email\"\n          type=\"email\"\n          required\n          placeholder={CONTENT.placeholder}\n          value={email}\n          onChange={(e) => setEmail(e.target.value)}\n          disabled={status === \"loading\"}\n          className=\"w-full border border-border-subtle bg-background px-3.5 py-2.5 text-sm text-foreground outline-none focus:border-foreground disabled:opacity-60\"\n        />\n        <button\n          type=\"submit\"\n          disabled={status === \"loading\"}\n          className=\"inline-flex h-11 w-full items-center justify-center gap-2 rounded-lg bg-foreground px-5 text-sm font-medium text-background disabled:opacity-50\"\n        >\n          {status === \"loading\" ? (\n            <Loader2 className=\"size-4 animate-spin\" aria-hidden />\n          ) : (\n            <>\n              {CONTENT.submitLabel}\n              <ArrowRight className=\"size-4\" aria-hidden />\n            </>\n          )}\n        </button>\n      </form>\n      {status === \"error\" ? (\n        <p className=\"mt-3 text-xs font-medium text-red-600 dark:text-red-400\">\n          {message}\n        </p>\n      ) : null}\n      <p className=\"mt-3 text-[11px] text-muted-foreground\">{CONTENT.footnote}</p>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/waitlist-form.tsx"
    }
  ],
  "type": "registry:block"
}