diff --git a/packages/mobile/src/common/constants/constants.ts b/packages/mobile/src/common/constants/constants.ts index 473700644..a832d130c 100644 --- a/packages/mobile/src/common/constants/constants.ts +++ b/packages/mobile/src/common/constants/constants.ts @@ -26,4 +26,3 @@ export { CHANEL_NAME, } from './push'; export { MINIMUM_SLIDER_PRICE, MAXIMUM_SLIDER_PRICE } from './slider-price'; -export { CONDITION } from './products'; diff --git a/packages/mobile/src/common/constants/products.ts b/packages/mobile/src/common/constants/products.ts deleted file mode 100644 index c7dbf82e2..000000000 --- a/packages/mobile/src/common/constants/products.ts +++ /dev/null @@ -1,9 +0,0 @@ -import i18next from 'i18next'; -import { Condition } from '@vse-bude/shared'; - -const CONDITION = [ - { label: i18next.t('make_a_post.NEW'), value: Condition.NEW }, - { label: i18next.t('make_a_post.USED'), value: Condition.USED }, -]; - -export { CONDITION }; diff --git a/packages/mobile/src/helpers/products/get-conditions/get-conditions.ts b/packages/mobile/src/helpers/products/get-conditions/get-conditions.ts new file mode 100644 index 000000000..dd7510c59 --- /dev/null +++ b/packages/mobile/src/helpers/products/get-conditions/get-conditions.ts @@ -0,0 +1,13 @@ +import { TFunction } from 'i18next'; +import { Condition } from '@vse-bude/shared'; + +type ConditionType = Record[]; + +const getConditions = (t: TFunction): ConditionType => { + return [ + { label: t('make_a_post.NEW'), value: Condition.NEW }, + { label: t('make_a_post.USED'), value: Condition.USED }, + ]; +}; + +export { getConditions }; diff --git a/packages/mobile/src/helpers/products/products.ts b/packages/mobile/src/helpers/products/products.ts index f82758066..3d9009f9b 100644 --- a/packages/mobile/src/helpers/products/products.ts +++ b/packages/mobile/src/helpers/products/products.ts @@ -2,3 +2,5 @@ export { makeAuctionParser, makePostParser, } from './make-post-parse/make-post-parse'; + +export { getConditions } from './get-conditions/get-conditions'; diff --git a/packages/mobile/src/localization/languages/en/screens.ts b/packages/mobile/src/localization/languages/en/screens.ts index f822c86a9..b16ba7f81 100644 --- a/packages/mobile/src/localization/languages/en/screens.ts +++ b/packages/mobile/src/localization/languages/en/screens.ts @@ -209,8 +209,8 @@ export const screens = { FACEBOOK: 'Facebook', FACEBOOK_PLACEHOLDER: 'Enter your nickname', SITE: 'Site', - NEW: 'New', - USED: 'Used', + NEW: 'new', + USED: 'used', SAVE_AS_DRAFT_BUTTON: 'Save as draft', MAKE_POST_BUTTON: 'Make a post', MAKE_AUCTION_BUTTON: 'Create auction', diff --git a/packages/mobile/src/localization/languages/ua/screens.ts b/packages/mobile/src/localization/languages/ua/screens.ts index a895c5b15..5f553e38d 100644 --- a/packages/mobile/src/localization/languages/ua/screens.ts +++ b/packages/mobile/src/localization/languages/ua/screens.ts @@ -208,8 +208,8 @@ export const screens = { FACEBOOK: 'Facebook', FACEBOOK_PLACEHOLDER: 'Введіть URL', SITE: 'Введіть URL', - NEW: 'Новий', - USED: 'Був у використанні', + NEW: 'новий', + USED: 'уживаний', SAVE_AS_DRAFT_BUTTON: 'Зберегти як чернетку', MAKE_POST_BUTTON: 'Створити публікацію', MAKE_AUCTION_BUTTON: 'Створити аукціон', diff --git a/packages/mobile/src/navigation/tabs/tabs.navigation.tsx b/packages/mobile/src/navigation/tabs/tabs.navigation.tsx index cc3c0c23b..385035120 100644 --- a/packages/mobile/src/navigation/tabs/tabs.navigation.tsx +++ b/packages/mobile/src/navigation/tabs/tabs.navigation.tsx @@ -165,6 +165,7 @@ const MainNavigation: FC = () => { options={{ tabBarLabel: renderTabBarLabel(t('common:tab_navigation.LOG_IN')), tabBarIcon: LogInIcon, + unmountOnBlur: true, }} /> )} diff --git a/packages/mobile/src/screens/auth/components/reset-password/reset-password.tsx b/packages/mobile/src/screens/auth/components/reset-password/reset-password.tsx index 08d663e5d..f0f0e8114 100644 --- a/packages/mobile/src/screens/auth/components/reset-password/reset-password.tsx +++ b/packages/mobile/src/screens/auth/components/reset-password/reset-password.tsx @@ -1,6 +1,6 @@ import React, { FC } from 'react'; import { useAppForm, useTranslation, useState } from '~/hooks/hooks'; -import { resetPassword } from '~/validation-schemas/validation-schemas'; +import { getResetPasswordSchema } from '~/validation-schemas/validation-schemas'; import { ResetPasswordLink } from '@vse-bude/shared'; import { View, @@ -21,7 +21,7 @@ const ResetPassword: FC = ({ onSubmit }) => { const { t } = useTranslation(); const { control, errors, handleSubmit } = useAppForm({ defaultValues: DEFAULT_RESET_PASSWORD_PAYLOAD, - validationSchema: resetPassword, + validationSchema: getResetPasswordSchema(t), }); return ( diff --git a/packages/mobile/src/screens/auth/components/sign-in-form/sign-in-form.tsx b/packages/mobile/src/screens/auth/components/sign-in-form/sign-in-form.tsx index d807a3fb0..7ba09f9f3 100644 --- a/packages/mobile/src/screens/auth/components/sign-in-form/sign-in-form.tsx +++ b/packages/mobile/src/screens/auth/components/sign-in-form/sign-in-form.tsx @@ -14,7 +14,7 @@ import { useNavigation, useAppSelector, } from '~/hooks/hooks'; -import { signIn } from '~/validation-schemas/validation-schemas'; +import { getSignInSchema } from '~/validation-schemas/validation-schemas'; import { globalStyles } from '~/styles/styles'; import { DataStatus, RootScreenName } from '~/common/enums/enums'; import { RootNavigationProps } from '~/common/types/types'; @@ -26,13 +26,13 @@ type Props = { }; const SignInForm: FC = ({ onSubmit }) => { + const { t } = useTranslation(); const dataStatusAuth = useAppSelector(selectAuthDataStatus); const isLoading = dataStatusAuth === DataStatus.PENDING; const { control, errors, handleSubmit } = useAppForm({ defaultValues: DEFAULT_SIGN_IN_PAYLOAD, - validationSchema: signIn, + validationSchema: getSignInSchema(t), }); - const { t } = useTranslation(); const { navigate } = useNavigation(); const navigateResetPassword = () => { diff --git a/packages/mobile/src/screens/auth/components/sign-up-form/sign-up-form.tsx b/packages/mobile/src/screens/auth/components/sign-up-form/sign-up-form.tsx index ad8179684..5e2b1b4c6 100644 --- a/packages/mobile/src/screens/auth/components/sign-up-form/sign-up-form.tsx +++ b/packages/mobile/src/screens/auth/components/sign-up-form/sign-up-form.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { UserSignUpDto } from '@vse-bude/shared'; import { View, Input, PrimaryButton } from '~/components/components'; import { useAppForm, useTranslation, useAppSelector } from '~/hooks/hooks'; -import { signUp } from '~/validation-schemas/validation-schemas'; +import { getSignUpSchema } from '~/validation-schemas/validation-schemas'; import { globalStyles } from '~/styles/styles'; import { selectAuthDataStatus } from '~/store/selectors'; import { DataStatus } from '~/common/enums/enums'; @@ -18,7 +18,7 @@ const SignUpForm: React.FC = ({ onSubmit }) => { const isLoading = dataStatusAuth === DataStatus.PENDING; const { control, errors, handleSubmit } = useAppForm({ defaultValues: DEFAULT_SIGN_UP_PAYLOAD, - validationSchema: signUp, + validationSchema: getSignUpSchema(t), }); return ( diff --git a/packages/mobile/src/screens/new-item/components/new-auction-form/new-auction-form.tsx b/packages/mobile/src/screens/new-item/components/new-auction-form/new-auction-form.tsx index ac6f09bf2..2e9254d64 100644 --- a/packages/mobile/src/screens/new-item/components/new-auction-form/new-auction-form.tsx +++ b/packages/mobile/src/screens/new-item/components/new-auction-form/new-auction-form.tsx @@ -31,10 +31,13 @@ import { ButtonAppearance, DateTimeType } from '~/common/enums/ui/ui'; import { ButtonsContainer } from '~/screens/components/components'; import { selectCategories, selectDataStatusProducts } from '~/store/selectors'; import { DataStatus } from '~/common/enums/enums'; -import { productsAuctionSchema } from '~/validation-schemas/validation-schemas'; +import { getProductsAuctionSchema } from '~/validation-schemas/validation-schemas'; import { notification } from '~/services/services'; -import { categoryForDropdown, makeAuctionParser } from '~/helpers/helpers'; -import { CONDITION } from '~/common/constants/products'; +import { + categoryForDropdown, + getConditions, + makeAuctionParser, +} from '~/helpers/helpers'; import { AddPhotos } from '../add-photos/add-photos'; import { useStyles } from './styles'; @@ -74,9 +77,10 @@ const NewAuctionForm: FC = ({ personalInfo }) => { city: personalInfo.userAddress?.city || '', phone: personalInfo.phone?.replace(/\s/g, '').slice(4) || '', }, - validationSchema: productsAuctionSchema, + validationSchema: getProductsAuctionSchema(t), }); const [images, setImages] = useState([]); + const conditions = getConditions(t); useEffect(() => { if (Object.keys(errors).length > 0) { @@ -202,7 +206,7 @@ const NewAuctionForm: FC = ({ personalInfo }) => { name="condition" errors={errors} control={control} - items={CONDITION} + items={conditions} zIndex={19} required={true} /> diff --git a/packages/mobile/src/screens/new-item/components/new-item-form/new-item-form.tsx b/packages/mobile/src/screens/new-item/components/new-item-form/new-item-form.tsx index 9b80bdf60..aaefa46af 100644 --- a/packages/mobile/src/screens/new-item/components/new-item-form/new-item-form.tsx +++ b/packages/mobile/src/screens/new-item/components/new-item-form/new-item-form.tsx @@ -30,10 +30,9 @@ import { categoryForDropdown } from '~/helpers/category/format-category-for-drop import { ButtonsContainer } from '~/screens/components/components'; import { ButtonAppearance, DataStatus } from '~/common/enums/enums'; import { selectCategories, selectDataStatusProducts } from '~/store/selectors'; -import { productsPostSchema } from '~/validation-schemas/validation-schemas'; +import { getProductsPostSchema } from '~/validation-schemas/validation-schemas'; import { notification } from '~/services/services'; -import { makePostParser } from '~/helpers/helpers'; -import { CONDITION } from '~/common/constants/products'; +import { getConditions, makePostParser } from '~/helpers/helpers'; import { AddPhotos } from '../add-photos/add-photos'; import { useStyles } from './styles'; @@ -68,10 +67,11 @@ const NewItemForm: FC = ({ personalInfo }) => { city: personalInfo.userAddress?.city || '', phone: personalInfo.phone?.replace(/\s/g, '').slice(4) || '', }, - validationSchema: productsPostSchema, + validationSchema: getProductsPostSchema(t), }); const [images, setImages] = useState([]); + const conditions = getConditions(t); useEffect(() => { if (Object.keys(errors).length > 0) { @@ -197,7 +197,7 @@ const NewItemForm: FC = ({ personalInfo }) => { name="condition" errors={errors} control={control} - items={CONDITION} + items={conditions} zIndex={19} required={true} /> diff --git a/packages/mobile/src/screens/personal-info/components/personal-info-form/personal-info-form.tsx b/packages/mobile/src/screens/personal-info/components/personal-info-form/personal-info-form.tsx index e58af70ca..3d443bb42 100644 --- a/packages/mobile/src/screens/personal-info/components/personal-info-form/personal-info-form.tsx +++ b/packages/mobile/src/screens/personal-info/components/personal-info-form/personal-info-form.tsx @@ -22,7 +22,7 @@ import { selectAuthDataStatus, } from '~/store/selectors'; import { personalInfoActions, auth as authActions } from '~/store/actions'; -import { personalInfoSchema } from '~/validation-schemas/validation-schemas'; +import { getPersonalInfoSchema } from '~/validation-schemas/validation-schemas'; import { notification } from '~/services/services'; import { personalInfoParser, @@ -68,7 +68,7 @@ const PersonalInfoForm: React.FC = ({ personalInfo }) => { const { control, errors, handleSubmit, reset } = useAppForm({ defaultValues: DEFAULT_VALUES, - validationSchema: personalInfoSchema, + validationSchema: getPersonalInfoSchema(t), }); const { isDirty } = useFormState({ control }); diff --git a/packages/mobile/src/screens/product-info/components/price-block/lot-price-block.tsx b/packages/mobile/src/screens/product-info/components/price-block/lot-price-block.tsx index 5839e95b0..4c53a6641 100644 --- a/packages/mobile/src/screens/product-info/components/price-block/lot-price-block.tsx +++ b/packages/mobile/src/screens/product-info/components/price-block/lot-price-block.tsx @@ -53,7 +53,7 @@ const LotPriceBlock: FC = ({ const dispatch = useAppDispatch(); const { control, errors, handleSubmit, setValue } = useAppForm({ defaultValues: DEFAULT_BID_VALUE, - validationSchema: getBidValidationSchema(Number(minimalBid)), + validationSchema: getBidValidationSchema(Number(minimalBid), t), }); const { isAbleToLeaveAuction } = useAppSelector(selectPermission); const user = useAppSelector(selectCurrentUser); diff --git a/packages/mobile/src/screens/verify-screens/verify-code-email/verify-code-email.tsx b/packages/mobile/src/screens/verify-screens/verify-code-email/verify-code-email.tsx index 4cf5e6d03..f326d9c68 100644 --- a/packages/mobile/src/screens/verify-screens/verify-code-email/verify-code-email.tsx +++ b/packages/mobile/src/screens/verify-screens/verify-code-email/verify-code-email.tsx @@ -32,7 +32,7 @@ import { selectUserEmail, } from '~/store/selectors'; import { notification } from '~/services/services'; -import { codeSchema } from '~/validation-schemas/validation-schemas'; +import { getCodeSchema } from '~/validation-schemas/validation-schemas'; import { ButtonsContainer, Header } from '~/screens/components/components'; import { VERIFICATION_CODE_REGEX } from '~/common/regexp/regexp'; import { @@ -59,7 +59,7 @@ const VerifyCodeEmailScreen: FC = ({ route }) => { defaultValues: { code: '', }, - validationSchema: codeSchema, + validationSchema: getCodeSchema(t), }); const [isCorrectCode, setIsCorrectCode] = useState(false); diff --git a/packages/mobile/src/screens/verify-screens/verify-code-phone/verify-code-phone.tsx b/packages/mobile/src/screens/verify-screens/verify-code-phone/verify-code-phone.tsx index 1f8909663..8a0ff26cc 100644 --- a/packages/mobile/src/screens/verify-screens/verify-code-phone/verify-code-phone.tsx +++ b/packages/mobile/src/screens/verify-screens/verify-code-phone/verify-code-phone.tsx @@ -32,7 +32,7 @@ import { selectUserPhone, } from '~/store/selectors'; import { notification } from '~/services/services'; -import { codeSchema } from '~/validation-schemas/validation-schemas'; +import { getCodeSchema } from '~/validation-schemas/validation-schemas'; import { ButtonsContainer, Header } from '~/screens/components/components'; import { VERIFICATION_CODE_REGEX } from '~/common/regexp/regexp'; import { @@ -59,7 +59,7 @@ const VerifyCodePhoneScreen: FC = ({ route }) => { defaultValues: { code: '', }, - validationSchema: codeSchema, + validationSchema: getCodeSchema(t), }); const [isCorrectCode, setIsCorrectCode] = useState(false); diff --git a/packages/mobile/src/screens/verify-screens/verify-phone/verify-phone.tsx b/packages/mobile/src/screens/verify-screens/verify-phone/verify-phone.tsx index 494871d4c..927d0bcd9 100644 --- a/packages/mobile/src/screens/verify-screens/verify-phone/verify-phone.tsx +++ b/packages/mobile/src/screens/verify-screens/verify-phone/verify-phone.tsx @@ -26,7 +26,7 @@ import { } from '~/components/components'; import { verifyActions } from '~/store/actions'; import { images } from '~/assets/images/images'; -import { phone } from '~/validation-schemas/validation-schemas'; +import { getPhoneSchema } from '~/validation-schemas/validation-schemas'; import { globalStyles } from '~/styles/styles'; import { selectVerifyDataStatus, selectUserPhone } from '~/store/selectors'; import { notification } from '~/services/services'; @@ -52,7 +52,7 @@ const VerifyPhoneScreen: FC = ({ route }) => { defaultValues: { phone: userPhone, }, - validationSchema: phone, + validationSchema: getPhoneSchema(t), }); const handleBackButtonPress = (): void => { diff --git a/packages/mobile/src/validation-schemas/bid/make-bid.ts b/packages/mobile/src/validation-schemas/bid/make-bid.ts index a92d87527..e2f215119 100644 --- a/packages/mobile/src/validation-schemas/bid/make-bid.ts +++ b/packages/mobile/src/validation-schemas/bid/make-bid.ts @@ -1,13 +1,13 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; -const getBidValidationSchema = (minimalBid: number) => +const getBidValidationSchema = (minimalBid: number, t: TFunction) => Joi.object({ bid: Joi.number() .min(minimalBid) .messages({ - 'number.min': i18next.t('common:errors.LOW_BID'), - 'number.base': i18next.t('common:errors.INVALID_BID'), + 'number.min': t('common:errors.LOW_BID'), + 'number.base': t('common:errors.INVALID_BID'), }), }); diff --git a/packages/mobile/src/validation-schemas/code/code.ts b/packages/mobile/src/validation-schemas/code/code.ts index f51507b71..9d32f25c6 100644 --- a/packages/mobile/src/validation-schemas/code/code.ts +++ b/packages/mobile/src/validation-schemas/code/code.ts @@ -1,17 +1,19 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { PhoneVerifyDto } from '@vse-bude/shared'; import { VERIFICATION_CODE_REGEX } from '~/common/regexp/regexp'; -const codeSchema = Joi.object({ - code: Joi.string() - .pattern(VERIFICATION_CODE_REGEX) - .trim() - .required() - .messages({ - 'string.pattern.base': i18next.t('errors.WRONG_FORMAT'), - 'string.empty': i18next.t('errors.EMPTY_CODE'), - }), -}); +const getCodeSchema = (t: TFunction): Joi.ObjectSchema => { + return Joi.object({ + code: Joi.string() + .pattern(VERIFICATION_CODE_REGEX) + .trim() + .required() + .messages({ + 'string.pattern.base': t('errors.WRONG_FORMAT'), + 'string.empty': t('errors.EMPTY_CODE'), + }), + }); +}; -export { codeSchema }; +export { getCodeSchema }; diff --git a/packages/mobile/src/validation-schemas/helpers/email-validator.ts b/packages/mobile/src/validation-schemas/helpers/email-validator.ts index d811e8c53..e26221c97 100644 --- a/packages/mobile/src/validation-schemas/helpers/email-validator.ts +++ b/packages/mobile/src/validation-schemas/helpers/email-validator.ts @@ -1,17 +1,18 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { EMAIL_REGEX } from '~/common/regexp/regexp'; -const emailValidator = (value: string, helpers: Joi.CustomHelpers) => { - if (value.match(/[а-яА-Я]/)) { - return helpers.message({ custom: i18next.t('errors.LATIN') }); - } +const emailValidator = + (t: TFunction) => (value: string, helpers: Joi.CustomHelpers) => { + if (value.match(/[а-яА-Я]/)) { + return helpers.message({ custom: t('errors.LATIN') }); + } - if (!value.match(EMAIL_REGEX)) { - return helpers.message({ custom: i18next.t('errors.INVALID_EMAIL') }); - } + if (!value.match(EMAIL_REGEX)) { + return helpers.message({ custom: t('errors.INVALID_EMAIL') }); + } - return value; -}; + return value; + }; export { emailValidator }; diff --git a/packages/mobile/src/validation-schemas/helpers/name-validator.ts b/packages/mobile/src/validation-schemas/helpers/name-validator.ts index 30cfc3b76..1e75efc05 100644 --- a/packages/mobile/src/validation-schemas/helpers/name-validator.ts +++ b/packages/mobile/src/validation-schemas/helpers/name-validator.ts @@ -1,34 +1,35 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { SPECIAL_SYMBOLS_REGEX } from '~/common/regexp/regexp'; const nameValidator = - (prefix: string) => (value: string, helpers: Joi.CustomHelpers) => { + (prefix: string, t: TFunction) => + (value: string, helpers: Joi.CustomHelpers) => { if (value.length < 1) { return helpers.message({ - custom: i18next.t('errors.MIN_NAME_LENGTH', { - name: i18next.t('words.' + prefix), + custom: t('errors.MIN_NAME_LENGTH', { + name: t('words.' + prefix), }), }); } if (value.length > 40) { return helpers.message({ - custom: i18next.t('errors.MIN_NAME_LENGTH', { - name: i18next.t('words.' + prefix), + custom: t('errors.MIN_NAME_LENGTH', { + name: t('words.' + prefix), }), }); } if (value.match(SPECIAL_SYMBOLS_REGEX)) { return helpers.message({ - custom: i18next.t(`errors.${prefix}_INVALID`), + custom: t(`errors.${prefix}_INVALID`), }); } if (value.match(/^-|-$/)) { return helpers.message({ - custom: i18next.t(`errors.${prefix}_INVALID`), + custom: t(`errors.${prefix}_INVALID`), }); } diff --git a/packages/mobile/src/validation-schemas/helpers/password-validator.ts b/packages/mobile/src/validation-schemas/helpers/password-validator.ts index 7caaef71e..46c87a2b6 100644 --- a/packages/mobile/src/validation-schemas/helpers/password-validator.ts +++ b/packages/mobile/src/validation-schemas/helpers/password-validator.ts @@ -1,47 +1,48 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { MAX_PASSWORD_LENGTH, MIN_PASSWORD_LENGTH, } from '~/common/constants/constants'; import { PASSWORD_REGEX } from '~/common/regexp/regexp'; -const passwordValidator = (value: string, helpers: Joi.CustomHelpers) => { - const hasUppercase = value.match(/[A-Z]/); - const hasLowercases = value.match(/[a-z]/); - const hasNumber = value.match(/[0-9]/); - - if (value.match(/[а-яА-Я]/)) { - return helpers.message({ custom: i18next.t('errors.LATIN') }); - } - - if (value.match(/\s/)) { - return helpers.message({ custom: i18next.t('errors.SPACES') }); - } - - if (value.length < MIN_PASSWORD_LENGTH) { - return helpers.message({ - custom: i18next.t('errors.MIN_PASSWORD_LENGTH'), - }); - } - - if (value.length > MAX_PASSWORD_LENGTH) { - return helpers.message({ - custom: i18next.t('errors.MAX_PASSWORD_LENGTH'), - }); - } - - if (!hasUppercase || !hasLowercases || !hasNumber) { - return helpers.message({ - custom: i18next.t('errors.UP_LOW_NUM'), - }); - } - - if (!value.match(PASSWORD_REGEX)) { - return helpers.message({ custom: i18next.t('errors.INVALID_PASSWORD') }); - } - - return value; -}; +const passwordValidator = + (t: TFunction) => (value: string, helpers: Joi.CustomHelpers) => { + const hasUppercase = value.match(/[A-Z]/); + const hasLowercases = value.match(/[a-z]/); + const hasNumber = value.match(/[0-9]/); + + if (value.match(/[а-яА-Я]/)) { + return helpers.message({ custom: t('errors.LATIN') }); + } + + if (value.match(/\s/)) { + return helpers.message({ custom: t('errors.SPACES') }); + } + + if (value.length < MIN_PASSWORD_LENGTH) { + return helpers.message({ + custom: t('errors.MIN_PASSWORD_LENGTH'), + }); + } + + if (value.length > MAX_PASSWORD_LENGTH) { + return helpers.message({ + custom: t('errors.MAX_PASSWORD_LENGTH'), + }); + } + + if (!hasUppercase || !hasLowercases || !hasNumber) { + return helpers.message({ + custom: t('errors.UP_LOW_NUM'), + }); + } + + if (!value.match(PASSWORD_REGEX)) { + return helpers.message({ custom: t('errors.INVALID_PASSWORD') }); + } + + return value; + }; export { passwordValidator }; diff --git a/packages/mobile/src/validation-schemas/personal-info/personal-info.ts b/packages/mobile/src/validation-schemas/personal-info/personal-info.ts index 66b005009..dc9e5c813 100644 --- a/packages/mobile/src/validation-schemas/personal-info/personal-info.ts +++ b/packages/mobile/src/validation-schemas/personal-info/personal-info.ts @@ -1,5 +1,5 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { PLACE, SaveUserProfileDto, ZIP } from '@vse-bude/shared'; import { SHORT_PHONE_NUMBER_REGEX } from '~/common/regexp/regexp'; import { @@ -15,104 +15,108 @@ import { passwordValidator, } from '../helpers/helpers'; -const personalInfoSchema = Joi.object({ - email: Joi.string() - .trim() - .custom(emailValidator) - .email({ tlds: { allow: false } }) - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_EMAIL'), - }), - firstName: Joi.string() - .trim() - .custom(nameValidator('FIRST_NAME')) - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_FIRST_NAME'), - }), - lastName: Joi.string() - .trim() - .custom(nameValidator('LAST_NAME')) - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_LAST_NAME'), - }), - phone: Joi.string() - .trim() - .empty('') - .pattern(SHORT_PHONE_NUMBER_REGEX) - .messages({ - 'string.pattern.base': i18next.t('errors.WRONG_FORMAT_PHONE'), - }), - country: Joi.string() - .empty('') - .max(MAX_COUNTRY_LENGTH) - .pattern(PLACE) - .messages({ - 'string.max': i18next.t('errors.MAX_COUNTRY_LENGTH'), - 'string.pattern.base': i18next.t('errors.PLACE_NAME'), - }), - region: Joi.string() - .empty('') - .max(MAX_REGION_LENGTH) - .pattern(PLACE) - .messages({ - 'string.max': i18next.t('errors.MAX_REGION_LENGTH'), - 'string.pattern.base': i18next.t('errors.PLACE_NAME'), - }), - city: Joi.string() - .empty('') - .max(MAX_CITY_LENGTH) - .pattern(PLACE) - .messages({ - 'string.max': i18next.t('errors.MAX_CITY_LENGTH'), - 'string.pattern.base': i18next.t('errors.PLACE_NAME'), - }), - zip: Joi.string() - .empty('') - .pattern(ZIP) - .messages({ - 'string.pattern.base': i18next.t('errors.INVALID_ZIP'), - }), - deliveryData: Joi.string() - .empty('') - .max(MAX_DELIVERY_DATA_LENGTH) - .messages({ - 'string.max': i18next.t('errors.MAX_DELIVERY_DATA_LENGTH'), - }), - instagram: Joi.string() - .empty('') - .uri() - .max(MAX_SOCIAL_NETWORK_LENGTH) - .messages({ - 'string.uri': i18next.t('errors.INVALID_URI'), - 'string.max': i18next.t('errors.MAX_SOCIAL_NETWORK_LENGTH'), - }), - linkedin: Joi.string() - .empty('') - .uri() - .max(MAX_SOCIAL_NETWORK_LENGTH) - .messages({ - 'string.uri': i18next.t('errors.INVALID_URI'), - 'string.max': i18next.t('errors.MAX_SOCIAL_NETWORK_LENGTH'), - }), - facebook: Joi.string() - .empty('') - .uri() - .max(MAX_SOCIAL_NETWORK_LENGTH) - .messages({ - 'string.uri': i18next.t('errors.INVALID_URI'), - 'string.max': i18next.t('errors.MAX_SOCIAL_NETWORK_LENGTH'), - }), - password: Joi.string().empty(''), - newPassword: Joi.string().empty('').custom(passwordValidator).trim(), - repeatPassword: Joi.string() - .empty('') - .valid(Joi.ref('newPassword')) - .messages({ - 'any.only': i18next.t('errors.REPEAT_PASSWORD_INVALID'), - }), -}); +const getPersonalInfoSchema = ( + t: TFunction, +): Joi.ObjectSchema => { + return Joi.object({ + email: Joi.string() + .trim() + .custom(emailValidator(t)) + .email({ tlds: { allow: false } }) + .required() + .messages({ + 'string.empty': t('errors.EMPTY_EMAIL'), + }), + firstName: Joi.string() + .trim() + .custom(nameValidator('FIRST_NAME', t)) + .required() + .messages({ + 'string.empty': t('errors.EMPTY_FIRST_NAME'), + }), + lastName: Joi.string() + .trim() + .custom(nameValidator('LAST_NAME', t)) + .required() + .messages({ + 'string.empty': t('errors.EMPTY_LAST_NAME'), + }), + phone: Joi.string() + .trim() + .empty('') + .pattern(SHORT_PHONE_NUMBER_REGEX) + .messages({ + 'string.pattern.base': t('errors.WRONG_FORMAT_PHONE'), + }), + country: Joi.string() + .empty('') + .max(MAX_COUNTRY_LENGTH) + .pattern(PLACE) + .messages({ + 'string.max': t('errors.MAX_COUNTRY_LENGTH'), + 'string.pattern.base': t('errors.PLACE_NAME'), + }), + region: Joi.string() + .empty('') + .max(MAX_REGION_LENGTH) + .pattern(PLACE) + .messages({ + 'string.max': t('errors.MAX_REGION_LENGTH'), + 'string.pattern.base': t('errors.PLACE_NAME'), + }), + city: Joi.string() + .empty('') + .max(MAX_CITY_LENGTH) + .pattern(PLACE) + .messages({ + 'string.max': t('errors.MAX_CITY_LENGTH'), + 'string.pattern.base': t('errors.PLACE_NAME'), + }), + zip: Joi.string() + .empty('') + .pattern(ZIP) + .messages({ + 'string.pattern.base': t('errors.INVALID_ZIP'), + }), + deliveryData: Joi.string() + .empty('') + .max(MAX_DELIVERY_DATA_LENGTH) + .messages({ + 'string.max': t('errors.MAX_DELIVERY_DATA_LENGTH'), + }), + instagram: Joi.string() + .empty('') + .uri() + .max(MAX_SOCIAL_NETWORK_LENGTH) + .messages({ + 'string.uri': t('errors.INVALID_URI'), + 'string.max': t('errors.MAX_SOCIAL_NETWORK_LENGTH'), + }), + linkedin: Joi.string() + .empty('') + .uri() + .max(MAX_SOCIAL_NETWORK_LENGTH) + .messages({ + 'string.uri': t('errors.INVALID_URI'), + 'string.max': t('errors.MAX_SOCIAL_NETWORK_LENGTH'), + }), + facebook: Joi.string() + .empty('') + .uri() + .max(MAX_SOCIAL_NETWORK_LENGTH) + .messages({ + 'string.uri': t('errors.INVALID_URI'), + 'string.max': t('errors.MAX_SOCIAL_NETWORK_LENGTH'), + }), + password: Joi.string().empty(''), + newPassword: Joi.string().empty('').custom(passwordValidator).trim(), + repeatPassword: Joi.string() + .empty('') + .valid(Joi.ref('newPassword')) + .messages({ + 'any.only': t('errors.REPEAT_PASSWORD_INVALID'), + }), + }); +}; -export { personalInfoSchema }; +export { getPersonalInfoSchema }; diff --git a/packages/mobile/src/validation-schemas/phone/phone.ts b/packages/mobile/src/validation-schemas/phone/phone.ts index 506958d03..59bbd6719 100644 --- a/packages/mobile/src/validation-schemas/phone/phone.ts +++ b/packages/mobile/src/validation-schemas/phone/phone.ts @@ -1,17 +1,21 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { PHONE_NUMBER_REGEX } from '~/common/regexp/regexp'; import { VerifyPhoneRequestDto } from '~/common/types/types'; -const phone = Joi.object({ - phone: Joi.string() - .trim() - .pattern(PHONE_NUMBER_REGEX) - .required() - .messages({ - 'string.pattern.base': i18next.t('errors.WRONG_FORMAT'), - 'string.empty': i18next.t('errors.EMPTY_PHONE'), - }), -}); +const getPhoneSchema = ( + t: TFunction, +): Joi.ObjectSchema => { + return Joi.object({ + phone: Joi.string() + .trim() + .pattern(PHONE_NUMBER_REGEX) + .required() + .messages({ + 'string.pattern.base': t('errors.WRONG_FORMAT'), + 'string.empty': t('errors.EMPTY_PHONE'), + }), + }); +}; -export { phone }; +export { getPhoneSchema }; diff --git a/packages/mobile/src/validation-schemas/products/products-auction.ts b/packages/mobile/src/validation-schemas/products/products-auction.ts index ff47f67f0..cf0ebf1e0 100644 --- a/packages/mobile/src/validation-schemas/products/products-auction.ts +++ b/packages/mobile/src/validation-schemas/products/products-auction.ts @@ -1,5 +1,5 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { ICreateAuction, PLACE } from '@vse-bude/shared'; import { SHORT_PHONE_NUMBER_REGEX } from '~/common/regexp/regexp'; import { @@ -11,77 +11,81 @@ import { MIN_BID, } from '~/common/constants/constants'; -const productsAuctionSchema = Joi.object({ - category: Joi.string().empty(''), - title: Joi.string() - .trim() - .required() - .max(MAX_TITLE_POST_LENGTH) - .messages({ - 'string.max': i18next.t('errors.MAX_TITLE_POST_LENGTH'), - 'string.empty': i18next.t('errors.EMPTY_PRODUCT'), - }), - description: Joi.string() - .trim() - .required() - .max(MAX_DESCRIPTION_POST_LENGTH) - .messages({ - 'string.max': i18next.t('errors.MAX_DESCRIPTION_POST_LENGTH'), - 'string.empty': i18next.t('errors.EMPTY_DESCRIPTION'), - }), - condition: Joi.string() - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_CONDITION'), - }), - recommendedPriceCurrency: Joi.any().empty(''), - recommendedPrice: Joi.number() - .min(MIN_PRICE) - .messages({ - 'number.base': i18next.t('errors.NUMBER_PRICE'), - 'number.min': i18next.t('errors.MIN_PRICE'), - }), - minimalBidCurrency: Joi.any().empty(''), - minimalBid: Joi.number() - .min(MIN_BID) - .messages({ - 'number.base': i18next.t('errors.NUMBER_BID'), - 'number.min': i18next.t('errors.MIN_BID'), - }), - endDate: Joi.date() - .iso() - .required() - .messages({ - 'date.format': i18next.t('errors.EMPTY_DATE'), - 'string.empty': i18next.t('errors.EMPTY_DATE'), - 'any.required': i18next.t('errors.EMPTY_DATE'), - }), - phone: Joi.string() - .trim() - .empty('') - .pattern(SHORT_PHONE_NUMBER_REGEX) - .messages({ - 'string.pattern.base': i18next.t('errors.WRONG_FORMAT_PHONE'), - }), - country: Joi.string() - .trim() - .required() - .max(MAX_COUNTRY_LENGTH) - .pattern(PLACE) - .messages({ - 'string.empty': i18next.t('errors.EMPTY_COUNTRY'), - 'string.max': i18next.t('errors.MAX_COUNTRY_LENGTH'), - 'string.pattern.base': i18next.t('errors.PLACE_NAME'), - }), - city: Joi.string() - .trim() - .empty('') - .max(MAX_CITY_LENGTH) - .pattern(PLACE) - .messages({ - 'string.max': i18next.t('errors.MAX_CITY_LENGTH'), - 'string.pattern.base': i18next.t('errors.PLACE_NAME'), - }), -}); +const getProductsAuctionSchema = ( + t: TFunction, +): Joi.ObjectSchema => { + return Joi.object({ + category: Joi.string().empty(''), + title: Joi.string() + .trim() + .required() + .max(MAX_TITLE_POST_LENGTH) + .messages({ + 'string.max': t('errors.MAX_TITLE_POST_LENGTH'), + 'string.empty': t('errors.EMPTY_PRODUCT'), + }), + description: Joi.string() + .trim() + .required() + .max(MAX_DESCRIPTION_POST_LENGTH) + .messages({ + 'string.max': t('errors.MAX_DESCRIPTION_POST_LENGTH'), + 'string.empty': t('errors.EMPTY_DESCRIPTION'), + }), + condition: Joi.string() + .required() + .messages({ + 'string.empty': t('errors.EMPTY_CONDITION'), + }), + recommendedPriceCurrency: Joi.any().empty(''), + recommendedPrice: Joi.number() + .min(MIN_PRICE) + .messages({ + 'number.base': t('errors.NUMBER_PRICE'), + 'number.min': t('errors.MIN_PRICE'), + }), + minimalBidCurrency: Joi.any().empty(''), + minimalBid: Joi.number() + .min(MIN_BID) + .messages({ + 'number.base': t('errors.NUMBER_BID'), + 'number.min': t('errors.MIN_BID'), + }), + endDate: Joi.date() + .iso() + .required() + .messages({ + 'date.format': t('errors.EMPTY_DATE'), + 'string.empty': t('errors.EMPTY_DATE'), + 'any.required': t('errors.EMPTY_DATE'), + }), + phone: Joi.string() + .trim() + .empty('') + .pattern(SHORT_PHONE_NUMBER_REGEX) + .messages({ + 'string.pattern.base': t('errors.WRONG_FORMAT_PHONE'), + }), + country: Joi.string() + .trim() + .required() + .max(MAX_COUNTRY_LENGTH) + .pattern(PLACE) + .messages({ + 'string.empty': t('errors.EMPTY_COUNTRY'), + 'string.max': t('errors.MAX_COUNTRY_LENGTH'), + 'string.pattern.base': t('errors.PLACE_NAME'), + }), + city: Joi.string() + .trim() + .empty('') + .max(MAX_CITY_LENGTH) + .pattern(PLACE) + .messages({ + 'string.max': t('errors.MAX_CITY_LENGTH'), + 'string.pattern.base': t('errors.PLACE_NAME'), + }), + }); +}; -export { productsAuctionSchema }; +export { getProductsAuctionSchema }; diff --git a/packages/mobile/src/validation-schemas/products/products-post.ts b/packages/mobile/src/validation-schemas/products/products-post.ts index 16540223e..4721bc930 100644 --- a/packages/mobile/src/validation-schemas/products/products-post.ts +++ b/packages/mobile/src/validation-schemas/products/products-post.ts @@ -1,5 +1,5 @@ import * as Joi from 'joi'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { IPostForms, PLACE } from '@vse-bude/shared'; import { SHORT_PHONE_NUMBER_REGEX } from '~/common/regexp/regexp'; import { @@ -10,62 +10,64 @@ import { MIN_PRICE, } from '~/common/constants/constants'; -const productsPostSchema = Joi.object({ - category: Joi.string().empty(''), - title: Joi.string() - .trim() - .required() - .max(MAX_TITLE_POST_LENGTH) - .messages({ - 'string.max': i18next.t('errors.MAX_TITLE_POST_LENGTH'), - 'string.empty': i18next.t('errors.EMPTY_PRODUCT'), - }), - description: Joi.string() - .trim() - .required() - .max(MAX_DESCRIPTION_POST_LENGTH) - .messages({ - 'string.max': i18next.t('errors.MAX_DESCRIPTION_POST_LENGTH'), - 'string.empty': i18next.t('errors.EMPTY_DESCRIPTION'), - }), - condition: Joi.string() - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_CONDITION'), - }), - currency: Joi.any().empty(''), - price: Joi.number() - .min(MIN_PRICE) - .messages({ - 'number.base': i18next.t('errors.NUMBER_PRICE'), - 'number.min': i18next.t('errors.MIN_PRICE'), - }), - phone: Joi.string() - .trim() - .empty('') - .pattern(SHORT_PHONE_NUMBER_REGEX) - .messages({ - 'string.pattern.base': i18next.t('errors.WRONG_FORMAT_PHONE'), - }), - country: Joi.string() - .trim() - .required() - .max(MAX_COUNTRY_LENGTH) - .pattern(PLACE) - .messages({ - 'string.empty': i18next.t('errors.EMPTY_COUNTRY'), - 'string.max': i18next.t('errors.MAX_COUNTRY_LENGTH'), - 'string.pattern.base': i18next.t('errors.PLACE_NAME'), - }), - city: Joi.string() - .trim() - .empty('') - .max(MAX_CITY_LENGTH) - .pattern(PLACE) - .messages({ - 'string.max': i18next.t('errors.MAX_CITY_LENGTH'), - 'string.pattern.base': i18next.t('errors.PLACE_NAME'), - }), -}); +const getProductsPostSchema = (t: TFunction): Joi.ObjectSchema => { + return Joi.object({ + category: Joi.string().empty(''), + title: Joi.string() + .trim() + .required() + .max(MAX_TITLE_POST_LENGTH) + .messages({ + 'string.max': t('errors.MAX_TITLE_POST_LENGTH'), + 'string.empty': t('errors.EMPTY_PRODUCT'), + }), + description: Joi.string() + .trim() + .required() + .max(MAX_DESCRIPTION_POST_LENGTH) + .messages({ + 'string.max': t('errors.MAX_DESCRIPTION_POST_LENGTH'), + 'string.empty': t('errors.EMPTY_DESCRIPTION'), + }), + condition: Joi.string() + .required() + .messages({ + 'string.empty': t('errors.EMPTY_CONDITION'), + }), + currency: Joi.any().empty(''), + price: Joi.number() + .min(MIN_PRICE) + .messages({ + 'number.base': t('errors.NUMBER_PRICE'), + 'number.min': t('errors.MIN_PRICE'), + }), + phone: Joi.string() + .trim() + .empty('') + .pattern(SHORT_PHONE_NUMBER_REGEX) + .messages({ + 'string.pattern.base': t('errors.WRONG_FORMAT_PHONE'), + }), + country: Joi.string() + .trim() + .required() + .max(MAX_COUNTRY_LENGTH) + .pattern(PLACE) + .messages({ + 'string.empty': t('errors.EMPTY_COUNTRY'), + 'string.max': t('errors.MAX_COUNTRY_LENGTH'), + 'string.pattern.base': t('errors.PLACE_NAME'), + }), + city: Joi.string() + .trim() + .empty('') + .max(MAX_CITY_LENGTH) + .pattern(PLACE) + .messages({ + 'string.max': t('errors.MAX_CITY_LENGTH'), + 'string.pattern.base': t('errors.PLACE_NAME'), + }), + }); +}; -export { productsPostSchema }; +export { getProductsPostSchema }; diff --git a/packages/mobile/src/validation-schemas/products/products.ts b/packages/mobile/src/validation-schemas/products/products.ts index 40a16f937..a9f543388 100644 --- a/packages/mobile/src/validation-schemas/products/products.ts +++ b/packages/mobile/src/validation-schemas/products/products.ts @@ -1,2 +1,2 @@ -export { productsAuctionSchema } from './products-auction'; -export { productsPostSchema } from './products-post'; +export { getProductsAuctionSchema } from './products-auction'; +export { getProductsPostSchema } from './products-post'; diff --git a/packages/mobile/src/validation-schemas/user/reset-password.ts b/packages/mobile/src/validation-schemas/user/reset-password.ts index 6e9df769e..5917a41cb 100644 --- a/packages/mobile/src/validation-schemas/user/reset-password.ts +++ b/packages/mobile/src/validation-schemas/user/reset-password.ts @@ -1,16 +1,20 @@ import * as Joi from 'joi'; import { ResetPasswordLink } from '@vse-bude/shared'; -import { t } from 'i18next'; +import { TFunction } from 'i18next'; -const resetPassword = Joi.object({ - email: Joi.string() - .trim() - .email({ tlds: { allow: false } }) - .required() - .messages({ - 'string.email': t('errors.INVALID_EMAIL'), - 'string.empty': t('errors.EMPTY_EMAIL'), - }), -}); +const getResetPasswordSchema = ( + t: TFunction, +): Joi.ObjectSchema => { + return Joi.object({ + email: Joi.string() + .trim() + .email({ tlds: { allow: false } }) + .required() + .messages({ + 'string.email': t('errors.INVALID_EMAIL'), + 'string.empty': t('errors.EMPTY_EMAIL'), + }), + }); +}; -export { resetPassword }; +export { getResetPasswordSchema }; diff --git a/packages/mobile/src/validation-schemas/user/sign-in.ts b/packages/mobile/src/validation-schemas/user/sign-in.ts index 22724547a..6d8123782 100644 --- a/packages/mobile/src/validation-schemas/user/sign-in.ts +++ b/packages/mobile/src/validation-schemas/user/sign-in.ts @@ -1,22 +1,24 @@ import * as Joi from 'joi'; import { UserSignInDto } from '@vse-bude/shared'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; -const signIn = Joi.object({ - email: Joi.string() - .trim() - .email({ tlds: { allow: false } }) - .required() - .messages({ - 'string.email': i18next.t('errors.WRONG_EMAIL'), - 'string.empty': i18next.t('errors.EMPTY_EMAIL'), - }), - password: Joi.string() - .trim() - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_PASSWORD'), - }), -}); +const getSignInSchema = (t: TFunction): Joi.ObjectSchema => { + return Joi.object({ + email: Joi.string() + .trim() + .email({ tlds: { allow: false } }) + .required() + .messages({ + 'string.email': t('errors.WRONG_EMAIL'), + 'string.empty': t('errors.EMPTY_EMAIL'), + }), + password: Joi.string() + .trim() + .required() + .messages({ + 'string.empty': t('errors.EMPTY_PASSWORD'), + }), + }); +}; -export { signIn }; +export { getSignInSchema }; diff --git a/packages/mobile/src/validation-schemas/user/sign-up.ts b/packages/mobile/src/validation-schemas/user/sign-up.ts index e262d0a2e..c038ed519 100644 --- a/packages/mobile/src/validation-schemas/user/sign-up.ts +++ b/packages/mobile/src/validation-schemas/user/sign-up.ts @@ -1,6 +1,6 @@ import * as Joi from 'joi'; import { UserSignUpDto } from '@vse-bude/shared'; -import i18next from 'i18next'; +import { TFunction } from 'i18next'; import { SHORT_PHONE_NUMBER_REGEX } from '~/common/regexp/regexp'; import { emailValidator, @@ -8,50 +8,52 @@ import { passwordValidator, } from '../helpers/helpers'; -const signUp = Joi.object({ - email: Joi.string() - .trim() - .custom(emailValidator) - .email({ tlds: { allow: false } }) - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_EMAIL'), - }), - firstName: Joi.string() - .trim() - .custom(nameValidator('FIRST_NAME')) - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_FIRST_NAME'), - }), - lastName: Joi.string() - .trim() - .custom(nameValidator('LAST_NAME')) - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_LAST_NAME'), - }), - phone: Joi.string() - .trim() - .empty('') - .pattern(SHORT_PHONE_NUMBER_REGEX) - .messages({ - 'string.pattern.base': i18next.t('errors.WRONG_FORMAT_PHONE'), - }), - password: Joi.string() - .custom(passwordValidator) - .trim() - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_PASSWORD'), - }), - repeatPassword: Joi.string() - .valid(Joi.ref('password')) - .required() - .messages({ - 'string.empty': i18next.t('errors.EMPTY_PASSWORD'), - 'any.only': i18next.t('errors.REPEAT_PASSWORD_INVALID'), - }), -}); +const getSignUpSchema = (t: TFunction): Joi.ObjectSchema => { + return Joi.object({ + email: Joi.string() + .trim() + .custom(emailValidator(t)) + .email({ tlds: { allow: false } }) + .required() + .messages({ + 'string.empty': t('errors.EMPTY_EMAIL'), + }), + firstName: Joi.string() + .trim() + .custom(nameValidator('FIRST_NAME', t)) + .required() + .messages({ + 'string.empty': t('errors.EMPTY_FIRST_NAME'), + }), + lastName: Joi.string() + .trim() + .custom(nameValidator('LAST_NAME', t)) + .required() + .messages({ + 'string.empty': t('errors.EMPTY_LAST_NAME'), + }), + phone: Joi.string() + .trim() + .empty('') + .pattern(SHORT_PHONE_NUMBER_REGEX) + .messages({ + 'string.pattern.base': t('errors.WRONG_FORMAT_PHONE'), + }), + password: Joi.string() + .custom(passwordValidator) + .trim() + .required() + .messages({ + 'string.empty': t('errors.EMPTY_PASSWORD'), + }), + repeatPassword: Joi.string() + .valid(Joi.ref('password')) + .required() + .messages({ + 'string.empty': t('errors.EMPTY_PASSWORD'), + 'any.only': t('errors.REPEAT_PASSWORD_INVALID'), + }), + }); +}; -export { signUp }; +export { getSignUpSchema }; diff --git a/packages/mobile/src/validation-schemas/user/user.ts b/packages/mobile/src/validation-schemas/user/user.ts index 148201e69..912f6064a 100644 --- a/packages/mobile/src/validation-schemas/user/user.ts +++ b/packages/mobile/src/validation-schemas/user/user.ts @@ -1,3 +1,3 @@ -export { signUp } from './sign-up'; -export { signIn } from './sign-in'; -export { resetPassword } from './reset-password'; +export { getSignUpSchema } from './sign-up'; +export { getSignInSchema } from './sign-in'; +export { getResetPasswordSchema } from './reset-password'; diff --git a/packages/mobile/src/validation-schemas/validation-schemas.ts b/packages/mobile/src/validation-schemas/validation-schemas.ts index abef2a739..9393f1453 100644 --- a/packages/mobile/src/validation-schemas/validation-schemas.ts +++ b/packages/mobile/src/validation-schemas/validation-schemas.ts @@ -1,5 +1,12 @@ -export { signUp, signIn, resetPassword } from './user/user'; -export { personalInfoSchema } from './personal-info/personal-info'; -export { phone } from './phone/phone'; -export { codeSchema } from './code/code'; -export { productsAuctionSchema, productsPostSchema } from './products/products'; +export { + getSignUpSchema, + getSignInSchema, + getResetPasswordSchema, +} from './user/user'; +export { getPersonalInfoSchema } from './personal-info/personal-info'; +export { getPhoneSchema } from './phone/phone'; +export { getCodeSchema } from './code/code'; +export { + getProductsAuctionSchema, + getProductsPostSchema, +} from './products/products';