import * as preact from "preact"; import { ComponentChildren, createContext, h } from "preact"; import { TranslateProvider } from "@denysvuika/preact-translate"; import { StateUpdater, useState, useCallback, useMemo, useRef, } from "preact/compat"; import { Hanko, User, UserInfo, Passcode, Emails, Config, WebauthnCredentials, } from "@teamhanko/hanko-frontend-sdk"; import { translations } from "../Translations"; import Container from "../components/wrapper/Container"; import InitPage from "../pages/InitPage"; import { JSXInternal } from "preact/src/jsx"; import SignalLike = JSXInternal.SignalLike; type ExperimentalFeature = "conditionalMediation"; type ExperimentalFeatures = ExperimentalFeature[]; type ComponentName = "auth" | "profile"; interface Props { api?: string; lang?: string | SignalLike; fallbackLang?: string; experimental?: string; componentName: ComponentName; children?: ComponentChildren; } interface States { config: Config; setConfig: StateUpdater; userInfo: UserInfo; setUserInfo: StateUpdater; passcode: Passcode; setPasscode: StateUpdater; user: User; setUser: StateUpdater; emails: Emails; setEmails: StateUpdater; webauthnCredentials: WebauthnCredentials; setWebauthnCredentials: StateUpdater; page: h.JSX.Element; setPage: StateUpdater; } interface Context extends States { hanko: Hanko; componentName: ComponentName; experimentalFeatures?: ExperimentalFeatures; emitSuccessEvent: () => void; } export const AppContext = createContext(null); const AppProvider = ({ api, lang, fallbackLang = "en", componentName, experimental = "", }: Props) => { const ref = useRef(null); const hanko = useMemo(() => { if (api) { return new Hanko(api, 13000); } return null; }, [api]); const experimentalFeatures = useMemo( () => experimental .split(" ") .filter((feature) => feature.length) .map((feature) => feature as ExperimentalFeature), [experimental] ); const emitSuccessEvent = useCallback(() => { const event = new Event("hankoAuthSuccess", { bubbles: true, composed: true, }); const fn = setTimeout(() => { ref.current.dispatchEvent(event); }, 500); return () => clearTimeout(fn); }, []); const [config, setConfig] = useState(); const [userInfo, setUserInfo] = useState(null); const [passcode, setPasscode] = useState(); const [user, setUser] = useState(); const [emails, setEmails] = useState(); const [webauthnCredentials, setWebauthnCredentials] = useState(); const [page, setPage] = useState(); return ( {page} ); }; export default AppProvider;