{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "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 > 1_048_576) {\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 onOpenChange={setOpen} open={open}>\n      <DialogTrigger render={<Button />}>Open Dialog</DialogTrigger>\n      <DialogContent className=\"gap-0 rounded-3xl p-0 sm:max-w-lg\">\n        <DialogHeader className=\"border-b px-6 py-4\">\n          <DialogTitle className=\"text-balance font-medium\">\n            Add a writer\n          </DialogTitle>\n        </DialogHeader>\n\n        <div className=\"grid grid-cols-1 px-6 pt-4 pb-6 md:grid-cols-5\">\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 alt=\"Profile\" src={image || undefined} />\n                <AvatarFallback>\n                  <UserRoundIcon\n                    aria-hidden=\"true\"\n                    className=\"text-muted-foreground\"\n                    size={52}\n                  />\n                </AvatarFallback>\n              </Avatar>\n              <Button\n                className=\"-top-0.5 -right-0.5 absolute rounded-full border-[3px] border-background bg-accent 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                size=\"icon-sm\"\n                variant=\"ghost\"\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-muted-foreground text-sm\">\n              Max file size: 1MB\n            </p>\n            <input\n              accept=\"image/*\"\n              className=\"hidden\"\n              onChange={handleFileChange}\n              ref={fileInputRef}\n              type=\"file\"\n            />\n            <Button\n              className=\"mt-2\"\n              onClick={triggerFileInput}\n              size=\"sm\"\n              variant=\"outline\"\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 className=\"flex items-center\" htmlFor=\"author-name\">\n                  Author name <span className=\"text-primary\">*</span>\n                </Label>\n                <Input\n                  id=\"author-name\"\n                  onChange={(e) => setAuthorName(e.target.value)}\n                  required\n                  value={authorName}\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                  onChange={(e) => setTitle(e.target.value)}\n                  value={title}\n                />\n              </div>\n            </div>\n\n            <div className=\"flex justify-end gap-2\">\n              <Button onClick={() => setOpen(false)} variant=\"outline\">\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"
  ]
}