{
  "name": "authentication-authfloworchestrator",
  "type": "registry:component",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "components/authentication/AuthFlowOrchestrator.tsx",
      "type": "registry:component",
      "content": "\"use client\";\n\nimport React, { useState, useCallback, useEffect, useMemo } from \"react\";\nimport { useBitcoinAuth } from \"../../hooks/useBitcoinAuth.js\";\nimport { CONTAINER_WIDTHS } from \"../../lib/layout-constants.js\";\nimport type { AuthStep } from \"../../lib/types.js\";\nimport { cn } from \"../../lib/utils.js\";\nimport { BackupImport } from \"../backup-recovery/BackupImport.js\";\nimport { useBapProfileSync } from \"../bap-identity/hooks/useBapProfileSync.js\";\nimport { AuthLayout, CenteredLayout } from \"../layouts/AuthLayout.js\";\nimport { ErrorDisplay } from \"../ui-components/ErrorDisplay.js\";\nimport { HandCashIcon } from \"../ui-components/HandCashIcon.js\";\nimport { LoadingButton } from \"../ui-components/LoadingButton.js\";\nimport { PasswordInput } from \"../ui-components/PasswordInput.js\";\nimport { YoursWalletIcon } from \"../ui-components/YoursWalletIcon.js\";\nimport { Button } from \"../ui/button.js\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../ui/card.js\";\nimport { Separator } from \"../ui/separator.js\";\nimport { OAuthConflictModal } from \"../wallet-integrations/OAuthConflictModal.js\";\nimport { DeviceLinkQR } from \"./DeviceLinkQR.js\";\nimport { LoginForm } from \"./LoginForm.js\";\nimport { OAuthRestoreFlow } from \"./OAuthRestoreFlow.js\";\nimport { SignupFlow } from \"./SignupFlow.js\";\n\nexport type AuthFlowType =\n\t| \"unified\" // Smart flow that determines signin/signup automatically\n\t| \"signin\" // Traditional signin flow\n\t| \"signup\" // Traditional signup flow\n\t| \"oauth-restore\" // OAuth backup restoration\n\t| \"device-link\" // Device linking via QR code\n\t| \"import\" // Import backup file\n\t| \"custom\"; // Custom flow managed externally\n\nexport interface AuthFlowOrchestratorProps {\n\t// Flow configuration\n\tflowType?: AuthFlowType;\n\tinitialStep?: AuthStep;\n\n\t// Available features\n\tenableOAuth?: boolean;\n\tenableDeviceLink?: boolean;\n\tenableFileImport?: boolean;\n\tenableLocalBackup?: boolean;\n\n\t// OAuth configuration\n\toauthProviders?: Array<{ id: string; name: string; icon: React.ReactNode }>;\n\n\t// Callbacks\n\tonSuccess?: (user: { id: string; address: string }) => void;\n\tonError?: (error: string) => void;\n\tonFlowChange?: (flow: AuthFlowType) => void;\n\tonStepChange?: (step: AuthStep) => void;\n\tonOAuthConflictResolved?: () => void;\n\n\t// Custom rendering\n\tcustomLayout?: React.ComponentType<{ children: React.ReactNode }>;\n\trenderCustomFlow?: () => React.ReactNode;\n\n\t// UI Options\n\tshowHeader?: boolean;\n\tshowFooter?: boolean;\n\tlayout?: \"full\" | \"centered\" | \"none\";\n\ttitle?: string;\n\tsubtitle?: string;\n\tclassName?: string;\n\n\t// Advanced options\n\tenableProfileSync?: boolean;\n\tdebug?: boolean;\n}\n\ninterface FlowState {\n\tcurrentFlow: AuthFlowType;\n\tcurrentStep: AuthStep;\n\terror?: string;\n\timportedBackup?: File;\n\toauthBackup?: {\n\t\tprovider: string;\n\t\tencryptedBackup: string;\n\t};\n\toauthConflict?: boolean;\n}\n\nexport const AuthFlowOrchestrator: React.FC<AuthFlowOrchestratorProps> = ({\n\tflowType = \"unified\",\n\tinitialStep = \"initial\",\n\tenableOAuth = true,\n\tenableDeviceLink = false,\n\tenableFileImport = true,\n\tenableLocalBackup = true,\n\toauthProviders = [\n\t\t{\n\t\t\tid: \"google\",\n\t\t\tname: \"Google\",\n\t\t\ticon: (\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\twidth=\"20\"\n\t\t\t\t\theight=\"20\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\taria-label=\"Google logo\"\n\t\t\t\t>\n\t\t\t\t\t<title>Google logo</title>\n\t\t\t\t\t<path\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\tfill=\"#4285F4\"\n\t\t\t\t\t/>\n\t\t\t\t\t<path\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\tfill=\"#34A853\"\n\t\t\t\t\t/>\n\t\t\t\t\t<path\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\tfill=\"#FBBC05\"\n\t\t\t\t\t/>\n\t\t\t\t\t<path\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\tfill=\"#EA4335\"\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: \"handcash\",\n\t\t\tname: \"HandCash\",\n\t\t\ticon: <HandCashIcon />,\n\t\t},\n\t\t{\n\t\t\tid: \"yourswallet\",\n\t\t\tname: \"Yours Wallet\",\n\t\t\ticon: <YoursWalletIcon />,\n\t\t},\n\t],\n\tonSuccess,\n\tonError,\n\tonFlowChange,\n\tonStepChange,\n\tonOAuthConflictResolved,\n\tcustomLayout,\n\trenderCustomFlow,\n\tshowHeader = true,\n\tshowFooter = true,\n\tlayout = \"none\",\n\ttitle = \"Welcome to BitcoinAuth\",\n\tsubtitle = \"Your journey to self-sovereign identity starts here\",\n\tclassName = \"\",\n\tenableProfileSync = true,\n\tdebug = false,\n}) => {\n\t// Core auth state\n\tconst auth = useBitcoinAuth();\n\tconst { isAuthenticated, mode, currentStep, hasLocalBackup, isLoading } =\n\t\tauth;\n\tconst profileSync = useBapProfileSync();\n\n\t// Local flow state\n\tconst [flowState, setFlowState] = useState<FlowState>({\n\t\tcurrentFlow: flowType,\n\t\tcurrentStep: initialStep,\n\t\toauthConflict: false,\n\t});\n\n\t// State for password input (import flow)\n\tconst [password, setPassword] = useState(\"\");\n\n\t// Update flow state helper\n\tconst updateFlowState = useCallback((updates: Partial<FlowState>) => {\n\t\tsetFlowState((prev) => ({ ...prev, ...updates }));\n\t}, []);\n\n\t// Handle flow changes\n\tconst handleFlowChange = useCallback(\n\t\t(newFlow: AuthFlowType) => {\n\t\t\tupdateFlowState({\n\t\t\t\tcurrentFlow: newFlow,\n\t\t\t\tcurrentStep: \"initial\",\n\t\t\t\terror: undefined,\n\t\t\t});\n\t\t\tonFlowChange?.(newFlow);\n\t\t},\n\t\t[updateFlowState, onFlowChange],\n\t);\n\n\t// Handle step changes\n\tconst handleStepChange = useCallback(\n\t\t(newStep: AuthStep) => {\n\t\t\tupdateFlowState({ currentStep: newStep });\n\t\t\tonStepChange?.(newStep);\n\t\t},\n\t\t[updateFlowState, onStepChange],\n\t);\n\n\t// Handle OAuth conflict resolution\n\tconst handleOAuthConflictResolved = useCallback(() => {\n\t\tupdateFlowState({ oauthConflict: false });\n\t\tonOAuthConflictResolved?.();\n\t}, [updateFlowState, onOAuthConflictResolved]);\n\n\t// Effect: Sync with auth state\n\tuseEffect(() => {\n\t\tif (isAuthenticated && auth.user) {\n\t\t\tonSuccess?.(auth.user);\n\t\t}\n\t}, [isAuthenticated, auth.user, onSuccess]);\n\n\t// Effect: Handle auth step changes\n\tuseEffect(() => {\n\t\tif (currentStep !== flowState.currentStep) {\n\t\t\thandleStepChange(currentStep);\n\t\t}\n\t}, [currentStep, flowState.currentStep, handleStepChange]);\n\n\t// Effect: Initialize profile sync if enabled\n\tuseEffect(() => {\n\t\tif (enableProfileSync && isAuthenticated && !profileSync.isScanning) {\n\t\t\t// Delay sync to avoid race conditions\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tprofileSync.syncProfiles();\n\t\t\t}, 1000);\n\t\t\treturn () => clearTimeout(timer);\n\t\t}\n\t}, [enableProfileSync, isAuthenticated, profileSync]);\n\n\t// Custom flow rendering\n\tif (flowType === \"custom\" && renderCustomFlow) {\n\t\treturn <>{renderCustomFlow()}</>;\n\t}\n\n\t// Main flow rendering logic\n\tconst renderFlow = () => {\n\t\tswitch (flowState.currentFlow) {\n\t\t\tcase \"unified\":\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"w-full\">\n\t\t\t\t\t\t{mode === \"signin\" ? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<LoginForm\n\t\t\t\t\t\t\t\t\tmode=\"signin\"\n\t\t\t\t\t\t\t\t\tonSuccess={(user) => onSuccess?.(user)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<div className=\"mt-8 flex flex-col gap-2 items-center\">\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"signup\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tDon't have an account? Sign up\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t{enableFileImport && (\n\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"import\")}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tImport backup file\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{enableOAuth && (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex flex-col gap-4\"\n\t\t\t\t\t\t\t\t\t\tstyle={{ marginTop: \"1.5rem\" }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-3\">\n\t\t\t\t\t\t\t\t\t\t\t<Separator className=\"flex-1\" />\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\tOr continue with\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t<Separator className=\"flex-1\" />\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex flex-col gap-3\">\n\t\t\t\t\t\t\t\t\t\t\t{oauthProviders.map((provider) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey={provider.id}\n\t\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tsize=\"lg\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// Use safe navigation that works in SSR\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst url = `/api/auth/signin/${provider.id}?callbackUrl=/dashboard`;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (typeof window !== \"undefined\") {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twindow.location.href = url;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"OAuth redirect attempted during SSR\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{ width: \"100%\" }}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-3 w-full justify-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: \"20px\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\theight: \"20px\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{provider.icon}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-base\">{provider.name}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<SignupFlow\n\t\t\t\t\t\t\t\t\tonSuccess={(user) => onSuccess?.(user)}\n\t\t\t\t\t\t\t\t\tonError={(authError) => onError?.(authError.message)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"flex justify-center\"\n\t\t\t\t\t\t\t\t\tstyle={{ marginTop: \"1rem\" }}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"signin\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tAlready have an account? Sign in\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\n\t\t\tcase \"signin\":\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<LoginForm mode=\"signin\" onSuccess={(user) => onSuccess?.(user)} />\n\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"flex flex-col items-center gap-2\"\n\t\t\t\t\t\t\tstyle={{ marginTop: \"1rem\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"signup\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tDon't have an account? Sign up\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t{enableFileImport && (\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=\"default\"\n\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"import\")}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tImport backup file\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{enableOAuth && (\n\t\t\t\t\t\t\t<div className=\"flex justify-center\">\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=\"default\"\n\t\t\t\t\t\t\t\t\tcolor=\"blue\"\n\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"oauth-restore\")}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRestore from cloud backup\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\n\t\t\tcase \"signup\":\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<SignupFlow\n\t\t\t\t\t\t\tonSuccess={(user) => onSuccess?.(user)}\n\t\t\t\t\t\t\tonError={(authError) => onError?.(authError.message)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<div className=\"flex justify-center\" style={{ marginTop: \"1rem\" }}>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"signin\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tAlready have an account? Sign in\n\t\t\t\t\t\t\t</Button>\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 \"oauth-restore\":\n\t\t\t\treturn (\n\t\t\t\t\t<OAuthRestoreFlow\n\t\t\t\t\t\tproviders={oauthProviders}\n\t\t\t\t\t\tshowProviderSelection={!flowState.oauthBackup}\n\t\t\t\t\t\tshowPasswordEntry={!!flowState.oauthBackup}\n\t\t\t\t\t\tonRestoreSuccess={(idKey) => {\n\t\t\t\t\t\t\tonSuccess?.({ id: idKey, address: \"\" });\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonRestoreError={(error) => {\n\t\t\t\t\t\t\tupdateFlowState({ error });\n\t\t\t\t\t\t\tonError?.(error);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tmockOAuthResponse={\n\t\t\t\t\t\t\tflowState.oauthBackup\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tprovider: flowState.oauthBackup.provider,\n\t\t\t\t\t\t\t\t\t\tencryptedBackup: flowState.oauthBackup.encryptedBackup,\n\t\t\t\t\t\t\t\t\t\tidKey: \"restored-id-key\",\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"import\":\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-2xl font-bold text-center\">Import Backup</h2>\n\t\t\t\t\t\t\t<span className=\"text-sm text-muted-foreground text-center\">\n\t\t\t\t\t\t\t\tImport your wallet backup file\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{flowState.currentStep !== \"password\" ? (\n\t\t\t\t\t\t\t<div className=\"flex flex-col gap-6\">\n\t\t\t\t\t\t\t\t<BackupImport\n\t\t\t\t\t\t\t\t\tonImport={async (file) => {\n\t\t\t\t\t\t\t\t\t\t// Use the AuthManager's importBackup method\n\t\t\t\t\t\t\t\t\t\tconst result = await auth.importBackup(file);\n\t\t\t\t\t\t\t\t\t\tif (result.success) {\n\t\t\t\t\t\t\t\t\t\t\t// The AuthManager will have set the proper state\n\t\t\t\t\t\t\t\t\t\t\t// Just update our flow state to reflect the change\n\t\t\t\t\t\t\t\t\t\t\tupdateFlowState({ currentStep: \"password\" });\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tupdateFlowState({\n\t\t\t\t\t\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\t\t\t\t\t\tresult.error?.message || \"Failed to import backup\",\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\tshowLabel={false}\n\t\t\t\t\t\t\t\t/>\n\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={() => handleFlowChange(\"signin\")}\n\t\t\t\t\t\t\t\t\tstyle={{ width: \"100%\" }}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tBack to sign in\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t\t\t\t\t<span className=\"text-center text-muted-foreground\">\n\t\t\t\t\t\t\t\t\tBackup file imported. Please enter your password to decrypt\n\t\t\t\t\t\t\t\t\tit.\n\t\t\t\t\t\t\t\t</span>\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 backup password\"\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\t{flowState.error && <ErrorDisplay error={flowState.error} />}\n\t\t\t\t\t\t\t\t<div className=\"flex flex-col gap-2\">\n\t\t\t\t\t\t\t\t\t<LoadingButton\n\t\t\t\t\t\t\t\t\t\tonClick={async () => {\n\t\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\t\t// Simply sign in with the password\n\t\t\t\t\t\t\t\t\t\t\t\t// The AuthManager already has the imported backup stored\n\t\t\t\t\t\t\t\t\t\t\t\tconst result = await auth.signIn(password);\n\t\t\t\t\t\t\t\t\t\t\t\tif (result.success && auth.user) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tonSuccess?.(auth.user);\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t// Optional: Trigger profile sync after successful backup import\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (enableProfileSync && !profileSync.isScanning) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprofileSync.syncProfiles();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}, 1000);\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\tupdateFlowState({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tresult.error?.message ||\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Invalid password or corrupted backup\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\t\t\tupdateFlowState({\n\t\t\t\t\t\t\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\terr instanceof Error\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? err.message\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: \"Failed to decrypt backup\",\n\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tloading={isLoading}\n\t\t\t\t\t\t\t\t\t\tdisabled={!password}\n\t\t\t\t\t\t\t\t\t\tsize=\"lg\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"w-full\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tDecrypt Backup\n\t\t\t\t\t\t\t\t\t</LoadingButton>\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tsize=\"lg\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\tupdateFlowState({ importedBackup: undefined });\n\t\t\t\t\t\t\t\t\t\t\thandleStepChange(\"initial\");\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tstyle={{ width: \"100%\" }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\n\t\t\tcase \"device-link\":\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<DeviceLinkQR\n\t\t\t\t\t\t\tonLinkGenerated={(url, token) => {\n\t\t\t\t\t\t\t\tconsole.log(\"Device link generated:\", { url, token });\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonError={(error) => {\n\t\t\t\t\t\t\t\tupdateFlowState({ error });\n\t\t\t\t\t\t\t\tonError?.(error);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<div className=\"flex justify-center\">\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"signin\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tBack to sign in\n\t\t\t\t\t\t\t</Button>\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\t// Select layout component\n\tconst LayoutComponent = useMemo(() => {\n\t\tif (customLayout) return customLayout;\n\t\tif (layout === \"centered\") return CenteredLayout;\n\t\tif (layout === \"full\") return AuthLayout;\n\t\treturn React.Fragment;\n\t}, [customLayout, layout]);\n\n\treturn (\n\t\t<>\n\t\t\t<LayoutComponent {...(layout === \"full\" ? { title, subtitle } : {})}>\n\t\t\t\t<div className={className}>\n\t\t\t\t\t{showHeader && flowState.currentFlow !== \"unified\" && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"flex justify-center\"\n\t\t\t\t\t\t\tstyle={{ marginBottom: \"1.5rem\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"flex items-center gap-4\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant={\n\t\t\t\t\t\t\t\t\t\tflowState.currentFlow === \"signin\" ? \"default\" : \"ghost\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"signin\")}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tSign In\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">|</span>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant={\n\t\t\t\t\t\t\t\t\t\tflowState.currentFlow === \"signup\" ? \"default\" : \"ghost\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"signup\")}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tSign Up\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t{enableOAuth && (\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">|</span>\n\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\tvariant={\n\t\t\t\t\t\t\t\t\t\t\t\tflowState.currentFlow === \"oauth-restore\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t? \"default\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t: \"ghost\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"oauth-restore\")}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tRestore\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{enableDeviceLink && (\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">|</span>\n\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\tvariant={\n\t\t\t\t\t\t\t\t\t\t\t\tflowState.currentFlow === \"device-link\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t? \"default\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t: \"ghost\"\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tsize=\"default\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => handleFlowChange(\"device-link\")}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tLink Device\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{flowState.error && flowState.currentFlow !== \"import\" && (\n\t\t\t\t\t\t<div style={{ marginBottom: \"1rem\" }}>\n\t\t\t\t\t\t\t<ErrorDisplay error={flowState.error} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{layout === \"centered\" ? (\n\t\t\t\t\t\t<div className=\"flex justify-center w-full\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\t\t\tmaxWidth: CONTAINER_WIDTHS.MODAL_SMALL,\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<Card className=\"p-6\">\n\t\t\t\t\t\t\t\t\t<div className=\"flex flex-col gap-6\">{renderFlow()}</div>\n\t\t\t\t\t\t\t\t</Card>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\trenderFlow()\n\t\t\t\t\t)}\n\n\t\t\t\t\t{showFooter && (\n\t\t\t\t\t\t<div className=\"flex justify-center\" style={{ marginTop: \"2rem\" }}>\n\t\t\t\t\t\t\t<span className=\"text-sm text-muted-foreground text-center\">\n\t\t\t\t\t\t\t\tYour keys, your Bitcoin.\n\t\t\t\t\t\t\t\t{enableLocalBackup && \" Encrypted locally.\"}\n\t\t\t\t\t\t\t\t{enableOAuth && \" Backed up securely.\"}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{debug && (\n\t\t\t\t\t\t<Card className=\"mt-8 p-4\">\n\t\t\t\t\t\t\t<div className=\"flex flex-col gap-1\">\n\t\t\t\t\t\t\t\t<span className=\"text-xs font-mono\">\n\t\t\t\t\t\t\t\t\tFlow: {flowState.currentFlow}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span className=\"text-xs font-mono\">\n\t\t\t\t\t\t\t\t\tStep: {flowState.currentStep}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span className=\"text-xs font-mono\">Auth Mode: {mode}</span>\n\t\t\t\t\t\t\t\t<span className=\"text-xs font-mono\">\n\t\t\t\t\t\t\t\t\tAuth Step: {currentStep}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span className=\"text-xs font-mono\">\n\t\t\t\t\t\t\t\t\tHas Backup: {hasLocalBackup ? \"Yes\" : \"No\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span className=\"text-xs font-mono\">\n\t\t\t\t\t\t\t\t\tAuthenticated: {isAuthenticated ? \"Yes\" : \"No\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</Card>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</LayoutComponent>\n\n\t\t\t{/* OAuth Conflict Modal */}\n\t\t\t{/* TODO: OAuthConflictModal needs to be refactored or replaced with proper backup conflict resolution modal\n\t\t\t{flowState.oauthConflict && (\n\t\t\t\t<OAuthConflictModal\n\t\t\t\t\tisOpen={true}\n\t\t\t\t\tonClose={handleOAuthConflictResolved}\n\t\t\t\t\tonKeepLocal={() => {\n\t\t\t\t\t\thandleOAuthConflictResolved();\n\t\t\t\t\t\t// Keep local backup logic\n\t\t\t\t\t}}\n\t\t\t\t\tonUseCloud={() => {\n\t\t\t\t\t\thandleOAuthConflictResolved();\n\t\t\t\t\t\t// Use cloud backup logic\n\t\t\t\t\t}}\n\t\t\t\t\tonMerge={() => {\n\t\t\t\t\t\thandleOAuthConflictResolved();\n\t\t\t\t\t\t// Merge backups logic\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t)} */}\n\t\t</>\n\t);\n};\n",
      "target": "<%- config.aliases.components %>/authfloworchestrator.tsx"
    }
  ]
}