From ade643f61c8ae6c469941171c0d54f1354b4513c Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 4 Jan 2026 19:22:57 +0000 Subject: [PATCH] feat: add LoginHandler component for executing login actions - Created LoginHandler component to process /login command results - Handles three action types: - add-account: Adds account to AccountManager and sets as active - error: Shows error toast with descriptive message - open-dialog: Shows info toast (dialog UI coming in next phase) - Uses sonner for toast notifications with success/error feedback - Integrated with WindowRenderer routing system - Component auto-executes action on mount via useEffect Files: - src/components/LoginHandler.tsx (new) - src/components/WindowRenderer.tsx (updated) --- src/components/LoginHandler.tsx | 95 +++++++++++++++++++++++++++++++ src/components/WindowRenderer.tsx | 10 ++++ 2 files changed, 105 insertions(+) create mode 100644 src/components/LoginHandler.tsx diff --git a/src/components/LoginHandler.tsx b/src/components/LoginHandler.tsx new file mode 100644 index 0000000..cfe8501 --- /dev/null +++ b/src/components/LoginHandler.tsx @@ -0,0 +1,95 @@ +import { useEffect } from "react"; +import { toast } from "sonner"; +import { Check, X, Info } from "lucide-react"; +import type { ReadOnlyAccount } from "@/lib/account-types"; +import accountManager from "@/services/accounts"; + +interface LoginHandlerProps { + action: "add-account" | "error" | "open-dialog"; + account?: ReadOnlyAccount; + message?: string; +} + +/** + * LoginHandler - Executes login command actions + * + * This component handles the result of the /login command: + * - add-account: Adds account to AccountManager and sets as active + * - error: Shows error toast + * - open-dialog: Shows info about opening login dialog (UI coming soon) + */ +export default function LoginHandler({ + action, + account, + message, +}: LoginHandlerProps) { + useEffect(() => { + const handleAction = async () => { + switch (action) { + case "add-account": + if (!account) { + toast.error("Failed to add account", { + description: "No account provided", + icon: , + }); + return; + } + + try { + // Add account to manager + accountManager.addAccount(account); + + // Set as active account + accountManager.setActive(account.id); + + // Show success toast + toast.success("Account added successfully", { + description: `Logged in as ${account.pubkey.slice(0, 8)}...${account.pubkey.slice(-8)}`, + icon: , + }); + } catch (error) { + toast.error("Failed to add account", { + description: + error instanceof Error ? error.message : "Unknown error", + icon: , + }); + } + break; + + case "error": + toast.error("Login failed", { + description: message || "Unknown error occurred", + icon: , + }); + break; + + case "open-dialog": + toast.info("Login dialog", { + description: + "Login dialog UI coming soon. For now, use: login ", + icon: , + duration: 5000, + }); + break; + + default: + toast.error("Unknown action", { + description: `Unhandled action: ${action}`, + icon: , + }); + } + }; + + handleAction(); + }, [action, account, message]); + + // This component doesn't render anything visible - it just executes the action + return ( +
+
+

Processing login...

+

This window can be closed.

+
+
+ ); +} diff --git a/src/components/WindowRenderer.tsx b/src/components/WindowRenderer.tsx index d0c535b..90debd4 100644 --- a/src/components/WindowRenderer.tsx +++ b/src/components/WindowRenderer.tsx @@ -33,6 +33,7 @@ const SpellsViewer = lazy(() => const SpellbooksViewer = lazy(() => import("./SpellbooksViewer").then((m) => ({ default: m.SpellbooksViewer })), ); +const LoginHandler = lazy(() => import("./LoginHandler")); // Loading fallback component function ViewerLoading() { @@ -175,6 +176,15 @@ export function WindowRenderer({ window, onClose }: WindowRendererProps) { case "spellbooks": content = ; break; + case "login-handler": + content = ( + + ); + break; default: content = (