import * as React from "react";
/**
* @typedef {Object} SignupFields
* @property {?boolean} display
* @property {string} id Ex: `signup_email`, `field_1`
* @property {string} label Field's label
* @property {string} member_type
* @property {Array<any>} options If field is a checkbox, this contains the checkbox fields
* @property {boolean} required True if field is required
* @property {string} type Ex: `email`, `checkbox`
*/
/**
* @typedef {Function} SignupFieldsFilterCallback
* @param {Array<SignupFields>} fields Old fields array
* @return {Array<SignupFields>} Changed fields array
*/
/**
* @typedef {Object} LoginButtonProps
* @property {TranslationFunction} t
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {String} stateUsername Username field state
* @property {String} statePassword Password field state
* @property {Function} doLogin Default login function
* @property {Object} auth
* @property {Object} screenProps
*/
/**
* @typedef {Object} SignupButtonProps
* @property {Boolean} disabled Returns `true` if button should be disabled
* @property {Object} global App global style
* @property {Function} doSignup Default signup function
* @property {String} label Button label
* @property {Boolean} loading Returns `true` if button is loading
* @property {Boolean} spinnerColor Returns spinner color in button
* @property {Array<Object>} visibleFields Visible fields in sign up form
* @property {Object} fieldValues Default field values. See: {@link https://react-hook-form.com/v5/api#getValues}
* @property {Object} formState Information about form state. See: {@link https://react-hook-form.com/v5/api#formState}
* @property {Function} getValues Returns entire form data. See: {@link https://react-hook-form.com/v5/api#getValues}
*/
/**
* @typedef {Object} RenderAuthInputsProps
* @property {TranslationFunction} t
* @property {String} authBg Screen background color
* @property {Object} global App global style
* @property {String} backgroundColor input wrap background color
* @property {String} textColor
* @property {Number} userIcon Default user icon
* @property {Function} setUsernameState Helper function for setting the username state
* @property {String} stateUsername Username field state
* @property {String} placeholderColor
* @property {Function} calcFontSize
* @property {Number} passwordIcon Default password icon
* @property {Function} setPasswordState Helper function for setting the password state
* @property {String} statePassword Password field state
* @property {Function} doLogin Default login function
* @property {Function} setInputRef Helper function which sets the component reference within the parent component
/**
* @typedef {Object} UserAgreementTextComponentProps
* @property {Boolean} register Returns `true` if used for registration
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {TranslationFunction} t
* @property {Object} termsOfService Terms of service data
* @property {Object} privacyPolicy Privacy policy data
* @property {Boolean} withCheckbox Returns `true` if component should have a checkbox
* @property {Function} onPress Helper function which shows the user agreement content
* @property {Function} onAgreementChecked Sets the state of `agreementChecked`
* @property {Function} agreementChecked Returns `true` if agreement is checked
*/
/**
* @typedef {Object} UserAgreementModalComponentProps
* @property {Function} calcFontSize Used to calculate font size based on the fixed value you assign and percent set on branding options
* @property {Boolean} authDarkStyle Returns `true` if component should use dark style
* @property {Object} config
* @property {String} modalContent Modal content string
* @property {String} modalHeader Modal header string
* @property {Function} onClosed Helper function which resets the modal
* @property {Function} refModal Modal reference
* @property {Function} hideModal Helper function which closes the modal
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {TranslationFunction} t
* @property {Object} termsOfService Terms of service data
* @property {Object} privacyPolicy Privacy policy data
* @property {Boolean} withCheckbox Returns `true` if component should have a checkbox
* @property {Function} onPress Helper function which shows the user agreement content
* @property {Function} onAgreementChecked Sets the state of `agreementChecked`
* @property {Function} agreementChecked Returns `true` if agreement is checked
*/
/**
* @typedef {Object} LoginLogoProps
* @property {Boolean | undefined} hideLogo Returns `true` if logo should be visible
* @property {Object} headerStyle Default style of the logo container
* @property {Object} logoStyle Default style of the logo image
* @property {Number} source Returns the image for the logo
*/
/**
* @typedef {Object} SignUpInputComponentProps
* @property {React.Component} DefaultComponent Default input component
* @property {String} label Input label
* @property {Record<any,any>} field Input details
* @property {Function} setValue Function to handle input changes to the component
* @property {Record<any,any>} theme Default style
* @property {undefined | string} initialValue Initial value of field
*/
/**
* @typedef {Object} SignUpLinkProps
* @property {Boolean} isSignUpEnabled Returns `true` if sign up is enabled
* @property {Object} footerRef Footer reference for the component
* @property {Function} onPress Calls the default sign up function
* @property {Object} styles Default style of the component
* @property {TranslationFunction} t
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {NavigationService} navigation
*/
/**
* @typedef {Object} UserAgreementTextComponentProps
* @property {Boolean} isSignUpEnabled Returns `true` if sign up is enabled
* @property {Boolean} register
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {TranslationFunction} t
* @property {Boolean} guestEnabled Returns `true` if guests are allowed to access the app
* @property {Object} termsOfService Terms of service details
* @property {privacyPolice} privacyPolice Privacy police details
* @property {Boolean} withCheckBox Returns `true` if a checkbox should be visible
* @property {Function} onPress Calls the default on press function
* @property {Function} onAgreementChecked Calls the default function when agreement is checked
* @property {Boolean} agreementChecked Returns `true` if agreement is checked
* @property {Object} style Default style of the component
* @property {NavigationService} navigation
*/
/**
* @typedef {Function} SignUpInputsValidationCallback
* @param {Function} doValidation Calls the default validation function
* @param {String} fieldName Name of the field
* @param {Object} field Field details
* @param {TranslationFunction} t
* @return {void}
*/
/**
* @class
* Authentication Hooks.
* Instance name: authApi
It enables the app to have authentication options during the signup/login process.
* @example
* externalCodeSetup.authApi.METHOD_NAME
*/
export class AuthApi {
/**
* @deprecated
* @private
*/
defaultSubsiteFilter = (defaultSubsite, subsites) => defaultSubsite;
// @deprecated
setRenderSignUpScreenAfterInputs = renderFunc => {
this.renderSignUpScreenAfterInputs = renderFunc;
};
// @deprecated
setDefaultSubsite = defaultSubsiteFilter => {
this.defaultSubsiteFilter = defaultSubsiteFilter;
};
/**
* @private
* @param {SignupFieldsFilterCallback} fields
*/
filterSignUpInputs = fields => fields;
/**
* You can use it to set the function that can filter the input fields to modify the signup process based on your app needs.
* @method
* @param {SignupFieldsFilterCallback} func
* @example <caption>Example: Remove first field in the sign up form</caption>
*
* externalCodeSetup.authApi.setSignUpInputsFilter(props => {
* props.shift()
* return props;
* })
*/
setSignUpInputsFilter = func => {
this.filterSignUpInputs = func;
};
LoginButton = null;
/**
* You can use this hook to replace the Login Button on the login screen.
* You can also use this hook to change the behavior or styling of the login button on the login screen
* @method
* @param {React.ComponentType<LoginButtonProps>} LoginButton
* @example <caption> Add an extra validation step before logging-in a user </caption>
*
* ...
*
* import {Alert} from "react-native"
* import AppButton from "@src/components/AppButton";
*
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.authApi.setLoginButton(props => {
* const {
* t,
* global,
* colors,
* doLogin,
* stateUsername,
* statePassword,
* auth
* } = props;
*
* const customLoginAction = () => {
* let isValid = false;
*
* //Call an action to do extra validation such as an OTP request...
* isValid = false;
*
* //If successful, do default app login...
* if (isValid) doLogin();
* else Alert.alert("OTP is invalid");
* };
*
* return (
* <AppButton
* accessibilityLabel="login_button"
* accessible
* style={[{marginTop: 10}, global.authButtonContainer]}
* onPress={() => customLoginAction()}
* label={t("login:login")}
* global={global}
* loading={auth.isFetching}
* labelStyle={global.authButtonLabel}
* spinnerColor={colors.authButtonTextColor}
* />
* );
* });
* }
*/
setLoginButton = LoginButton => {
this.LoginButton = LoginButton;
};
renderAuthInputs = null;
/**
* You can use this hook to modify the authentication fields on the login screen.
* For example, add a 'Phone' field along with the default email and password fields on the login screen.
* @method
* @param {React.ComponentType<RenderAuthInputsProps>} renderAuthInput
* @example <caption> Add a phone field along with username and password </caption>
*
* //In custom_code/LoginCustom.js...
*
* import React, { useEffect, useState, useRef } from 'react';
* import { Alert } from "react-native"
* import AppButton from "@src/components/AppButton";
* import TextInput from "@src/components/AppInput";
* import { getExternalCodeSetup } from '../../src/externalCode/externalRepo';
*
* const externalCodeSetup = getExternalCodeSetup();
*
* const phoneIcon = require("../assets/img/phone.png");
*
* const customLoginAction = (doLogin) => {
*
* let isValid = false;
*
* //Call an action to do extra validation such as an OTP request...
*
* isValid = true;
*
* //If successful, do default app login...
* if (isValid)
* doLogin()
* else
* Alert.alert("OTP is invalid")
* }
*
* const renderLoginButton = (phoneRef, usernameRef, passwordRef) => {
*
* externalCodeSetup.authApi.setLoginButton(props => {
* const {
* t,
* global,
* stateUsername,
* statePassword,
* isSignUpEnabled,
* privacyPolicy,
* termsOfService,
* withUserAgreementCheckbox,
* stateAgreementChecked,
* passwordInput,
* usernameInput,
* doLogin,
* auth,
* colors
* } = props;
*
* return <AppButton
* accessibilityLabel="login_button"
* accessible
* style={[{ marginTop: 10 }, global.authButtonContainer]}
* onPress={() => {
* if (!!!stateUsername || !!!statePassword) {
* return false;
* }
* if (
* !isSignUpEnabled &&
* withUserAgreementCheckbox &&
* (privacyPolicy || termsOfService) &&
* !stateAgreementChecked
* ) {
* return Alert.alert(
* t("login:user_agreement_title"),
* t(
* `login:user_agreement_message${privacyPolicy ? "_privacy" : ""
* }${termsOfService ? "_terms" : ""}`
* )
* );
* }
* phoneRef.current.clear()
* usernameRef.current.clear()
* passwordRef.current.clear()
* customLoginAction(doLogin);
* }}
* label="Get OTP"
* global={global}
* loading={auth.isFetching}
* labelStyle={global.authButtonLabel}
* spinnerColor={colors.authButtonTextColor}
* />
* });
* }
*
* const AuthInputs = props => {
* const {
* t,
* authBg,
* global,
* colors,
* backgroundColor,
* textColor,
* userIcon,
* setUsernameState,
* stateUsername,
* placeholderColor,
* calcFontSize,
* passwordIcon,
* setPasswordState,
* statePassword,
* doLogin,
* auth
* } = props;
*
* const [phone, setPhone] = useState('');
* const phoneRef = useRef(null);
* const usernameRef = useRef(null);
* const passwordRef = useRef(null);
*
* useEffect(() => {
* renderLoginButton(phoneRef, usernameRef, passwordRef);
* }, [])
*
* return <>
* <TextInput
* accessibilityLabel="login_phone_input"
* accessible
* ref={phoneRef}
* bodyColor={authBg}
* inputWrapStyle={[global.formInput, { backgroundColor }]}
* style={[
* global.formInputText,
* { color: textColor, paddingLeft: 0 }
* ]}
* keyboardType="numeric"
* icon={phoneIcon}
* webIcon={"IconUser"}
* tintColor={textColor}
* onChangeText={phone => setPhone({ phone })}
* value={phone}
* placeholderTextColor={placeholderColor}
* placeholder="Phone"
* autoCapitalize={"none"}
* returnKeyType="next"
* underlineColorAndroid="transparent"
* autoCorrect={false}
* calcFontSize={calcFontSize}
* />
* <TextInput
* accessibilityLabel="login_username_input"
* accessible
* ref={usernameRef}
* bodyColor={authBg}
* inputWrapStyle={[global.formInput, { backgroundColor }]}
* style={[
* global.formInputText,
* { color: textColor, paddingLeft: 0 }
* ]}
* icon={userIcon}
* webIcon={"IconUser"}
* tintColor={textColor}
* onChangeText={username => setUsernameState({ username })}
* value={stateUsername}
* placeholderTextColor={placeholderColor}
* placeholder={t("login:username")}
* autoCapitalize={"none"}
* returnKeyType="next"
* underlineColorAndroid="transparent"
* autoCorrect={false}
* calcFontSize={calcFontSize}
* />
*
* <TextInput
* accessibilityLabel="login_password_input"
* accessible
* bodyColor={authBg}
* inputWrapStyle={global.inputWrap}
* inputWrapStyle={[global.formInput, { backgroundColor }]}
* style={[
* global.formInputText,
* { color: textColor, width: "70%", paddingLeft: 0 }
* ]}
* ref={passwordRef}
* icon={passwordIcon}
* webIcon={"IconLock"}
* eyeTintColor={textColor}
* tintColor={textColor}
* onChangeText={password => setPasswordState({ password })}
* value={statePassword}
* placeholderTextColor={placeholderColor}
* placeholder={t("login:password")}
* secureTextEntry={true}
* secureToggle={true}
* returnKeyType={"done"}
* autoCapitalize={"none"}
* underlineColorAndroid="transparent"
* autoCorrect={false}
* onSubmitEditing={() =>
* // done key should execute action
* customLoginAction(doLogin)
* }
* calcFontSize={calcFontSize}
* />
*
* </>
*
* }
*
* export default AuthInputs;
*
* //In custom_code/index.js...
*
* import LoginCustom from "./components/LoginCustom";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.authApi.setRenderAuthInputs(props => <LoginCustom {...props} />)
* }
*
* @example <caption> Use default implementation of auth inputs in a hook </caption>
*
* export const applyCustomCode = externalCodeSetup => {
*
* externalCodeSetup.authApi.setRenderAuthInputs((props) => {
*
* const {
* t,
* authBg,
* global,
* colors,
* backgroundColor,
* textColor,
* userIcon,
* setUsernameState,
* stateUsername,
* placeholderColor,
* calcFontSize,
* passwordIcon,
* setPasswordState,
* statePassword,
* doLogin,
* setInputRef,
* auth
* } = props;
*
* let passwordRef;
*
* const setPasswordRef = (component) => {
*
* //Set password ref for LoginScreen.js
* setInputRef("password", component);
*
* //Set password ref for this component
* passwordRef = component;
* }
*
* return <>
* <TextInput
* accessibilityLabel="login_username_input"
* accessible
* ref={component => setInputRef("username", component)}
* bodyColor={authBg}
* inputWrapStyle={[global.formInput, { backgroundColor }]}
* style={[
* global.formInputText,
* { color: textColor, paddingLeft: 0 }
* ]}
* tabIndex={1}
* icon={userIcon}
* webIcon={"IconUser"}
* tintColor={textColor}
* onChangeText={username => setUsernameState({ username })}
* value={stateUsername}
* placeholderTextColor={placeholderColor}
* placeholder={t("login:username")}
* autoCapitalize={"none"}
* returnKeyType="next"
* underlineColorAndroid="transparent"
* autoCorrect={false}
* onSubmitEditing={() => {
* // next key should focus on next input by default
* passwordRef.focus()
* }}
* calcFontSize={calcFontSize}
* />
*
* <TextInput
* accessibilityLabel="login_password_input"
* accessible
* bodyColor={authBg}
* inputWrapStyle={global.inputWrap}
* inputWrapStyle={[global.formInput, { backgroundColor }]}
* style={[
* global.formInputText,
* { color: textColor, width: "70%", paddingLeft: 0 }
* ]}
* ref={component => setPasswordRef(component) }
* tabIndex={2}
* icon={passwordIcon}
* webIcon={"IconLock"}
* eyeTintColor={textColor}
* tintColor={textColor}
* onChangeText={password => setPasswordState({ password })}
* value={statePassword}
* placeholderTextColor={placeholderColor}
* placeholder={t("login:password")}
* secureTextEntry={true}
* secureToggle={true}
* returnKeyType={"done"}
* autoCapitalize={"none"}
* underlineColorAndroid="transparent"
* autoCorrect={false}
* onSubmitEditing={() =>
* // done key should execute action
* doLogin()
* }
* calcFontSize={calcFontSize}
* />
* </>
* })
* }
*/
setRenderAuthInputs = renderFunc => {
this.renderAuthInputs = renderFunc;
};
SignupButton = null;
/**
* You can use this hook to replace the Signup Button on the Signup screen.
* You can also use this hook to change the behavior or styling of the signup button on the login screen.
* @method
* @param {React.ComponentType<SignupButtonProps>} SignupButton
* @example
*
* ...
*
* import { Alert } from "react-native"
* import AppButton from "@src/components/AppButton";
* export const applyCustomCode = externalCodeSetup => {
*
* externalCodeSetup.authApi.setSignupButton(props => {
*
* const {
* disabled,
* global,
* doSignup,
* label,
* loading,
* spinnerColor,
* visibleFields,
* profileType,
* fieldValues,
* formState,
* getValues
* } = props;
*
* const signupAction = () => {
* Alert.alert("OTP", `We will send an OTP to ${getValues.field_1}. Do you want to proceed?`, [
* {
* text: "Cancel",
* onPress: () => console.log("Cancel Pressed"),
* style: "cancel"
* },
* { text: "OK", onPress: () => console.log("OK Pressed") }
* ])
* }
*
* return <AppButton
* disabled={disabled}
* style={[{ marginTop: 17 }, global.regButtonContainer]}
* // onPress={doSignup}
* onPress={signupAction}
* label={label}
* global={global}
* loading={loading}
* labelStyle={[
* global.buttonLabel,
* global.regButtonLabel,
* disabled && { opacity: 0.4 }
* ]}
* spinnerColor={spinnerColor}
* />
* });
*
* }
*
*/
setSignupButton = SignupButton => {
this.SignupButton = SignupButton;
};
UserAgreementTextComponent = null;
/**
* You can use this hook to customize the User Agreement text component located before the "Create Account" button.
* @method
* @param {React.ComponentType<UserAgreementTextComponentProps>} UserAgreementTextComponent
* @example <caption> Add an alert confirmation if the user has read the Terms of Service </caption>
*
* //In custom_code/components/UserAgreementText.js...
*
* import React from "react";
* import {Text, View, Alert} from "react-native";
* import AppCheckbox from "@src/components/AppCheckbox";
* import {Check} from "@src/components/AppCheckbox";
* import {getAuthFormTheme, getRegFormTheme} from "@src/components/Forms/utils";
*
* const confirmAgreement = (onAgreementChecked) => {
*
* Alert.alert(
* "Confirmation",
* "Have you read the Terms of Service?",
* [
* {
* text: "No",
* onPress: () => onAgreementChecked(false),
* },
* { text: "Yes", onPress: () => onAgreementChecked(true) }
* ]
* );
*
* }
*
* const UserAgreementText = props => {
* const {
* register,
* t,
* termsOfService,
* privacyPolicy,
* withCheckbox,
* global,
* colors,
* onPress,
* agreementChecked,
* onAgreementChecked,
* style = {}
* } = props;
*
* if (!termsOfService?.content && !privacyPolicy?.content) return null;
*
* const theme = register ? getRegFormTheme(colors) : getAuthFormTheme(colors);
* const {tint, inactiveTint, textColor, labelColor} = theme;
*
* const tColor = withCheckbox ? textColor : labelColor;
*
* const containerStyle = withCheckbox && {
* borderRadius: 10,
* backgroundColor: theme.backgroundColor,
* paddingVertical: 14,
* paddingHorizontal: 16,
* marginBottom: 15,
* ...style
* };
*
* return (
* <View
* style={[
* global.row,
* {alignItems: "center", justifyContent: "center"},
* containerStyle
* ]}
* >
* <Text
* style={[
* global.text,
* {
* textAlign: withCheckbox ? "left" : "center",
* marginTop: withCheckbox ? 0 : 16,
* paddingRight: 4,
* paddingLeft: withCheckbox ? 0 : 4,
* color: tColor,
* flex: 1
* },
* withCheckbox && {
* marginRight: 5
* }
* ]}
* >
* {withCheckbox ? t(`signup:agreementStartingTextWithCheckbox`) : null}
* {!!termsOfService?.content ? (
* <Text
* style={[global.boldText, {color: tColor}]}
* onPress={() =>
* onPress("termsOfService", termsOfService.content.rendered)
* }
* >
* {t("signup:termsOfService")}
* </Text>
* ) : (
* ""
* )}
* {!!termsOfService?.content && privacyPolicy?.content
* ? t("signup:and")
* : ""}
* {!!privacyPolicy?.content ? (
* <Text
* style={[global.boldText, {color: tColor}]}
* onPress={() =>
* onPress("privacyPolicy", privacyPolicy.content.rendered)
* }
* >
* {t("signup:privacyPolicy")}
* </Text>
* ) : (
* ""
* )}
* {withCheckbox ? t("signup:agreementEndingText") : null}
* </Text>
* {withCheckbox && (
* <Check
* inactiveTint={inactiveTint}
* tintColor={tint}
* isChecked={agreementChecked}
* onPress={() => confirmAgreement(onAgreementChecked)}
* // onPress={() => onAgreementChecked(!agreementChecked)}
* />
* )}
* </View>
* );
* };
*
* export default UserAgreementText;
*
* //In custom_code/index.js...
*
* import UserAgreementText from "./components/UserAgreementText";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.authApi.setUserAgreementTextComponent(props => <UserAgreementText {...props} />);
* }
*
*/
setUserAgreementTextComponent = UserAgreementTextComponent => {
this.UserAgreementTextComponent = UserAgreementTextComponent;
};
UserAgreementModalComponent = null;
/**
* You can use this hook to customize the User Agreement modal.
* For example, you can add a checkbox at the bottom of the modal which will require users to scroll to the bottom to agree to the Terms of Service.
* @param {React.ComponentType<UserAgreementModalComponentProps>} UserAgreementModalComponent
* @example <caption> Use default BB implementation and add the User Agreement Text inside the modal </caption>
*
* //In custom_code/components/UserAgreementModal.js...
*
* import React from "react";
* import { View, Text, Platform } from "react-native";
* import { wrapHtml } from "@src/utils";
* import { DEVICE_HEIGHT, globalStyle } from "@src/styles/global";
* import ScrollableModal from "@src/components/Modals/ScrollableModal";
* import BottomSheetCloseButton from "@src/components/BottomSheet/BottomSheetCloseButton";
* import ContentPlaceholder from "@src/components/ContentPlaceholder";
* import ResizingWebView from "@src/components/ResizingWebView";
* import { generateAssetsFontCss } from "@src/utils/jsUtils";
* import { UserAgreementText } from "@src/components/Auth/UserAgreementText";
*
* const UserAgreementModal = (props) => {
* const {
* config,
* onClosed,
* modalContent,
* modalHeader,
* hideModal,
* refModal,
* colors,
* global,
* t,
* termsOfService,
* privacyPolicy,
* onPress,
* onAgreementChecked,
* agreementChecked,
* } = props;
*
* const {
* htmlAdjustedCss,
* htmlContentCss,
* htmlStylesCss,
* typography,
* headerStyle
* } = globalStyle(config.styles);
*
* const renderModalHeader = () => (
* <View
* style={[
* global.row,
* global.panelHeader,
* headerStyle,
* { borderColor: colors.borderColor, borderBottomWidth: 0.5 }
* ]}
* >
* {!!modalHeader && <Text style={global.filterTitle}>{modalHeader}</Text>}
*
* <BottomSheetCloseButton onClose={hideModal} colors={colors} />
* </View>
* );
*
* return (
* <ScrollableModal
* ref={refModal}
* onClosed={onClosed}
* HeaderComponent={renderModalHeader(global, colors)}
* adjustToContentHeight={false}
* scrollViewProps={{ backgroundColor: colors.bodyFrontBg }}
* >
* <View style={{flex: 1, padding: 20, borderRadius: 12}}>
* <UserAgreementText
* {...{
* register: true,
* colors,
* global,
* t,
* termsOfService,
* privacyPolicy,
* withCheckbox: true,
* onPress,
* onAgreementChecked,
* agreementChecked
* }}
* />
* <ResizingWebView
* defaultHeight={DEVICE_HEIGHT}
* width={"100%"}
* startInLoadingState={true}
* scrollEnabled={Platform.OS === "android"}
* webViewStyle={Platform.OS === "android" ? { marginBottom: 150 } : {}}
* nestedScrollEnabled
* autoHeight={Platform.OS === "ios"}
* fixAndroid={true}
* contentId={"userAgreementContent"}
* source={{
* html: wrapHtml(
* String(htmlStylesCss).replace(";overflow: hidden", "") +
* htmlAdjustedCss +
* htmlContentCss +
* generateAssetsFontCss(
* typography.bodyText.family,
* typography.bodyText.type
* )
* )(modalContent)
* }}
* renderLoading={() => (
* <View
* style={{
* position: "absolute",
* top: 0,
* left: 0,
* bottom: 0,
* right: 0,
* zIndex: 1
* }}
* >
* <ContentPlaceholder global={global} base={colors.headingsColor} />
* </View>
* )}
* />
* </View>
* </ScrollableModal>
* );
* };
*
* export default UserAgreementModal;
*
* //In custom_code/index.js...
*
* ...
*
* import UserAgreeementModal from "./components/UserAgreementModal"
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.authApi.setUserAgreementModalComponent(props => <UserAgreeementModal {...props} />)
* }
*/
setUserAgreementModalComponent = UserAgreementModalComponent => {
this.UserAgreementModalComponent = UserAgreementModalComponent;
};
LoginLogo = null;
/**
* You can use this hook to replace the logo in the Login Screen.
* For example, you can change the logo's image, dimensions, or position.
* @method
* @param {React.ComponentType<LoginLogoProps>} LoginLogo
* @example
*
* ...
*
* import AppImage from "@src/components/AppImage";
* export const applyCustomCode = (externalCodeSetup: ExternalCodeSetup) => {
*
* externalCodeSetup.authApi.setLoginLogo(({
* hideLogo,
* headerStyle,
* logoStyle,
* source
* }) => {
*
* return !hideLogo && (
* <View style={headerStyle}>
* <AppImage
* id="logo"
* resizeMode={"contain"}
* style={logoStyle}
* source={source}
* />
* </View>
* )
* })
* }
*
*/
setLoginLogo = LoginLogo => {
this.LoginLogo = LoginLogo;
};
SignUpInputComponent = null;
/**
* You can use this hook to replace input components in the sign-up form.
* @method
* @param {React.ComponentType<SignUpInputComponentProps>} SignUpInputComponent
* @example
*
* //In custom_code/index.js...
* ...
*
* import MyTextInput from "./components/MyTextInput";
*
* export const applyCustomCode = (externalCodeSetup: any) => {
*
* externalCodeSetup.authApi.setSignUpInputComponent(props => {
* const {DefaultComponent, label} = props;
*
* if (label === "Email") {
* return <MyTextInput {...props}/>
* }
*
* return DefaultComponent;
* });
* }
*
*
* //In custom_code/components/MyTextInput.js...
*
* import React, {useState} from "react";
* import {View, TextInput, ActivityIndicator, Text} from "react-native";
* import axios from "axios";
* const MyTextInput = props => {
* const [loading, setLoading] = useState(false);
* const [data, setData] = useState(null);
*
* const fetchData = async text => {
* const search = text && text.toLowerCase();
*
* try {
* setLoading(true);
* const response = await axios.get(`https://example.api/${search}`);
* setData(response.data);
* setLoading(false);
* } catch (error) {
* console.error(error);
* }
* };
*
* const handleTextChange = text => {
* fetchData(text);
* props.setValue(props.field.id, text);
* };
*
* return (
* <View>
* <TextInput
* onChangeText={handleTextChange}
* placeholder="Type something..."
* />
* {loading && <ActivityIndicator />}
* {data && (
* <Text>
* Result: {data.name} | {data.abilities[0].ability.name}
* </Text>
* )}
* </View>
* );
* };
*
* export default MyTextInput;
*
*/
setSignUpInputComponent = SignUpInputComponent => {
this.SignUpInputComponent = SignUpInputComponent;
};
signUpInputsValidation = null;
/**
* You can use this hook to set the validation rules for the sign-up form.
* For example, you can exempt a field so that it will not be required when submitting the form.
* @method
* @param {SignUpInputsValidationCallback} SignUpInputsValidationCallback
* @example
*
* authApi.setSignUpInputsValidation(props => {
* const {doValidation, fieldName, field, register, t} = props;
*
* const changeLabel = false;
* const exemptField = false;
*
* if (changeLabel) {
* return register(fieldName, {
* required:
* field.required &&
* field.required &&
* `Custom - ${field.label}` + t("signup:validateFeildModal"),
* validate: value => {
* const {message} = getFieldError(field, value, t);
* return message ?? true;
* }
* });
* }
*
* if (exemptField) {
* if (fieldName === "signup_email") {
* return;
* }
* }
*
* return doValidation()
* });
*
*/
setSignUpInputsValidation = (validation, fieldName, field, t) => {
this.signUpInputsValidation = validation;
};
SignUpLink = null;
/**
* You can use this hook to replace the sign up link component in the Login Screen.
* @method
* @param {React.ComponentType<SignUpLinkProps>} SignUpLinkProps
* @example
*
*
* import React from "react";
* import {View, Text} from "react-native";
* import Icon from "@src/components/Icon";
* import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
*
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.authApi.setSignUpLink(props => {
* const {isSignUpEnabled, footerRef, onPress, styles, t, colors} = props;
*
* return (
* isSignUpEnabled && (
* <AppTouchableOpacity
* ref={footerRef}
* onPress={onPress}
* style={styles.buttonContainer}
* hitSlop={{top: 15, right: 15, bottom: 15, left: 15}}
* >
* <View style={styles.viewContainer}>
* <Text style={styles.text}>
* <Text>{t("login:haveAccount")}</Text>
* <Text> </Text>
* <Text style={styles.signUpText}>{t("login:signup")}</Text>
* </Text>
* <Icon
* icon={{fontIconName: "arrow-right", weight: 300}}
* webIcon={"IconArrowBack"}
* tintColor={colors.authTextColor}
* styles={{height: 15}}
* />
* </View>
* </AppTouchableOpacity>
* )
* );
* });
* };
*
*/
setSignUpLink = SignUpLink => {
this.SignUpLink = SignUpLink;
};
UserAgreementTextComponent = null;
/**
* You can use this hook to replace the "Terms of Service and Privacy Policy" component in the Login Screen.
* @method
* @param {React.ComponentType<UserAgreementTextComponentProps>} UserAgreementTextComponentProps
* @example
* import React from "react";
* import {UserAgreementText} from "@src/components/Auth/UserAgreementText";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.authApi.setUserAgreementTextComponent(props => {
* const {
* isSignUpEnabled,
* register,
* colors,
* global,
* t,
* guestEnabled,
* termsOfService,
* privacyPolicy,
* withCheckbox,
* onPress,
* onAgreementChecked,
* agreementChecked,
* style,
* navigation
* } = props;
*
* return (
* !isSignUpEnabled && (
* <UserAgreementText
* {...{
* register,
* colors,
* global,
* t,
* guestEnabled,
* termsOfService,
* privacyPolicy,
* withCheckbox,
* onPress,
* onAgreementChecked,
* agreementChecked,
* style
* }}
* />
* )
* );
* });
* }
*
*/
setUserAgreementTextComponent = UserAgreementTextComponent => {
this.UserAgreementTextComponent = UserAgreementTextComponent;
};
}
Source