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 = (