import React, { useRef } from 'react'; import { WebComponent } from '../../webComponent/WebComponent'; import { withReduxStore } from '../../helpers/store/helpers'; import { PresentationMode, WebComponentType } from '../../types/internal/webComponent.types'; import { RequestRefreshEvent, RequestRenderingEvent, UnitComponentsMessage, UnitWhiteLabelAppEvent } from '../../messages/webMessages/unitComponentsMessages'; import type { WebViewMessage } from '../../messages/webMessages'; import { BottomSheetRenderingType, SlotRendering, } from '../../types/internal/bottomSheet.types'; import type { BottomSheetSlotData } from '../../types/internal/bottomSheet.types'; import { eventBus } from '../../utils/eventBus'; import { BottomSheetNativeMessage } from '../../messages/nativeMessages/bottomSheetMessage'; import { useEventListener } from '../../hooks/useEventListener'; import WebView from 'react-native-webview'; import { getWhiteLabelAppParams, getWhiteLabelAppScript, injectAccountCreationActionsOpenPlaidForLinkExternalAccount, injectCardCreated, injectRefreshEventIfNeeded, injectRequestEditBill, injectRequestCreateManualBillPay, injectRequestOpenArchivedBills, injectRequestOpenVendors, injectRequestOpenPaymentMethods, injectVendorFormTrySubmit, injectUnsavedChangesAction, injectBillActionResult, } from './UNWhiteLabelAppComponent.utils'; import { BillPayMenuMessage, RequestEditBillEvent } from '../../messages/webMessages/billPayMenuMessage'; import { BillActionsMessage } from '../../messages/webMessages/billActionsMessage'; import { BillPayBillsMessage } from '../../messages/webMessages/billPayBillsMessage'; import { BalanceSummaryMessage } from '../../messages/webMessages/balanceSummaryMessage'; import { VendorFormMessage } from '../../messages/webMessages/vendorFormMessage'; import { UnsavedChangesMessage, UnsavedChangesActionEvent } from '../../messages/webMessages/unsavedChangesMessage'; import { UserDataKeys } from '../../types/internal/unitStore.types'; import { PageMessage } from '../../messages/webMessages/pageMessage'; import UNStoreManagerHelper from '../../nativeModulesHelpers/UNStoreModuleHelper/UNStoreModuleHelper'; import { ActivityMessage } from '../../messages/webMessages/activityMessage'; import { setItemInWindowUnitStore } from '../../utils/windowUnitStore'; import { UNBaseView } from '../../nativeComponents/UNBaseView'; import { UnitComponentsSDK } from '../../unitComponentsSdkManager/UnitComponentsSdkManager'; import { AccountMessage } from '../../messages/webMessages/accountMessage'; import { CardCreatedEvent, CardMessage } from '../../messages/webMessages/cardMessage'; import { OpenPlaidEvent, PlaidMessage } from '../../messages/webMessages/plaidMessages'; import { injectUnitPlaidExit, injectUnitPlaidResponse } from '../UNPayeeManagementComponent/UNPayeeManagementComponent.utils'; import { LinkExit, LinkSuccess, open as openPlaidLink, create as createPlaidLink } from 'react-native-plaid-link-sdk'; export interface UNWhiteLabelAppComponentProps { // inputs customerToken?: string; jwtToken?: string; // ui theme?: string; language?: string; } const UNWhiteLabelAppComponent = (props: UNWhiteLabelAppComponentProps) => { const webRef = useRef(null); const handleWebViewMessage = (message: WebViewMessage) => { switch (message.type) { case UnitComponentsMessage.UNIT_REQUEST_RENDERING: { const slotData: BottomSheetSlotData = { componentName: WebComponentType.whiteLabelApp, requestRenderingEvent: message.details as RequestRenderingEvent, }; const data = { type: BottomSheetRenderingType.Slot, data: slotData, } as SlotRendering; eventBus.emit(BottomSheetNativeMessage.REQUEST_RENDERING, data); break; } case UnitComponentsMessage.UNIT_WHITE_LABEL_APP_ON_LOAD: { const data = message.details as UnitWhiteLabelAppEvent; if (data.attributes.customerToken) { UnitComponentsSDK.setCustomerToken(data.attributes.customerToken); UNStoreManagerHelper.saveValue(UserDataKeys.unitCustomerToken, data.attributes.customerToken); // Upon receiving a new token, the web interface updates the window. Therefore, we (only) store it for subsequent windows. // updateWindowUnitStore(); } break; } case PageMessage.PAGE_LOADED: updateWindowUnitStore(); break; case PlaidMessage.UNIT_OPEN_PLAID: openPlaid(message.details as OpenPlaidEvent); break; } }; const updateWindowUnitStore = async () => { /** * The 2FA-token (verifiedToken) is managed for all the components in UNWebComponent. */ try { const token = await UNStoreManagerHelper.getValue(UserDataKeys.unitCustomerToken); if (token) { setItemInWindowUnitStore(webRef.current, UserDataKeys.unitCustomerToken, token); } } catch (e) { console.log(e); } }; const requestRefresh = (data: RequestRefreshEvent) => { injectRefreshEventIfNeeded(webRef.current, data); }; const dispatchActivityFiltersChanged = (query: string) => { webRef.current?.injectJavaScript(`dispatchActivityFilterChangedEvent('${query}')`); }; const dispatchBillsFiltersChanged = (query: string) => { webRef.current?.injectJavaScript(`dispatchBillsFilterChangedEvent('${query}')`); }; const dispatchDateRangeMenuValueChange = (value: string) => { webRef.current?.injectJavaScript(`dispatchDateRangeMenuValueChangeEvent('${value}')`); }; const openPlaid = (openPlaidData: OpenPlaidEvent) => { const linkToken = openPlaidData.plaidLinkToken.attributes.linkToken; createPlaidLink({ token: linkToken }); openPlaidLink({ onSuccess: (success: LinkSuccess) => { injectUnitPlaidResponse(webRef.current, success); }, onExit: (exit: LinkExit) => { injectUnitPlaidExit(webRef.current, exit.error); } }); }; useEventListener({ busEventKey: UnitComponentsMessage.UNIT_REQUEST_REFRESH, action: requestRefresh }); useEventListener({ busEventKey: ActivityMessage.UNIT_ACTIVITY_FILTERS_CHANGED, action: dispatchActivityFiltersChanged, }); useEventListener({ busEventKey: BillPayBillsMessage.UNIT_BILLS_FILTERS_CHANGED, action: dispatchBillsFiltersChanged, }); useEventListener({ busEventKey: BalanceSummaryMessage.UNIT_REQUEST_DATE_RANGE_MENU_VALUE_CHANGE, action: dispatchDateRangeMenuValueChange, }); useEventListener({ busEventKey: PlaidMessage.UNIT_OPEN_PLAID, action: (details) => { openPlaid(details); }, }); useEventListener({ busEventKey: AccountMessage.UNIT_ACCOUNT_CREATION_ACTIONS_OPEN_PLAID_FOR_LINK_EXTERNAL_ACCOUNT, action: () => injectAccountCreationActionsOpenPlaidForLinkExternalAccount(webRef.current), }); useEventListener({ busEventKey: AccountMessage.UNIT_ACCOUNT_CREATED, action: () => { webRef.current?.injectJavaScript('dispatchAccountCreatedEvent()'); } }); useEventListener({ busEventKey: CardMessage.CARD_CREATED, action: (card: CardCreatedEvent) => { injectCardCreated(webRef.current, card); } }); useEventListener({ busEventKey: BillPayMenuMessage.UNIT_REQUEST_EDIT_BILL, action: (detail: RequestEditBillEvent) => injectRequestEditBill(webRef.current, detail), }); useEventListener({ busEventKey: BillPayMenuMessage.UNIT_REQUEST_CREATE_MANUAL_BILL_PAY, action: () => injectRequestCreateManualBillPay(webRef.current), }); useEventListener({ busEventKey: BillPayMenuMessage.UNIT_REQUEST_OPEN_ARCHIVED_BILLS, action: () => injectRequestOpenArchivedBills(webRef.current), }); useEventListener({ busEventKey: BillPayMenuMessage.UNIT_REQUEST_OPEN_VENDORS, action: () => injectRequestOpenVendors(webRef.current), }); useEventListener({ busEventKey: BillPayMenuMessage.UNIT_REQUEST_OPEN_PAYMENT_METHODS, action: () => injectRequestOpenPaymentMethods(webRef.current), }); useEventListener({ busEventKey: VendorFormMessage.UNIT_VENDOR_FORM_TRY_SUBMIT, action: () => injectVendorFormTrySubmit(webRef.current), }); useEventListener({ busEventKey: UnsavedChangesMessage.UNIT_BILL_PAY_UNSAVED_CHANGES_ACTION, action: (detail: UnsavedChangesActionEvent) => injectUnsavedChangesAction(webRef.current, detail), }); useEventListener({ busEventKey: BillActionsMessage.UNIT_BILL_ARCHIVED, action: (billId: string) => injectBillActionResult(webRef.current, BillActionsMessage.UNIT_BILL_ARCHIVED, billId), }); useEventListener({ busEventKey: BillActionsMessage.UNIT_BILL_MARK_AS_PAID, action: (billId: string) => injectBillActionResult(webRef.current, BillActionsMessage.UNIT_BILL_MARK_AS_PAID, billId), }); useEventListener({ busEventKey: BillActionsMessage.UNIT_BILL_MARK_AS_UNPAID, action: (billId: string) => injectBillActionResult(webRef.current, BillActionsMessage.UNIT_BILL_MARK_AS_UNPAID, billId), }); useEventListener({ busEventKey: BillActionsMessage.UNIT_BILL_RESCHEDULED, action: (billId: string) => injectBillActionResult(webRef.current, BillActionsMessage.UNIT_BILL_RESCHEDULED, billId), }); useEventListener({ busEventKey: BillActionsMessage.UNIT_BILL_CHECK_CANCELLED, action: (billId: string) => injectBillActionResult(webRef.current, BillActionsMessage.UNIT_BILL_CHECK_CANCELLED, billId), }); useEventListener({ busEventKey: BillActionsMessage.UNIT_BILL_REFUNDED, action: (billId: string) => injectBillActionResult(webRef.current, BillActionsMessage.UNIT_BILL_REFUNDED, billId), }); const renderWebView = () => { return ( ); }; return ( renderWebView() ); }; export default withReduxStore(UNWhiteLabelAppComponent);