@upbudget/belvo-js
Version:
React component for Belvo
101 lines • 3.1 kB
JavaScript
"use client";
import Script from "next/script";
import React, {
createContext,
useCallback,
useContext,
useMemo,
useState
} from "react";
import { BelvoEvents } from "../react/types";
import { useBelvoAccessToken } from "../react/hooks/use-belvo-access-token";
const BELVO_SCRIPT_SRC = "https://cdn.belvo.io/belvo-widget-1-stable.js";
const BelvoNextContext = createContext(null);
function BelvoNextProvider({
getAccessToken,
analytics,
children
}) {
const [scriptReady, setScriptReady] = useState(false);
const [scriptError, setScriptError] = useState(null);
const { fetchToken } = useBelvoAccessToken(getAccessToken, analytics);
const handleScriptLoad = useCallback(() => {
analytics?.track(BelvoEvents.SCRIPT_LOADED);
setScriptReady(true);
}, [analytics]);
const handleScriptError = useCallback(() => {
const err = new Error(`Failed to load ${BELVO_SCRIPT_SRC}`);
analytics?.track(BelvoEvents.SCRIPT_ERROR, { error: err.message });
setScriptError(err);
}, [analytics]);
const open = useCallback(
async (extra = {}) => {
if (!scriptReady) throw new Error("Belvo script not loaded");
if (!window.belvoSDK) throw new Error("Belvo SDK not available");
const access = await fetchToken();
if (!access) throw new Error("Failed to fetch access token");
analytics?.track(BelvoEvents.WIDGET_OPENED, {
external_id: extra.external_id
});
const defaultConfig = {
locale: "pt",
mode: "webapp",
integration_type: "openfinance"
};
return new Promise((resolve) => {
window.belvoSDK.createWidget(access, {
...defaultConfig,
...extra,
callback(link, institution) {
analytics?.track(BelvoEvents.CONNECTION_SUCCESS, {
link,
institution
});
extra.onSuccess?.(link, institution);
resolve();
},
onExit(data) {
analytics?.track(
BelvoEvents.CONNECTION_EXIT,
data
);
extra.onExit?.(data);
resolve();
},
onEvent(data) {
analytics?.track(
BelvoEvents.WIDGET_EVENT,
data
);
extra.onEvent?.(data);
}
}).build();
});
},
[scriptReady, fetchToken, analytics]
);
const value = useMemo(
() => ({ open, scriptReady, scriptError, analytics }),
[open, scriptReady, scriptError, analytics]
);
return /* @__PURE__ */ React.createElement(BelvoNextContext.Provider, { value }, /* @__PURE__ */ React.createElement(
Script,
{
src: BELVO_SCRIPT_SRC,
strategy: "afterInteractive",
onLoad: handleScriptLoad,
onError: handleScriptError
}
), children);
}
function useBelvoNext() {
const ctx = useContext(BelvoNextContext);
if (!ctx)
throw new Error("useBelvoNext must be inside <BelvoNextProvider>");
return ctx;
}
export {
BelvoNextProvider,
useBelvoNext
};
//# sourceMappingURL=belvo-next-provider.js.map