{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-fetch-demo",
  "title": "UseFetchDemo",
  "description": "use-fetch's hook in action.",
  "registryDependencies": [
    "card",
    "button",
    "https://guarahooks.com/r/use-fetch.json"
  ],
  "files": [
    {
      "path": "registry/example/use-fetch-demo.tsx",
      "content": "'use client';\n\nimport React, { useState } from 'react';\n\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from '@/components/ui/card';\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\n\nimport {\n  FetchProvider,\n  useFetch,\n  useFetchContext,\n  type FetchConfig,\n} from '@/hooks/guarahooks/use-fetch';\n\ninterface HttpBinResponse {\n  args: Record<string, string>;\n  data: string;\n  files: Record<string, string>;\n  form: Record<string, string>;\n  headers: Record<string, string>;\n  json: Record<string, string | number | boolean | null> | null;\n  origin: string;\n  url: string;\n}\n\ninterface PostData {\n  title: string;\n  body: string;\n  userId: number;\n}\n\ninterface Post extends PostData {\n  id: number;\n}\n\n// Demo component that shows GET request\nfunction GetDemo() {\n  const { data, error, loading, refetch, abort, aborted } =\n    useFetch<HttpBinResponse>('/delay/3');\n\n  return (\n    <Card>\n      <CardHeader>\n        <CardTitle>GET Request</CardTitle>\n        <CardDescription>\n          Fetches data with a 3-second delay to test abort functionality\n        </CardDescription>\n      </CardHeader>\n      <CardContent className=\"space-y-4\">\n        <div className=\"flex items-center gap-2\">\n          <Badge variant={loading ? 'default' : 'secondary'}>\n            {loading ? 'Loading...' : 'Idle'}\n          </Badge>\n          {aborted && <Badge variant=\"destructive\">Aborted</Badge>}\n        </div>\n\n        {error && <p className=\"text-destructive\">Error: {error.message}</p>}\n\n        {!loading && !aborted && data && (\n          <div>\n            <Label className=\"text-sm font-medium\">Response:</Label>\n            <pre className=\"mt-2 p-3 rounded-md bg-muted text-sm overflow-auto max-h-32\">\n              {JSON.stringify(data, null, 2)}\n            </pre>\n          </div>\n        )}\n      </CardContent>\n      <CardFooter className=\"flex justify-end gap-2\">\n        <Button variant=\"outline\" onClick={abort} disabled={!loading}>\n          Abort\n        </Button>\n        <Button onClick={refetch} disabled={loading}>\n          Refetch\n        </Button>\n      </CardFooter>\n    </Card>\n  );\n}\n\n// Demo component that shows POST request\nfunction PostDemo() {\n  const [title, setTitle] = useState('Test Post');\n  const [body, setBody] = useState(\n    'This is a test post from the useFetch demo',\n  );\n\n  const {\n    data,\n    error,\n    loading,\n    refetch: createPost,\n  } = useFetch<Post>('https://jsonplaceholder.typicode.com/posts', {\n    method: 'POST',\n    body: JSON.stringify({ title, body, userId: 1 }),\n    headers: { 'Content-Type': 'application/json' },\n    immediate: false,\n  });\n\n  const handleSubmit = async () => {\n    const result = await createPost();\n    if (result) {\n      console.log('Post created:', result);\n    }\n  };\n\n  return (\n    <Card>\n      <CardHeader>\n        <CardTitle>POST Request</CardTitle>\n        <CardDescription>\n          Creates a new post using JSONPlaceholder API (bypasses baseURL)\n        </CardDescription>\n      </CardHeader>\n      <CardContent className=\"space-y-4\">\n        <div className=\"space-y-2\">\n          <Label htmlFor=\"title\">Title</Label>\n          <Input\n            id=\"title\"\n            value={title}\n            onChange={(e) => setTitle(e.target.value)}\n            placeholder=\"Enter post title\"\n          />\n        </div>\n\n        <div className=\"space-y-2\">\n          <Label htmlFor=\"body\">Body</Label>\n          <textarea\n            id=\"body\"\n            value={body}\n            onChange={(e) => setBody(e.target.value)}\n            placeholder=\"Enter post body\"\n            className=\"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\"\n          />\n        </div>\n\n        {error && <p className=\"text-destructive\">Error: {error.message}</p>}\n\n        {data && (\n          <div>\n            <Label className=\"text-sm font-medium\">Created Post:</Label>\n            <pre className=\"mt-2 p-3 rounded-md bg-muted text-sm overflow-auto\">\n              {JSON.stringify(data, null, 2)}\n            </pre>\n          </div>\n        )}\n      </CardContent>\n      <CardFooter>\n        <Button onClick={handleSubmit} disabled={loading} className=\"w-full\">\n          {loading ? 'Creating...' : 'Create Post'}\n        </Button>\n      </CardFooter>\n    </Card>\n  );\n}\n\n// Demo component that shows dynamic configuration\nfunction ConfigDemo() {\n  const { config, updateConfig } = useFetchContext();\n  const [newBaseURL, setNewBaseURL] = useState('');\n  const [newTimeout, setNewTimeout] = useState('');\n  const [showSuccess, setShowSuccess] = useState(false);\n\n  const handleUpdateConfig = () => {\n    const updates: Partial<FetchConfig> = {};\n\n    if (newBaseURL) {\n      updates.baseURL = newBaseURL;\n    }\n\n    if (newTimeout) {\n      updates.timeout = parseInt(newTimeout);\n    }\n\n    updateConfig(updates);\n    setNewBaseURL('');\n    setNewTimeout('');\n    setShowSuccess(true);\n\n    // Hide success message after 3 seconds\n    setTimeout(() => setShowSuccess(false), 3000);\n  };\n\n  return (\n    <Card>\n      <CardHeader>\n        <CardTitle>Dynamic Configuration</CardTitle>\n        <CardDescription>\n          Update global fetch configuration at runtime using useFetchContext\n        </CardDescription>\n      </CardHeader>\n      <CardContent className=\"space-y-4\">\n        <div>\n          <Label className=\"text-sm font-medium\">Current Config:</Label>\n          <pre className=\"mt-2 p-3 rounded-md bg-muted text-sm overflow-auto\">\n            {JSON.stringify(\n              {\n                baseURL: config.baseURL,\n                timeout: config.timeout,\n                retries: config.retries,\n                retryDelay: config.retryDelay,\n              },\n              null,\n              2,\n            )}\n          </pre>\n        </div>\n\n        <div className=\"border-t\" />\n\n        <div className=\"space-y-2\">\n          <Label htmlFor=\"baseURL\">New Base URL</Label>\n          <Input\n            id=\"baseURL\"\n            value={newBaseURL}\n            onChange={(e) => setNewBaseURL(e.target.value)}\n            placeholder=\"e.g., https://api.example.com\"\n          />\n        </div>\n\n        <div className=\"space-y-2\">\n          <Label htmlFor=\"timeout\">New Timeout (ms)</Label>\n          <Input\n            id=\"timeout\"\n            type=\"number\"\n            value={newTimeout}\n            onChange={(e) => setNewTimeout(e.target.value)}\n            placeholder=\"e.g., 5000\"\n          />\n        </div>\n\n        {showSuccess && (\n          <div className=\"flex items-center p-3 rounded-md bg-green-50 border border-green-200 dark:bg-green-950 dark:border-green-800\">\n            <div className=\"text-sm text-green-800 dark:text-green-200\">\n              ✓ Configuration updated successfully!\n            </div>\n          </div>\n        )}\n      </CardContent>\n      <CardFooter>\n        <Button\n          onClick={handleUpdateConfig}\n          disabled={!newBaseURL && !newTimeout}\n          className=\"w-full\"\n        >\n          Update Configuration\n        </Button>\n      </CardFooter>\n    </Card>\n  );\n}\n\n// Main demo component wrapped with provider\nfunction UseFetchDemoContent() {\n  return (\n    <div className=\"w-full max-w-4xl mx-auto\">\n      <div className=\"mb-6\">\n        <h1 className=\"text-2xl font-bold mb-2\">useFetch Hook Demo</h1>\n        <p className=\"text-muted-foreground\">\n          Demonstrando as funcionalidades do hook useFetch com provider global,\n          retry automático, timeout e controle de abort. Teste os diferentes\n          tipos de requisição e configurações dinâmicas.\n        </p>\n      </div>\n\n      <Tabs defaultValue=\"get\" className=\"w-full\">\n        <TabsList className=\"grid w-full grid-cols-3\">\n          <TabsTrigger value=\"get\">GET Request</TabsTrigger>\n          <TabsTrigger value=\"post\">POST Request</TabsTrigger>\n          <TabsTrigger value=\"config\">Configuration</TabsTrigger>\n        </TabsList>\n\n        <TabsContent value=\"get\" className=\"mt-4\">\n          <GetDemo />\n        </TabsContent>\n\n        <TabsContent value=\"post\" className=\"mt-4\">\n          <PostDemo />\n        </TabsContent>\n\n        <TabsContent value=\"config\" className=\"mt-4\">\n          <ConfigDemo />\n        </TabsContent>\n      </Tabs>\n    </div>\n  );\n}\n\nexport default function UseFetchDemo() {\n  return (\n    <FetchProvider\n      config={{\n        baseURL: 'https://httpbin.org',\n        timeout: 10000,\n        retries: 2,\n        retryDelay: 1000,\n        headers: {\n          'User-Agent': 'useFetch-Demo/1.0',\n        },\n      }}\n    >\n      <UseFetchDemoContent />\n    </FetchProvider>\n  );\n}\n",
      "type": "registry:example",
      "target": "components/example/use-fetch-demo.tsx"
    }
  ],
  "type": "registry:example"
}