@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
JavaScript
'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 };