{
  "name": "authentication-oauthrestoreflow",
  "type": "registry:component",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "components/authentication/OAuthRestoreFlow.tsx",
      "type": "registry:component",
      "content": "\"use client\";\n\nimport { useCallback, useMemo, useState } from \"react\";\nimport { useBitcoinAuth } from \"../../hooks/useBitcoinAuth.js\";\nimport { ErrorDisplay } from \"../ui-components/ErrorDisplay.js\";\nimport { LoadingButton } from \"../ui-components/LoadingButton.js\";\nimport { Modal } from \"../ui-components/Modal.js\";\nimport { PasswordInput } from \"../ui-components/PasswordInput.js\";\nimport { Button } from \"../ui/button.js\";\nimport {\n\ttype OAuthProvider,\n\tOAuthProviders,\n} from \"../wallet-integrations/OAuthProviders.js\";\n\nexport interface OAuthRestoreFlowProps {\n\t// Available OAuth providers\n\tproviders?: OAuthProvider[];\n\n\t// Callback URLs\n\tsignupCallbackUrl?: string;\n\tsigninCallbackUrl?: string;\n\n\t// Flow customization\n\tshowProviderSelection?: boolean;\n\tshowPasswordEntry?: boolean;\n\tallowProviderSwitch?: boolean;\n\n\t// Modal behavior\n\tisModal?: boolean;\n\tisOpen?: boolean;\n\tonClose?: () => void;\n\n\t// Event callbacks\n\tonProviderSelected?: (provider: string) => void;\n\tonPasswordValidated?: (password: string) => void;\n\tonRestoreSuccess?: (idKey: string) => void;\n\tonRestoreError?: (error: string) => void;\n\tonFlowComplete?: () => void;\n\n\t// Styling\n\tclassName?: string;\n\ttitle?: string;\n\tsubtitle?: string;\n\n\t// Debug/testing\n\tmockOAuthResponse?: {\n\t\tprovider: string;\n\t\tencryptedBackup: string;\n\t\tidKey: string;\n\t};\n}\n\ntype RestoreStep = \"provider\" | \"password\" | \"processing\" | \"success\" | \"error\";\n\nexport function OAuthRestoreFlow({\n\tproviders = [\n\t\t{\n\t\t\tid: \"google\",\n\t\t\tname: \"Google\",\n\t\t\tenabled: true,\n\t\t\ticon: (\n\t\t\t\t<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\">\n\t\t\t\t\t<title>Google</title>\n\t\t\t\t\t<path\n\t\t\t\t\t\tfill=\"#4285F4\"\n\t\t\t\t\t\td=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n\t\t\t\t\t/>\n\t\t\t\t\t<path\n\t\t\t\t\t\tfill=\"#34A853\"\n\t\t\t\t\t\td=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n\t\t\t\t\t/>\n\t\t\t\t\t<path\n\t\t\t\t\t\tfill=\"#FBBC05\"\n\t\t\t\t\t\td=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n\t\t\t\t\t/>\n\t\t\t\t\t<path\n\t\t\t\t\t\tfill=\"#EA4335\"\n\t\t\t\t\t\td=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"github\",\n\t\t\tname: \"GitHub\",\n\t\t\tenabled: true,\n\t\t\ticon: (\n\t\t\t\t<svg width=\"20\" height=\"20\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n\t\t\t\t\t<title>GitHub</title>\n\t\t\t\t\t<path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z\" />\n\t\t\t\t</svg>\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tid: \"twitter\",\n\t\t\tname: \"X (Twitter)\",\n\t\t\tenabled: true,\n\t\t\ticon: (\n\t\t\t\t<svg width=\"20\" height=\"20\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n\t\t\t\t\t<title>X (Twitter)</title>\n\t\t\t\t\t<path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" />\n\t\t\t\t</svg>\n\t\t\t),\n\t\t},\n\t],\n\tsignupCallbackUrl = \"/signup/oauth\",\n\tsigninCallbackUrl = \"/signin/oauth-restore\",\n\tshowProviderSelection = true,\n\tshowPasswordEntry = true,\n\tallowProviderSwitch = true,\n\tisModal = false,\n\tisOpen = true,\n\tonClose,\n\tonProviderSelected,\n\tonPasswordValidated,\n\tonRestoreSuccess,\n\tonRestoreError,\n\tonFlowComplete,\n\tclassName = \"\",\n\ttitle = \"Restore from Cloud Backup\",\n\tsubtitle = \"Sign in with your linked account to restore your wallet\",\n\tmockOAuthResponse,\n}: OAuthRestoreFlowProps) {\n\tconst [currentStep, setCurrentStep] = useState<RestoreStep>(\"provider\");\n\tconst [selectedProvider, setSelectedProvider] = useState<string>(\"\");\n\tconst [password, setPassword] = useState(\"\");\n\tconst [error, setError] = useState<string>(\"\");\n\tconst [encryptedBackup, setEncryptedBackup] = useState<string>(\"\");\n\n\tconst auth = useBitcoinAuth();\n\tconst { isLoading } = auth;\n\n\t// Handle methods that might not be available in all contexts (for backward compatibility)\n\tconst restoreFromBackup = useMemo(() => {\n\t\tconst authWithMethods = auth as typeof auth & {\n\t\t\trestoreFromBackup?: (\n\t\t\t\tencryptedBackup: string,\n\t\t\t\tpassword: string,\n\t\t\t) => Promise<{ success: boolean; idKey?: string; error?: string }>;\n\t\t};\n\t\treturn (\n\t\t\tauthWithMethods.restoreFromBackup ||\n\t\t\t(async () => ({\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"restoreFromBackup not available in this context\",\n\t\t\t}))\n\t\t);\n\t}, [auth]);\n\n\tconst validatePassword = useMemo(() => {\n\t\tconst authWithMethods = auth as typeof auth & {\n\t\t\tvalidatePassword?: (\n\t\t\t\tencryptedBackup: string,\n\t\t\t\tpassword: string,\n\t\t\t) => Promise<boolean>;\n\t\t};\n\t\treturn authWithMethods.validatePassword || (async () => false);\n\t}, [auth]);\n\n\t// Handle OAuth provider selection\n\tconst handleProviderClick = useCallback(\n\t\tasync (provider: string) => {\n\t\t\ttry {\n\t\t\t\tsetError(\"\");\n\t\t\t\tsetSelectedProvider(provider);\n\t\t\t\tonProviderSelected?.(provider);\n\n\t\t\t\t// If we have a mock response (for testing), use it\n\t\t\t\tif (mockOAuthResponse && mockOAuthResponse.provider === provider) {\n\t\t\t\t\tsetEncryptedBackup(mockOAuthResponse.encryptedBackup);\n\t\t\t\t\tsetCurrentStep(\"password\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Start OAuth flow\n\t\t\t\tsetCurrentStep(\"processing\");\n\n\t\t\t\t// Redirect to OAuth provider\n\t\t\t\tconst callbackUrl =\n\t\t\t\t\tcurrentStep === \"provider\" ? signinCallbackUrl : signupCallbackUrl;\n\t\t\t\tconst authUrl = `/api/auth/signin/${provider}?callbackUrl=${encodeURIComponent(callbackUrl)}`;\n\t\t\t\twindow.location.href = authUrl;\n\t\t\t} catch (err) {\n\t\t\t\tconst errorMessage =\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to start OAuth flow\";\n\t\t\t\tsetError(errorMessage);\n\t\t\t\tsetCurrentStep(\"error\");\n\t\t\t\tonRestoreError?.(errorMessage);\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tcurrentStep,\n\t\t\tsigninCallbackUrl,\n\t\t\tsignupCallbackUrl,\n\t\t\tmockOAuthResponse,\n\t\t\tonProviderSelected,\n\t\t\tonRestoreError,\n\t\t],\n\t);\n\n\t// Handle password validation and restore\n\tconst handlePasswordSubmit = useCallback(async () => {\n\t\tif (!password.trim() || !encryptedBackup) {\n\t\t\tsetError(\"Password is required\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tsetError(\"\");\n\t\t\tsetCurrentStep(\"processing\");\n\n\t\t\t// Validate password can decrypt the backup\n\t\t\tconst isValid = await validatePassword(encryptedBackup, password);\n\t\t\tif (!isValid) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Invalid password. Please check your password and try again.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tonPasswordValidated?.(password);\n\n\t\t\t// Restore from backup\n\t\t\tconst result = await restoreFromBackup(encryptedBackup, password);\n\n\t\t\tif (result.success && \"idKey\" in result && result.idKey) {\n\t\t\t\tsetCurrentStep(\"success\");\n\t\t\t\tonRestoreSuccess?.(result.idKey);\n\n\t\t\t\t// Auto-close after success\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tonFlowComplete?.();\n\t\t\t\t\tonClose?.();\n\t\t\t\t}, 2000);\n\t\t\t} else {\n\t\t\t\tthrow new Error(result.error || \"Failed to restore backup\");\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst errorMessage =\n\t\t\t\terr instanceof Error ? err.message : \"Failed to restore backup\";\n\t\t\tsetError(errorMessage);\n\t\t\tsetCurrentStep(\"error\");\n\t\t\tonRestoreError?.(errorMessage);\n\t\t}\n\t}, [\n\t\tpassword,\n\t\tencryptedBackup,\n\t\tvalidatePassword,\n\t\trestoreFromBackup,\n\t\tonPasswordValidated,\n\t\tonRestoreSuccess,\n\t\tonRestoreError,\n\t\tonFlowComplete,\n\t\tonClose,\n\t]);\n\n\t// Handle provider switch\n\tconst handleProviderSwitch = useCallback(() => {\n\t\tsetCurrentStep(\"provider\");\n\t\tsetSelectedProvider(\"\");\n\t\tsetPassword(\"\");\n\t\tsetError(\"\");\n\t\tsetEncryptedBackup(\"\");\n\t}, []);\n\n\t// Handle retry\n\tconst handleRetry = useCallback(() => {\n\t\tif (selectedProvider && allowProviderSwitch) {\n\t\t\tsetCurrentStep(\"password\");\n\t\t} else {\n\t\t\tsetCurrentStep(\"provider\");\n\t\t\tsetSelectedProvider(\"\");\n\t\t}\n\t\tsetPassword(\"\");\n\t\tsetError(\"\");\n\t}, [selectedProvider, allowProviderSwitch]);\n\n\tconst renderContent = () => {\n\t\tswitch (currentStep) {\n\t\t\tcase \"provider\":\n\t\t\t\tif (!showProviderSelection) {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div className=\"flex justify-center\">\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-center\">\n\t\t\t\t\t\t\t\tProvider selection disabled\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"flex flex-col gap-6\">\n\t\t\t\t\t\t<div className=\"flex flex-col items-center gap-2\">\n\t\t\t\t\t\t\t<h2 className=\"text-xl font-semibold text-center\">{title}</h2>\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-center text-sm\">\n\t\t\t\t\t\t\t\t{subtitle}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<OAuthProviders\n\t\t\t\t\t\t\tproviders={providers}\n\t\t\t\t\t\t\taction=\"signin\"\n\t\t\t\t\t\t\tonProviderClick={handleProviderClick}\n\t\t\t\t\t\t\tloading={isLoading}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\n\t\t\tcase \"password\":\n\t\t\t\tif (!showPasswordEntry) {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div className=\"flex justify-center\">\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-center\">\n\t\t\t\t\t\t\t\tPassword entry disabled\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"flex flex-col gap-6\">\n\t\t\t\t\t\t<div className=\"flex flex-col items-center gap-2\">\n\t\t\t\t\t\t\t<h2 className=\"text-xl font-semibold text-center\">\n\t\t\t\t\t\t\t\tEnter Your Password\n\t\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-center text-sm\">\n\t\t\t\t\t\t\t\tEnter the password you used to encrypt your wallet backup\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{selectedProvider && allowProviderSwitch && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tonClick={handleProviderSwitch}\n\t\t\t\t\t\t\t\t\tclassName=\"mt-2 text-primary\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tSwitch Provider ({selectedProvider})\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tonKeyDown={(e) =>\n\t\t\t\t\t\t\t\t\te.key === \"Enter\" &&\n\t\t\t\t\t\t\t\t\t!isLoading &&\n\t\t\t\t\t\t\t\t\tpassword.trim() &&\n\t\t\t\t\t\t\t\t\thandlePasswordSubmit()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<PasswordInput\n\t\t\t\t\t\t\t\t\tvalue={password}\n\t\t\t\t\t\t\t\t\tonChange={setPassword}\n\t\t\t\t\t\t\t\t\tplaceholder=\"Enter your wallet password\"\n\t\t\t\t\t\t\t\t\tdisabled={isLoading}\n\t\t\t\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{error && <ErrorDisplay error={error} />}\n\n\t\t\t\t\t\t\t<LoadingButton\n\t\t\t\t\t\t\t\tonClick={handlePasswordSubmit}\n\t\t\t\t\t\t\t\tloading={isLoading}\n\t\t\t\t\t\t\t\tdisabled={!password.trim()}\n\t\t\t\t\t\t\t\tclassName=\"w-full\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tRestore Wallet\n\t\t\t\t\t\t\t</LoadingButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\n\t\t\tcase \"processing\":\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"flex flex-col items-center gap-4\">\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\tclassName=\"animate-spin h-10 w-10 text-primary\"\n\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\taria-label=\"Loading spinner\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<title>Loading spinner</title>\n\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\tclassName=\"opacity-25\"\n\t\t\t\t\t\t\t\tcx=\"12\"\n\t\t\t\t\t\t\t\tcy=\"12\"\n\t\t\t\t\t\t\t\tr=\"10\"\n\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\tstrokeWidth=\"4\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\tclassName=\"opacity-75\"\n\t\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t\t\td=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<h2 className=\"text-xl font-semibold text-center\">\n\t\t\t\t\t\t\t{selectedProvider\n\t\t\t\t\t\t\t\t? \"Restoring Wallet...\"\n\t\t\t\t\t\t\t\t: \"Connecting to Provider...\"}\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<p className=\"text-muted-foreground text-center text-sm\">\n\t\t\t\t\t\t\t{selectedProvider\n\t\t\t\t\t\t\t\t? \"Decrypting and restoring your wallet backup\"\n\t\t\t\t\t\t\t\t: \"Please complete the sign-in process in the popup window\"}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\n\t\t\tcase \"success\":\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"flex flex-col items-center gap-4\">\n\t\t\t\t\t\t<div className=\"w-12 h-12 rounded-full bg-green-500 flex items-center justify-center\">\n\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\twidth=\"24\"\n\t\t\t\t\t\t\t\theight=\"24\"\n\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\tstroke=\"white\"\n\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\taria-label=\"Success\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<title>Success</title>\n\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t\td=\"M5 13l4 4L19 7\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<h2 className=\"text-xl font-semibold text-center\">\n\t\t\t\t\t\t\tWallet Restored!\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<p className=\"text-muted-foreground text-center text-sm\">\n\t\t\t\t\t\t\tYour wallet has been successfully restored from your cloud backup.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\n\t\t\tcase \"error\":\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"flex flex-col gap-6\">\n\t\t\t\t\t\t<div className=\"flex flex-col items-center gap-4\">\n\t\t\t\t\t\t\t<div className=\"w-12 h-12 rounded-full bg-destructive flex items-center justify-center\">\n\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\twidth=\"24\"\n\t\t\t\t\t\t\t\t\theight=\"24\"\n\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\tstroke=\"white\"\n\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\taria-label=\"Error\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<title>Error</title>\n\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t\t\td=\"M6 18L18 6M6 6l12 12\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<h2 className=\"text-xl font-semibold text-center\">\n\t\t\t\t\t\t\t\tRestore Failed\n\t\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<ErrorDisplay error={error} />\n\n\t\t\t\t\t\t<div className=\"flex flex-col gap-3\">\n\t\t\t\t\t\t\t<LoadingButton\n\t\t\t\t\t\t\t\tonClick={handleRetry}\n\t\t\t\t\t\t\t\tloading={false}\n\t\t\t\t\t\t\t\tclassName=\"w-full\"\n\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tTry Again\n\t\t\t\t\t\t\t</LoadingButton>\n\n\t\t\t\t\t\t\t{onClose && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tsize=\"lg\"\n\t\t\t\t\t\t\t\t\tonClick={onClose}\n\t\t\t\t\t\t\t\t\tclassName=\"w-full\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t};\n\n\tif (isModal) {\n\t\treturn (\n\t\t\t<Modal\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tonClose={onClose || (() => {})}\n\t\t\t\tclassName=\"max-w-md\"\n\t\t\t>\n\t\t\t\t<div className={`p-6 ${className || \"\"}`}>{renderContent()}</div>\n\t\t\t</Modal>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tclassName={`w-full h-full flex items-center justify-center ${className || \"\"}`}\n\t\t>\n\t\t\t<div className=\"w-full max-w-md p-4\">{renderContent()}</div>\n\t\t</div>\n\t);\n}\n",
      "target": "<%- config.aliases.components %>/oauthrestoreflow.tsx"
    }
  ]
}