UNPKG

@dynamic-labs/sdk-react-core

Version:

A React SDK for implementing wallet web3 authentication and authorization to your website.

166 lines (163 loc) 8.3 kB
'use client' import { __awaiter } from '../../../../../_virtual/_tslib.js'; import { useState, useMemo, useCallback } from 'react'; import { object } from 'yup'; import { KycFieldType, CustomFieldType } from '@dynamic-labs/sdk-api-core'; import { DynamicError, EmailAlreadyExistsError, CustomFieldNotUniqueError, TooManyEmailVerificationsError, UsernameAlreadyExistsError, InvalidPhoneNumberError } from '@dynamic-labs/utils'; import { useMockContext } from '../../../context/MockContext/MockContext.js'; import { logger } from '../../../shared/logger.js'; import '@dynamic-labs/iconic'; import '@dynamic-labs/wallet-connector-core'; import 'react/jsx-runtime'; import '../../../context/ViewContext/ViewContext.js'; import '@dynamic-labs/wallet-book'; import { getValueByKey } from '../../../shared/utils/functions/getValueByKey/index.js'; import '../../constants/colors.js'; import '../../constants/values.js'; import { countryCodes, tShirtSizes, teamNames } from '../../../shared/consts/index.js'; import { useFields, customFieldValidationMap } from '../../../views/CollectUserDataView/useFields.js'; // Hook that returns the prepared data to work with the formik // In order to update or display user information const useUserDataForm = ({ onSubmit, onError, userProfile, shouldEnforcePolicies = true, fields, }) => { var _a; const { mockedSDK } = useMockContext(); const [fetch, setFetch] = useState(false); const { fieldsConfig } = useFields(); const enforcePolicies = shouldEnforcePolicies && ((_a = fields.find((setting) => setting.name === 'policiesConsent')) === null || _a === void 0 ? void 0 : _a.enabled); const requiredTitleCase = (name) => `${name.charAt(0).toUpperCase() + name.slice(1)} is required`; const formikValidationSchema = useMemo(() => object().shape(Object.fromEntries(fields.map(({ name, required, type, validationType, validationRules }) => { let schema = type === KycFieldType.Custom ? getValueByKey(customFieldValidationMap, validationType) : getValueByKey(fieldsConfig, name).validation; if (type === KycFieldType.Custom && validationRules && (validationType === CustomFieldType.Select || validationType === CustomFieldType.Text)) { schema = schema; if (validationRules.validOptions) { schema = schema.oneOf(validationRules.validOptions.map((option) => option.label), 'Select a valid option'); } else if (validationRules.regex) { schema = schema.matches(new RegExp(validationRules.regex), 'Invalid field format'); } } return [ name, required ? schema.required(requiredTitleCase(name)) : schema, ]; }))), [fields]); const formikInitialValues = useMemo(() => Object.fromEntries(fields.map(({ name, type, validationRules, validationType }) => { var _a, _b, _c, _d; const info = (userProfile !== null && userProfile !== void 0 ? userProfile : {}); if (type === KycFieldType.Custom) { let defaultValue = ''; if (validationType === CustomFieldType.Select && (validationRules === null || validationRules === void 0 ? void 0 : validationRules.validOptions)) defaultValue = (_a = validationRules.validOptions[0].label) !== null && _a !== void 0 ? _a : ''; return [ name, (() => { var _a; const value = info.metadata ? getValueByKey(info.metadata, name) : undefined; return Array.isArray(value) ? value : (_a = value === null || value === void 0 ? void 0 : value.toString()) !== null && _a !== void 0 ? _a : defaultValue; })(), ]; } const mapNameToDefaultValue = { country: countryCodes[0].code, policiesConsent: false, tShirtSize: tShirtSizes[0], team: teamNames[0], }; const defaultValue = (_b = mapNameToDefaultValue[name]) !== null && _b !== void 0 ? _b : ''; return [name, (_d = (_c = getValueByKey(info, name)) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : defaultValue]; })) || {}, [fields, userProfile]); const onFormSubmit = useCallback((values, formikHelper) => __awaiter(void 0, void 0, void 0, function* () { const metadata = {}; const uniqueMetadata = {}; if (mockedSDK) return; try { if (!(userProfile === null || userProfile === void 0 ? void 0 : userProfile.environmentId)) throw new DynamicError('Invalid environment ID'); setFetch(true); let updatedUserFields = values; // all kyc fields including custom are in the object, move custom fields to the object.metadata Object.entries(updatedUserFields).forEach(([fieldName, fieldValue]) => { const field = fields.find((f) => f.name === fieldName && f.type === KycFieldType.Custom); if (field) { metadata[fieldName] = fieldValue; delete updatedUserFields[fieldName]; if (field.unique) uniqueMetadata[fieldName] = fieldValue; } }); if (Object.keys(metadata).length > 0) updatedUserFields.metadata = metadata; if (enforcePolicies) { updatedUserFields = Object.assign(Object.assign({}, updatedUserFields), { policiesConsent: true }); delete updatedUserFields.policiesConsentArray; } yield (onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(updatedUserFields)); } catch (e) { logger.error(e); onError === null || onError === void 0 ? void 0 : onError(e); if (e instanceof EmailAlreadyExistsError) { formikHelper.setErrors({ email: 'Email already exists' }); } else if (e instanceof CustomFieldNotUniqueError) { // clear all non error fields because user has to edit them anyways for the validation to pass, not sure why formikHelper.setFormikState((state) => (Object.assign(Object.assign({}, state), { errors: Object.fromEntries(Object.entries(uniqueMetadata).map(([customFieldName]) => [ customFieldName, Object.entries(uniqueMetadata).length > 1 ? 'One or more fields are already tied to another user' : `${customFieldName} is already tied to another user`, ])), touched: Object.fromEntries(Object.entries(uniqueMetadata).map(([fieldName]) => [ fieldName, true, ])), values: Object.assign(Object.assign({}, formikInitialValues), uniqueMetadata) }))); } else if (e instanceof TooManyEmailVerificationsError) { formikHelper.setErrors({ email: 'Too many email verification attempts.', }); } else if (e instanceof UsernameAlreadyExistsError) { formikHelper.setErrors({ username: 'Username already exists' }); } else if (e instanceof InvalidPhoneNumberError) { formikHelper.setErrors({ phoneNumber: e.message }); } else { formikHelper.setErrors({ api: 'Something went wrong. Please try again.', }); } } finally { setFetch(false); } }), [ mockedSDK, userProfile === null || userProfile === void 0 ? void 0 : userProfile.environmentId, enforcePolicies, onSubmit, fields, onError, formikInitialValues, ]); return { enforcePolicies, fetch, formikInitialValues, formikValidationSchema, onFormSubmit, }; }; export { useUserDataForm };