import { useEffect, useRef, useState } from "react"; import { Landmark } from "lucide-react"; import { toast } from "sonner"; import { Button, type ButtonProps } from "@/components/ui/button"; import { api } from "@/lib/api"; import { useFinanceData } from "@/context/FinanceDataContext"; import { PlaidLinkSession } from "./PlaidLinkSession"; export function ConnectBankButton({ children = "Connect your bank", autoStart = false, ...props }: ButtonProps & { autoStart?: boolean }) { const { syncPlaid, refreshData } = useFinanceData(); const [token, setToken] = useState(null); const [busy, setBusy] = useState(false); const starting = useRef(false); const autoStarted = useRef(false); const start = async () => { if (starting.current) return; starting.current = true; setBusy(true); try { setToken((await api.plaid.createLinkToken()).link_token); } catch { toast.error("Couldn't start bank connection. Please try again."); } finally { setBusy(false); starting.current = false; } }; useEffect(() => { if (!autoStart) autoStarted.current = false; if (autoStart && !autoStarted.current) { autoStarted.current = true; void start(); } // The initial navigation intent should run only once, including StrictMode. }, [autoStart]); const complete = async (publicToken: string) => { setToken(null); setBusy(true); try { await api.plaid.exchangeToken(publicToken); try { await syncPlaid(); toast.success("Bank connected and accounts updated"); } catch (error) { refreshData(); toast.warning(error instanceof Error ? error.message : "Bank connected. Sync needs another attempt."); } } catch { toast.error("Couldn't finish connecting the bank. Please try again."); } finally { setBusy(false); } }; return token ? { void complete(publicToken); }} onClose={failed => { setToken(null); if (failed) toast.error("Bank connection wasn't completed. Please try again."); }} /> : ; }