{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-ai-avatar",
  "title": "Use AI Avatar",
  "description": "React hook for generating AI avatars from photos with multiple style options",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/blocks/badges/use-ai-avatar/components/elements/use-ai-avatar.tsx",
      "content": "\"use client\";\n\nimport { useCallback, useState } from \"react\";\n\nexport type AvatarStyle =\n  | \"pixel-art\"\n  | \"anime\"\n  | \"cartoon\"\n  | \"realistic\"\n  | \"sketch\";\n\nexport interface UseAiAvatarOptions {\n  /** API endpoint for avatar generation */\n  endpoint?: string;\n  /** Style of avatar to generate */\n  style?: AvatarStyle;\n  /** Custom prompt additions */\n  promptAdditions?: string;\n  /** Whether to convert to grayscale */\n  grayscale?: boolean;\n  /** Whether to remove background */\n  removeBackground?: boolean;\n  /** Output size */\n  outputSize?: { width: number; height: number };\n}\n\nexport interface GenerateAvatarParams {\n  /** Source image URL or File */\n  image: string | File;\n  /** Override options for this generation */\n  options?: Partial<UseAiAvatarOptions>;\n}\n\nexport interface UseAiAvatarReturn {\n  /** Generate an AI avatar from an image */\n  generateAvatar: (params: GenerateAvatarParams) => Promise<string | null>;\n  /** Whether generation is in progress */\n  isGenerating: boolean;\n  /** Current generation progress (0-100) */\n  progress: number;\n  /** Current status message */\n  status: string | null;\n  /** Error if generation failed */\n  error: Error | null;\n  /** The generated avatar URL */\n  avatarUrl: string | null;\n  /** Reset the hook state */\n  reset: () => void;\n}\n\nconst DEFAULT_PROMPTS: Record<AvatarStyle, string> = {\n  \"pixel-art\": `8-bit pixel-art portrait, chest-up view. Use a simple solid background for easy cutout.\nApply flat grayscale shading with four tones. Style should be printed, cartoonish, anime inspired, and cute tender soft.\nPreserve the facial structure. The character should fit entirely within the frame, with no labels or text.\nIMPORTANT: Maintain proper proportions. If the image appears too large, zoom out to ensure the full figure fits.`,\n  anime: `Anime style portrait, clean lines, vibrant but soft coloring.\nPreserve facial features and expression. Simple background.\nHigh quality illustration style.`,\n  cartoon: `Cartoon style portrait with bold outlines and flat colors.\nExaggerated features in a friendly, approachable style.\nClean simple background.`,\n  realistic: `Photorealistic portrait enhancement.\nImprove lighting and composition while maintaining likeness.\nProfessional headshot style.`,\n  sketch: `Hand-drawn sketch style portrait with pencil texture.\nArtistic interpretation while preserving likeness.\nWhite paper background with subtle shading.`,\n};\n\n/**\n * Hook for generating AI avatars from photos\n *\n * @example\n * ```tsx\n * const { generateAvatar, isGenerating, avatarUrl } = useAiAvatar({\n *   endpoint: \"/api/generate-avatar\",\n *   style: \"pixel-art\",\n * });\n *\n * const handleUpload = async (file: File) => {\n *   const url = await generateAvatar({ image: file });\n *   if (url) {\n *     setProfilePicture(url);\n *   }\n * };\n * ```\n */\nexport function useAiAvatar(\n  options: UseAiAvatarOptions = {},\n): UseAiAvatarReturn {\n  const {\n    endpoint = \"/api/generate-avatar\",\n    style = \"pixel-art\",\n    promptAdditions = \"\",\n    grayscale = true,\n    removeBackground = true,\n    outputSize = { width: 684, height: 577 },\n  } = options;\n\n  const [isGenerating, setIsGenerating] = useState(false);\n  const [progress, setProgress] = useState(0);\n  const [status, setStatus] = useState<string | null>(null);\n  const [error, setError] = useState<Error | null>(null);\n  const [avatarUrl, setAvatarUrl] = useState<string | null>(null);\n\n  const reset = useCallback(() => {\n    setIsGenerating(false);\n    setProgress(0);\n    setStatus(null);\n    setError(null);\n    setAvatarUrl(null);\n  }, []);\n\n  const generateAvatar = useCallback(\n    async (params: GenerateAvatarParams): Promise<string | null> => {\n      const { image, options: overrideOptions = {} } = params;\n\n      const finalStyle = overrideOptions.style ?? style;\n      const finalPromptAdditions =\n        overrideOptions.promptAdditions ?? promptAdditions;\n      const finalGrayscale = overrideOptions.grayscale ?? grayscale;\n      const finalRemoveBackground =\n        overrideOptions.removeBackground ?? removeBackground;\n      const finalOutputSize = overrideOptions.outputSize ?? outputSize;\n\n      setIsGenerating(true);\n      setProgress(0);\n      setStatus(\"Preparing image...\");\n      setError(null);\n\n      try {\n        // Convert File to base64 if needed\n        let imageUrl: string;\n\n        if (image instanceof File) {\n          setProgress(10);\n          setStatus(\"Uploading image...\");\n\n          imageUrl = await new Promise<string>((resolve, reject) => {\n            const reader = new FileReader();\n            reader.onloadend = () => resolve(reader.result as string);\n            reader.onerror = () => reject(new Error(\"Failed to read file\"));\n            reader.readAsDataURL(image);\n          });\n        } else {\n          imageUrl = image;\n        }\n\n        setProgress(20);\n        setStatus(\"Generating AI avatar...\");\n\n        // Build the prompt\n        const basePrompt = DEFAULT_PROMPTS[finalStyle];\n        const fullPrompt = finalPromptAdditions\n          ? `${basePrompt}\\n\\n${finalPromptAdditions}`\n          : basePrompt;\n\n        // Call the API endpoint\n        const response = await fetch(endpoint, {\n          method: \"POST\",\n          headers: {\n            \"Content-Type\": \"application/json\",\n          },\n          body: JSON.stringify({\n            imageUrl,\n            prompt: fullPrompt,\n            style: finalStyle,\n            grayscale: finalGrayscale,\n            removeBackground: finalRemoveBackground,\n            outputSize: finalOutputSize,\n          }),\n        });\n\n        if (!response.ok) {\n          const errorData = await response.json().catch(() => ({}));\n          throw new Error(\n            errorData.error || `Generation failed: ${response.status}`,\n          );\n        }\n\n        setProgress(80);\n        setStatus(\"Processing result...\");\n\n        const data = await response.json();\n\n        if (!data.url) {\n          throw new Error(\"No avatar URL in response\");\n        }\n\n        setProgress(100);\n        setStatus(\"Complete!\");\n        setAvatarUrl(data.url);\n\n        return data.url;\n      } catch (err) {\n        const error =\n          err instanceof Error ? err : new Error(\"Avatar generation failed\");\n        setError(error);\n        setStatus(\"Failed\");\n        return null;\n      } finally {\n        setIsGenerating(false);\n      }\n    },\n    [endpoint, style, promptAdditions, grayscale, removeBackground, outputSize],\n  );\n\n  return {\n    generateAvatar,\n    isGenerating,\n    progress,\n    status,\n    error,\n    avatarUrl,\n    reset,\n  };\n}\n\n/**\n * Server-side helper for generating AI avatars using FAL AI\n *\n * This is meant to be used in an API route. Example:\n *\n * ```ts\n * // app/api/generate-avatar/route.ts\n * import { generateAiAvatar } from \"@/components/elements/use-ai-avatar\";\n *\n * export async function POST(req: Request) {\n *   const body = await req.json();\n *   const result = await generateAiAvatar(body);\n *   return Response.json(result);\n * }\n * ```\n */\nexport interface GenerateAiAvatarServerParams {\n  imageUrl: string;\n  prompt: string;\n  style?: AvatarStyle;\n  grayscale?: boolean;\n  removeBackground?: boolean;\n  outputSize?: { width: number; height: number };\n}\n\n// Note: The actual FAL AI integration should be done in the user's API route\n// This is just the type definitions and client-side hook\n",
      "type": "registry:component"
    }
  ],
  "docs": "Client-side hook for AI avatar generation. Supports pixel-art, anime, cartoon, realistic, and sketch styles. Requires a backend API endpoint (FAL AI recommended).",
  "categories": [
    "badges"
  ],
  "type": "registry:ui"
}