{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-better-auth-demo",
  "title": "UseBetterAuthDemo",
  "description": "use-better-auth's hook in action.",
  "registryDependencies": [
    "card",
    "button",
    "badge",
    "input",
    "label",
    "tabs",
    "sonner",
    "https://guarahooks.com/r/use-better-auth.json"
  ],
  "files": [
    {
      "path": "registry/example/use-better-auth-demo.tsx",
      "content": "'use client';\n\nimport { useState } from 'react';\n\nimport { toast } from 'sonner';\n\nimport { Badge } from '@/components/ui/badge';\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 { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\n\nimport { useBetterAuth } from '@/hooks/guarahooks/use-better-auth';\n\ninterface DemoUser {\n  id: string;\n  name: string;\n  email: string;\n  avatar?: string;\n}\n\ninterface DemoCredentials extends Record<string, string | number | boolean> {\n  email: string;\n  password: string;\n}\n\n// Mock API responses for demo purposes\nconst mockLogin = async (credentials: DemoCredentials) => {\n  await new Promise((resolve) => setTimeout(resolve, 1000)); // Simulate network delay\n\n  if (\n    credentials.email === 'user@example.com' &&\n    credentials.password === 'password'\n  ) {\n    return {\n      token: 'mock-jwt-token-' + Date.now(),\n      user: {\n        id: '1',\n        name: 'John Doe',\n        email: credentials.email,\n        avatar: 'https://github.com/shadcn.png',\n      },\n    };\n  }\n\n  throw new Error('Invalid credentials');\n};\n\nconst mockRefresh = async () => {\n  await new Promise((resolve) => setTimeout(resolve, 500));\n  return {\n    token: 'refreshed-jwt-token-' + Date.now(),\n    user: {\n      id: '1',\n      name: 'John Doe',\n      email: 'user@example.com',\n      avatar: 'https://github.com/shadcn.png',\n    },\n  };\n};\n\nexport default function UseBetterAuthDemo() {\n  const [credentials, setCredentials] = useState<DemoCredentials>({\n    email: 'user@example.com',\n    password: 'password',\n  });\n  const [storageType, setStorageType] = useState<\n    'localStorage' | 'sessionStorage'\n  >('localStorage');\n  const [autoRefresh, setAutoRefresh] = useState(false);\n  const [lastAuthChange, setLastAuthChange] = useState<string>('');\n\n  // Main auth hook with localStorage\n  const mainAuth = useBetterAuth<DemoUser, DemoCredentials>({\n    storageKey: 'demo-auth-main',\n    storage: typeof window !== 'undefined' ? window[storageType] : undefined,\n    fetcher: async (creds) => mockLogin(creds),\n    refreshInterval: autoRefresh ? 10000 : undefined, // 10 seconds for demo\n    onAuthChange: (token, user) => {\n      const timestamp = new Date().toLocaleTimeString();\n      setLastAuthChange(\n        `${token ? 'Authenticated' : 'Unauthenticated'} at ${timestamp}`,\n      );\n\n      if (token && user) {\n        toast.success('Authentication successful!', {\n          description: `Welcome, ${user.name}!`,\n        });\n      } else {\n        toast.info('Logged out', {\n          description: 'Session ended',\n        });\n      }\n    },\n  });\n\n  // Secondary auth hook with custom fetcher for comparison\n  const customAuth = useBetterAuth<DemoUser, DemoCredentials>({\n    storageKey: 'demo-auth-custom',\n    fetcher: async (creds) => {\n      // Custom fetcher that simulates different API response\n      await new Promise((resolve) => setTimeout(resolve, 800));\n      return {\n        token: 'custom-token-' + Date.now(),\n        user: {\n          id: '2',\n          name: 'Custom User',\n          email: creds.email,\n        },\n      };\n    },\n  });\n\n  const handleLogin = async () => {\n    try {\n      await mainAuth.login(credentials);\n    } catch (error) {\n      toast.error('Login failed', {\n        description: error instanceof Error ? error.message : 'Unknown error',\n      });\n    }\n  };\n\n  const handleRefresh = async () => {\n    try {\n      // For demo, we'll simulate a refresh by updating the user\n      const refreshedData = await mockRefresh();\n      mainAuth.updateUser(refreshedData.user, refreshedData.token);\n      toast.success('Session refreshed!');\n    } catch (error) {\n      toast.error('Refresh failed', {\n        description: error instanceof Error ? error.message : 'Unknown error',\n      });\n    }\n  };\n\n  const handleUpdateUser = () => {\n    if (mainAuth.user) {\n      const updatedUser = {\n        ...mainAuth.user,\n        name: mainAuth.user.name + ' (Updated)',\n      };\n      mainAuth.updateUser(updatedUser);\n      toast.success('User updated!');\n    }\n  };\n\n  const toggleAutoRefresh = () => {\n    setAutoRefresh(!autoRefresh);\n    toast.info(`Auto-refresh ${!autoRefresh ? 'enabled' : 'disabled'}`, {\n      description: !autoRefresh\n        ? 'Token will refresh every 10 seconds'\n        : undefined,\n    });\n  };\n\n  const clearError = () => {\n    mainAuth.clearError();\n    customAuth.clearError();\n  };\n\n  return (\n    <div className=\"w-full max-w-4xl mx-auto space-y-6\">\n      {/* Main Authentication Card */}\n      <Card>\n        <CardHeader>\n          <CardTitle className=\"flex items-center justify-between\">\n            Main Authentication\n            <div className=\"flex gap-2\">\n              <Badge\n                variant={mainAuth.isAuthenticated ? 'default' : 'secondary'}\n              >\n                {mainAuth.isAuthenticated\n                  ? 'Authenticated'\n                  : 'Not Authenticated'}\n              </Badge>\n              {mainAuth.loading && <Badge variant=\"outline\">Loading</Badge>}\n            </div>\n          </CardTitle>\n          <CardDescription>\n            Demonstration of the main auth hook with customizable storage and\n            auto-refresh\n          </CardDescription>\n        </CardHeader>\n        <CardContent className=\"space-y-4\">\n          {!mainAuth.isAuthenticated ? (\n            <div className=\"space-y-4\">\n              <div className=\"grid grid-cols-2 gap-4\">\n                <div className=\"space-y-2\">\n                  <Label htmlFor=\"email\">Email</Label>\n                  <Input\n                    id=\"email\"\n                    type=\"email\"\n                    value={credentials.email}\n                    onChange={(e) =>\n                      setCredentials((prev) => ({\n                        ...prev,\n                        email: e.target.value,\n                      }))\n                    }\n                    placeholder=\"user@example.com\"\n                  />\n                </div>\n                <div className=\"space-y-2\">\n                  <Label htmlFor=\"password\">Password</Label>\n                  <Input\n                    id=\"password\"\n                    type=\"password\"\n                    value={credentials.password}\n                    onChange={(e) =>\n                      setCredentials((prev) => ({\n                        ...prev,\n                        password: e.target.value,\n                      }))\n                    }\n                    placeholder=\"password\"\n                  />\n                </div>\n              </div>\n\n              <div className=\"flex gap-2\">\n                <Button onClick={handleLogin} disabled={mainAuth.loading}>\n                  {mainAuth.loading ? 'Logging in...' : 'Login'}\n                </Button>\n                <Button\n                  variant=\"outline\"\n                  onClick={() =>\n                    setStorageType(\n                      storageType === 'localStorage'\n                        ? 'sessionStorage'\n                        : 'localStorage',\n                    )\n                  }\n                >\n                  Storage: {storageType}\n                </Button>\n              </div>\n\n              <div className=\"text-sm text-muted-foreground p-3 bg-muted rounded-md\">\n                <p>\n                  <strong>Demo credentials:</strong>\n                </p>\n                <p>Email: user@example.com</p>\n                <p>Password: password</p>\n              </div>\n            </div>\n          ) : (\n            <div className=\"space-y-4\">\n              <div className=\"flex items-center gap-4\">\n                {mainAuth.user?.avatar && (\n                  <img\n                    src={mainAuth.user.avatar}\n                    alt={mainAuth.user.name}\n                    className=\"w-10 h-10 rounded-full\"\n                  />\n                )}\n                <div>\n                  <p className=\"font-medium\">{mainAuth.user?.name}</p>\n                  <p className=\"text-sm text-muted-foreground\">\n                    {mainAuth.user?.email}\n                  </p>\n                </div>\n              </div>\n\n              <div className=\"text-xs font-mono bg-muted p-2 rounded border overflow-hidden\">\n                <p>\n                  <strong>Token:</strong> {mainAuth.token?.substring(0, 50)}...\n                </p>\n              </div>\n\n              <div className=\"flex gap-2 flex-wrap\">\n                <Button onClick={mainAuth.logout} variant=\"outline\">\n                  Logout\n                </Button>\n                <Button onClick={handleRefresh} variant=\"outline\">\n                  Refresh Session\n                </Button>\n                <Button onClick={handleUpdateUser} variant=\"outline\">\n                  Update User\n                </Button>\n                <Button onClick={toggleAutoRefresh} variant=\"outline\">\n                  {autoRefresh ? 'Disable' : 'Enable'} Auto-refresh\n                </Button>\n              </div>\n            </div>\n          )}\n\n          {mainAuth.error && (\n            <div className=\"p-3 border border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950 rounded-md\">\n              <div className=\"flex items-center justify-between\">\n                <p className=\"text-sm text-red-800 dark:text-red-200\">\n                  <strong>Error:</strong> {mainAuth.error.message}\n                </p>\n                <Button onClick={clearError} variant=\"ghost\" size=\"sm\">\n                  Clear\n                </Button>\n              </div>\n            </div>\n          )}\n\n          {lastAuthChange && (\n            <div className=\"text-xs text-muted-foreground\">\n              <strong>Last change:</strong> {lastAuthChange}\n            </div>\n          )}\n        </CardContent>\n      </Card>\n\n      {/* Feature Comparison Tabs */}\n      <Tabs defaultValue=\"storage\" className=\"w-full\">\n        <TabsList className=\"grid w-full grid-cols-3\">\n          <TabsTrigger value=\"storage\">Storage Types</TabsTrigger>\n          <TabsTrigger value=\"custom-fetcher\">Custom Fetcher</TabsTrigger>\n          <TabsTrigger value=\"features\">Advanced Features</TabsTrigger>\n        </TabsList>\n\n        <TabsContent value=\"storage\" className=\"space-y-4\">\n          <Card>\n            <CardHeader>\n              <CardTitle>Storage Comparison</CardTitle>\n              <CardDescription>\n                Compare localStorage vs sessionStorage behavior\n              </CardDescription>\n            </CardHeader>\n            <CardContent className=\"space-y-4\">\n              <div className=\"grid grid-cols-2 gap-4\">\n                <div className=\"space-y-2\">\n                  <h4 className=\"font-medium\">localStorage</h4>\n                  <p className=\"text-sm text-muted-foreground\">\n                    Persists across browser sessions\n                  </p>\n                  <Badge\n                    variant={\n                      storageType === 'localStorage' ? 'default' : 'outline'\n                    }\n                  >\n                    {storageType === 'localStorage' ? 'Active' : 'Inactive'}\n                  </Badge>\n                </div>\n                <div className=\"space-y-2\">\n                  <h4 className=\"font-medium\">sessionStorage</h4>\n                  <p className=\"text-sm text-muted-foreground\">\n                    Cleared when tab closes\n                  </p>\n                  <Badge\n                    variant={\n                      storageType === 'sessionStorage' ? 'default' : 'outline'\n                    }\n                  >\n                    {storageType === 'sessionStorage' ? 'Active' : 'Inactive'}\n                  </Badge>\n                </div>\n              </div>\n              <p className=\"text-sm text-muted-foreground\">\n                Switch storage types and notice how authentication persists\n                differently. Try logging in, switching tabs, or refreshing the\n                page.\n              </p>\n            </CardContent>\n          </Card>\n        </TabsContent>\n\n        <TabsContent value=\"custom-fetcher\" className=\"space-y-4\">\n          <Card>\n            <CardHeader>\n              <CardTitle>Custom Fetcher Example</CardTitle>\n              <CardDescription>\n                Demonstrates how to use a custom fetcher function\n              </CardDescription>\n            </CardHeader>\n            <CardContent className=\"space-y-4\">\n              <div className=\"flex items-center justify-between\">\n                <div>\n                  <p className=\"font-medium\">Custom Auth State</p>\n                  <p className=\"text-sm text-muted-foreground\">\n                    {customAuth.isAuthenticated\n                      ? `Logged in as ${customAuth.user?.name}`\n                      : 'Not authenticated'}\n                  </p>\n                </div>\n                <Badge\n                  variant={customAuth.isAuthenticated ? 'default' : 'secondary'}\n                >\n                  {customAuth.isAuthenticated ? 'Active' : 'Inactive'}\n                </Badge>\n              </div>\n\n              <div className=\"flex gap-2\">\n                {!customAuth.isAuthenticated ? (\n                  <Button\n                    onClick={() => customAuth.login(credentials)}\n                    disabled={customAuth.loading}\n                  >\n                    {customAuth.loading\n                      ? 'Logging in...'\n                      : 'Login with Custom Fetcher'}\n                  </Button>\n                ) : (\n                  <Button onClick={customAuth.logout} variant=\"outline\">\n                    Logout\n                  </Button>\n                )}\n              </div>\n\n              {customAuth.token && (\n                <div className=\"text-xs font-mono bg-muted p-2 rounded border\">\n                  <p>\n                    <strong>Custom Token:</strong>{' '}\n                    {customAuth.token.substring(0, 30)}...\n                  </p>\n                </div>\n              )}\n            </CardContent>\n          </Card>\n        </TabsContent>\n\n        <TabsContent value=\"features\" className=\"space-y-4\">\n          <Card>\n            <CardHeader>\n              <CardTitle>Advanced Features</CardTitle>\n              <CardDescription>\n                Overview of all hook capabilities\n              </CardDescription>\n            </CardHeader>\n            <CardContent>\n              <div className=\"grid grid-cols-2 gap-4\">\n                <div className=\"space-y-3\">\n                  <div className=\"flex items-center gap-2\">\n                    <Badge\n                      variant={mainAuth.isAuthenticated ? 'default' : 'outline'}\n                    >\n                      Authentication State\n                    </Badge>\n                    <span className=\"text-sm\">\n                      {mainAuth.isAuthenticated ? 'Active' : 'Inactive'}\n                    </span>\n                  </div>\n\n                  <div className=\"flex items-center gap-2\">\n                    <Badge variant={autoRefresh ? 'default' : 'outline'}>\n                      Auto Refresh\n                    </Badge>\n                    <span className=\"text-sm\">\n                      {autoRefresh ? 'Enabled' : 'Disabled'}\n                    </span>\n                  </div>\n\n                  <div className=\"flex items-center gap-2\">\n                    <Badge\n                      variant={\n                        storageType === 'localStorage' ? 'default' : 'secondary'\n                      }\n                    >\n                      Storage Type\n                    </Badge>\n                    <span className=\"text-sm\">{storageType}</span>\n                  </div>\n                </div>\n\n                <div className=\"space-y-3\">\n                  <div className=\"flex items-center gap-2\">\n                    <Badge variant={mainAuth.loading ? 'default' : 'outline'}>\n                      Loading State\n                    </Badge>\n                    <span className=\"text-sm\">\n                      {mainAuth.loading ? 'Loading' : 'Idle'}\n                    </span>\n                  </div>\n\n                  <div className=\"flex items-center gap-2\">\n                    <Badge variant={mainAuth.error ? 'destructive' : 'outline'}>\n                      Error Handling\n                    </Badge>\n                    <span className=\"text-sm\">\n                      {mainAuth.error ? 'Has Error' : 'No Errors'}\n                    </span>\n                  </div>\n\n                  <div className=\"flex items-center gap-2\">\n                    <Badge variant=\"outline\">Cross-tab Sync</Badge>\n                    <span className=\"text-sm\">Automatic</span>\n                  </div>\n                </div>\n              </div>\n            </CardContent>\n          </Card>\n        </TabsContent>\n      </Tabs>\n    </div>\n  );\n}\n",
      "type": "registry:example",
      "target": "components/example/use-better-auth-demo.tsx"
    }
  ],
  "type": "registry:example"
}