From c927aeee930a85feb35517bfda4d08ffd4c5a961 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Fri, 8 Apr 2022 15:21:40 +0800 Subject: [PATCH] feat(ui): impelment signin methods links component (#504) implement signin methods link component --- packages/phrases/src/locales/en.ts | 10 +- packages/phrases/src/locales/zh-cn.ts | 2 +- packages/ui/package.json | 1 + .../PasscodeValidation/index.test.tsx | 4 +- .../containers/PasscodeValidation/index.tsx | 19 +- .../SignInMethodsLink/index.module.scss | 34 +++ .../containers/SignInMethodsLink/index.tsx | 70 ++++++ .../src/containers/UsernameSignin/index.tsx | 4 +- pnpm-lock.yaml | 216 ++++++++++-------- 9 files changed, 246 insertions(+), 114 deletions(-) create mode 100644 packages/ui/src/containers/SignInMethodsLink/index.module.scss create mode 100644 packages/ui/src/containers/SignInMethodsLink/index.tsx diff --git a/packages/phrases/src/locales/en.ts b/packages/phrases/src/locales/en.ts index b76a5c4d4..09fce6686 100644 --- a/packages/phrases/src/locales/en.ts +++ b/packages/phrases/src/locales/en.ts @@ -17,8 +17,8 @@ const translation = { confirm_password: 'Confirm password', }, secondary: { - sign_in_with: 'Sign in with {{ method }}', - sign_in_with_2: 'Sign in with {{ methods[0] }} or {{ methods[1] }}', + sign_in_with: 'Sign in with {{method}}', + sign_in_with_2: 'Sign in with {{methods.0}} or {{methods.1}}', }, action: { sign_in: 'Sign In', @@ -35,8 +35,8 @@ const translation = { creat_account: 'Create Account', forgot_password: 'Forgot Password?', or: 'Or', - enter_passcode: 'The passcode has been sent to {{ address }}', - resend_after_senconds: 'Resend after {{ seconds }} seconds', + enter_passcode: 'The passcode has been sent to {{address}}', + resend_after_senconds: 'Resend after {{seconds}} seconds', resend_passcode: 'Resend Passcode', continue_with: 'Continue with', create_account_id_exsits: @@ -46,7 +46,7 @@ const translation = { }, error: { username_password_mismatch: 'Username and password do not match.', - required: '{{ field }} is required.', + required: '{{field}} is required.', username_exists: 'Username already exists.', username_should_not_start_with_number: 'Username should not start with a number.', username_valid_charset: 'Username should only contain letters, numbers, or underscore.', diff --git a/packages/phrases/src/locales/zh-cn.ts b/packages/phrases/src/locales/zh-cn.ts index 276d3de66..67dc44fed 100644 --- a/packages/phrases/src/locales/zh-cn.ts +++ b/packages/phrases/src/locales/zh-cn.ts @@ -19,7 +19,7 @@ const translation = { confirm_password: '确认密码', }, secondary: { - sign_in_with: '通过 {{ method }} 登录', + sign_in_with: '通过 {{method}} 登录', sign_in_with_2: '通过 {{ methods[0] }} 或 {{ methods[1] }} 登录', }, action: { diff --git a/packages/ui/package.json b/packages/ui/package.json index 03e869a8d..32e3006ee 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -30,6 +30,7 @@ "react-modal": "^3.14.4", "react-phone-number-input": "^3.1.46", "react-router-dom": "^6.2.2", + "react-string-replace": "^1.0.0", "react-timer-hook": "^3.0.5" }, "devDependencies": { diff --git a/packages/ui/src/containers/PasscodeValidation/index.test.tsx b/packages/ui/src/containers/PasscodeValidation/index.test.tsx index b66f19a33..b872df229 100644 --- a/packages/ui/src/containers/PasscodeValidation/index.test.tsx +++ b/packages/ui/src/containers/PasscodeValidation/index.test.tsx @@ -1,7 +1,7 @@ import { render, act, fireEvent, waitFor } from '@testing-library/react'; import React from 'react'; -import PasscodeValidation, { timeRange } from '.'; +import PasscodeValidation from '.'; jest.useFakeTimers(); @@ -32,7 +32,7 @@ describe('', () => { ); - expect(queryByText(timeRange)).not.toBeNull(); + expect(queryByText('description.resend_after_senconds')).not.toBeNull(); act(() => { jest.runAllTimers(); diff --git a/packages/ui/src/containers/PasscodeValidation/index.tsx b/packages/ui/src/containers/PasscodeValidation/index.tsx index 6e124bdc4..f51ca6601 100644 --- a/packages/ui/src/containers/PasscodeValidation/index.tsx +++ b/packages/ui/src/containers/PasscodeValidation/index.tsx @@ -1,6 +1,7 @@ import classNames from 'classnames'; -import React, { useState, useEffect, useContext, useMemo, ReactNode } from 'react'; +import React, { useState, useEffect, useContext, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; +import reactStringReplace from 'react-string-replace'; import { useTimer } from 'react-timer-hook'; import { getSendPasscodeApi, getVerifyPasscodeApi } from '@/apis/utils'; @@ -86,15 +87,15 @@ const PasscodeValidation = ({ type, channel, className, target }: Props) => { }, [verifyPasscodeError]); const renderCountDownMessage = useMemo(() => { - const contents: ReactNode[] = t('description.resend_after_senconds', { seconds }).split( - `${seconds}` + const contents = t('description.resend_after_senconds', { seconds }); + + return ( +
+ {reactStringReplace(contents, `${seconds}`, (match) => ( + {match} + ))} +
); - const counter = {seconds}; - - // eslint-disable-next-line @silverhand/fp/no-mutating-methods - contents.splice(1, 0, counter); - - return
{contents}
; }, [seconds, t]); return ( diff --git a/packages/ui/src/containers/SignInMethodsLink/index.module.scss b/packages/ui/src/containers/SignInMethodsLink/index.module.scss new file mode 100644 index 000000000..0bc54723c --- /dev/null +++ b/packages/ui/src/containers/SignInMethodsLink/index.module.scss @@ -0,0 +1,34 @@ +@use '@/scss/underscore' as _; + +.methodsPrimary { + @include _.flex-row; + justify-content: center; + + .signInMethodLink { + padding: 0 _.unit(4); + position: relative; + + &::after { + content: ''; + width: 1px; + height: 12px; + position: absolute; + top: 50%; + right: 0; + transform: translateY(-50%); + background-color: var(--color-primary); + } + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + + &::after { + content: none; + } + } + } +} diff --git a/packages/ui/src/containers/SignInMethodsLink/index.tsx b/packages/ui/src/containers/SignInMethodsLink/index.tsx new file mode 100644 index 000000000..43bd84d68 --- /dev/null +++ b/packages/ui/src/containers/SignInMethodsLink/index.tsx @@ -0,0 +1,70 @@ +import classNames from 'classnames'; +import React, { useMemo, ReactNode } from 'react'; +import { TFuncKey, useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; +import reactStringReplace from 'react-string-replace'; + +import TextLink from '@/components/TextLink'; +import { SignInMethod } from '@/types'; + +import * as styles from './index.module.scss'; + +type Props = { + signInMethods: SignInMethod[]; + type?: 'primary' | 'secondary'; + classname?: string; +}; + +const SignInMethodsKeyMap: { + [key in SignInMethod]: TFuncKey<'translation', 'main_flow.input'>; +} = { + username: 'username', + email: 'email', + phone: 'phone_number', +}; + +const SignInMethodsLink = ({ signInMethods, type = 'secondary', classname }: Props) => { + const navigate = useNavigate(); + const { t } = useTranslation(undefined, { keyPrefix: 'main_flow' }); + + const signInMethodsLink = useMemo( + () => + signInMethods.map((method) => ( + { + navigate(`/sign-in/${method}`); + }} + /> + )), + [navigate, signInMethods] + ); + + if (type === 'primary') { + return
{signInMethodsLink}
; + } + + if (signInMethods.length > 1) { + const rawText = t('secondary.sign_in_with_2', { + methods: signInMethods, + }); + + const textLink: ReactNode = signInMethods.reduce( + (content, method, index) => + // @ts-expect-error: reactStringReplace type bug, using deprecated ReactNodeArray as its input type + reactStringReplace(content, method, () => signInMethodsLink[index]), + rawText + ); + + return
{textLink}
; + } + + const rawText = t('secondary.sign_in_with', { method: signInMethods[0] }); + const textLink = reactStringReplace(rawText, signInMethods[0], () => signInMethodsLink[0]); + + return
{textLink}
; +}; + +export default SignInMethodsLink; diff --git a/packages/ui/src/containers/UsernameSignin/index.tsx b/packages/ui/src/containers/UsernameSignin/index.tsx index 39c82637e..d7584bb92 100644 --- a/packages/ui/src/containers/UsernameSignin/index.tsx +++ b/packages/ui/src/containers/UsernameSignin/index.tsx @@ -55,12 +55,12 @@ const UsernameSignin: FC = () => { () => ({ username: ({ username }) => { if (!username) { - return { code: 'required', data: { fieldName: t('input.username') } }; + return { code: 'required', data: { field: t('input.username') } }; } }, password: ({ password }) => { if (!password) { - return { code: 'required', data: { fieldName: t('input.password') } }; + return { code: 'required', data: { field: t('input.password') } }; } }, termsAgreement: ({ termsAgreement }) => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11ec95bf1..526f1c2e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -345,6 +345,7 @@ importers: react-modal: ^3.14.4 react-phone-number-input: ^3.1.46 react-router-dom: ^6.2.2 + react-string-replace: ^1.0.0 react-timer-hook: ^3.0.5 stylelint: ^13.13.1 ts-jest: ^27.1.1 @@ -364,6 +365,7 @@ importers: react-modal: 3.14.4_react-dom@17.0.2+react@17.0.2 react-phone-number-input: 3.1.46_react-dom@17.0.2+react@17.0.2 react-router-dom: 6.2.2_react-dom@17.0.2+react@17.0.2 + react-string-replace: 1.0.0 react-timer-hook: 3.0.5_react-dom@17.0.2+react@17.0.2 devDependencies: '@jest/types': 27.5.1 @@ -715,6 +717,19 @@ packages: semver: 6.3.0 dev: true + /@babel/helper-compilation-targets/7.16.7_@babel+core@7.17.9: + resolution: {integrity: sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.17.0 + '@babel/core': 7.17.9 + '@babel/helper-validator-option': 7.16.7 + browserslist: 4.20.0 + semver: 6.3.0 + dev: false + /@babel/helper-compilation-targets/7.17.7_@babel+core@7.17.9: resolution: {integrity: sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==} engines: {node: '>=6.9.0'} @@ -1329,12 +1344,12 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: false - /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.17.5: + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.16.0: resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1347,21 +1362,21 @@ packages: '@babel/helper-plugin-utils': 7.14.5 dev: false - /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.17.5: + /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.16.0: resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true - /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.17.5: + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.16.0: resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1390,7 +1405,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.9 - '@babel/helper-plugin-utils': 7.14.5 + '@babel/helper-plugin-utils': 7.16.7 dev: false /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.17.9: @@ -1402,21 +1417,21 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: false - /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.17.5: + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.16.0: resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true - /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.17.5: + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.16.0: resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1448,12 +1463,12 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: false - /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.17.5: + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.16.0: resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1466,12 +1481,12 @@ packages: '@babel/helper-plugin-utils': 7.14.5 dev: false - /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.17.5: + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.16.0: resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1484,12 +1499,12 @@ packages: '@babel/helper-plugin-utils': 7.14.5 dev: false - /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.17.5: + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.16.0: resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1511,12 +1526,12 @@ packages: '@babel/helper-plugin-utils': 7.14.5 dev: false - /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.17.5: + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.16.0: resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1529,12 +1544,12 @@ packages: '@babel/helper-plugin-utils': 7.14.5 dev: false - /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.17.5: + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.16.0: resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1547,12 +1562,12 @@ packages: '@babel/helper-plugin-utils': 7.14.5 dev: false - /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.17.5: + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.16.0: resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1575,13 +1590,13 @@ packages: '@babel/helper-plugin-utils': 7.16.7 dev: false - /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.17.5: + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.16.0: resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -1595,13 +1610,13 @@ packages: '@babel/helper-plugin-utils': 7.14.5 dev: false - /@babel/plugin-syntax-typescript/7.16.0_@babel+core@7.17.5: + /@babel/plugin-syntax-typescript/7.16.0_@babel+core@7.16.0: resolution: {integrity: sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@babel/helper-plugin-utils': 7.14.5 dev: true @@ -2079,7 +2094,7 @@ packages: dependencies: '@babel/compat-data': 7.17.0 '@babel/core': 7.17.9 - '@babel/helper-compilation-targets': 7.17.7_@babel+core@7.17.9 + '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.9 '@babel/helper-plugin-utils': 7.16.7 '@babel/helper-validator-option': 7.16.7 '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.16.7_@babel+core@7.17.9 @@ -3364,7 +3379,7 @@ packages: resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@jest/types': 27.5.1 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 @@ -5482,8 +5497,8 @@ packages: /@types/babel__core/7.1.17: resolution: {integrity: sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==} dependencies: - '@babel/parser': 7.17.3 - '@babel/types': 7.17.0 + '@babel/parser': 7.16.4 + '@babel/types': 7.16.0 '@types/babel__generator': 7.6.3 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.14.2 @@ -5492,27 +5507,27 @@ packages: /@types/babel__generator/7.6.3: resolution: {integrity: sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==} dependencies: - '@babel/types': 7.17.0 + '@babel/types': 7.16.0 dev: true /@types/babel__template/7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: - '@babel/parser': 7.17.3 - '@babel/types': 7.17.0 + '@babel/parser': 7.16.4 + '@babel/types': 7.16.0 dev: true /@types/babel__traverse/7.14.2: resolution: {integrity: sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==} dependencies: - '@babel/types': 7.17.0 + '@babel/types': 7.16.0 dev: true /@types/body-parser/1.19.2: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 16.11.12 + '@types/node': 17.0.23 /@types/bonjour/3.5.10: resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} @@ -5539,7 +5554,7 @@ packages: /@types/connect/3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 16.11.12 + '@types/node': 17.0.23 /@types/content-disposition/0.5.4: resolution: {integrity: sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==} @@ -5582,7 +5597,7 @@ packages: /@types/express-serve-static-core/4.17.26: resolution: {integrity: sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ==} dependencies: - '@types/node': 16.11.12 + '@types/node': 17.0.23 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 @@ -5850,7 +5865,7 @@ packages: /@types/react-router/5.1.17: resolution: {integrity: sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==} dependencies: - '@types/history': 4.7.9 + '@types/history': 4.7.11 '@types/react': 17.0.37 /@types/react/17.0.37: @@ -5889,7 +5904,7 @@ packages: resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} dependencies: '@types/mime': 1.3.2 - '@types/node': 16.11.12 + '@types/node': 17.0.23 /@types/sockjs/0.3.33: resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==} @@ -6609,18 +6624,18 @@ packages: - debug dev: false - /babel-jest/27.5.1_@babel+core@7.17.5: + /babel-jest/27.5.1_@babel+core@7.16.0: resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 '@types/babel__core': 7.1.17 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 27.5.1_@babel+core@7.17.5 + babel-preset-jest: 27.5.1_@babel+core@7.16.0 chalk: 4.1.2 graceful-fs: 4.2.9 slash: 3.0.0 @@ -6688,8 +6703,8 @@ packages: resolution: {integrity: sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/template': 7.16.7 - '@babel/types': 7.17.0 + '@babel/template': 7.16.0 + '@babel/types': 7.16.0 '@types/babel__core': 7.1.17 '@types/babel__traverse': 7.14.2 dev: true @@ -6738,35 +6753,35 @@ packages: - supports-color dev: false - /babel-preset-current-node-syntax/1.0.1_@babel+core@7.17.5: + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.16.0: resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.17.5 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.17.5 - '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.17.5 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.17.5 - '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.17.5 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.17.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.17.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.17.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.17.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.17.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.17.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.17.5 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.17.5 + '@babel/core': 7.16.0 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.16.0 + '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.16.0 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.16.0 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.16.0 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.16.0 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.16.0 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.16.0 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.16.0 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.16.0 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.16.0 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.16.0 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.16.0 dev: true - /babel-preset-jest/27.5.1_@babel+core@7.17.5: + /babel-preset-jest/27.5.1_@babel+core@7.16.0: resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 babel-plugin-jest-hoist: 27.5.1 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.17.5 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.16.0 dev: true /bail/1.0.5: @@ -7129,6 +7144,7 @@ packages: /camelcase/6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + dev: false /caniuse-api/3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} @@ -8490,7 +8506,6 @@ packages: engines: {node: '>= 4'} dependencies: domelementtype: 2.2.0 - dev: false /domutils/1.5.1: resolution: {integrity: sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=} @@ -8510,7 +8525,7 @@ packages: dependencies: dom-serializer: 1.3.2 domelementtype: 2.2.0 - domhandler: 4.3.0 + domhandler: 4.3.1 /dot-case/3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} @@ -9319,7 +9334,7 @@ packages: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.4 + micromatch: 4.0.5 /fast-glob/3.2.7: resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} @@ -9611,7 +9626,7 @@ packages: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 - mime-types: 2.1.35 + mime-types: 2.1.34 dev: true /form-data/4.0.0: @@ -10225,7 +10240,7 @@ packages: /history/4.10.1: resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} dependencies: - '@babel/runtime': 7.17.9 + '@babel/runtime': 7.16.3 loose-envify: 1.4.0 resolve-pathname: 3.0.0 tiny-invariant: 1.2.0 @@ -10650,6 +10665,15 @@ packages: engines: {node: '>=8'} dev: true + /import-local/3.0.3: + resolution: {integrity: sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + /import-local/3.1.0: resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} engines: {node: '>=8'} @@ -10860,7 +10884,6 @@ packages: resolution: {integrity: sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==} dependencies: has: 1.0.3 - dev: false /is-core-module/2.8.1: resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==} @@ -11163,8 +11186,8 @@ packages: resolution: {integrity: sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.17.5 - '@babel/parser': 7.17.3 + '@babel/core': 7.16.0 + '@babel/parser': 7.16.4 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 6.3.0 @@ -11262,7 +11285,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.9 - import-local: 3.1.0 + import-local: 3.0.3 jest-config: 27.5.1 jest-util: 27.5.1 jest-validate: 27.5.1 @@ -11285,10 +11308,10 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.17.5 + '@babel/core': 7.16.0 '@jest/test-sequencer': 27.5.1 '@jest/types': 27.5.1 - babel-jest: 27.5.1_@babel+core@7.17.5 + babel-jest: 27.5.1_@babel+core@7.16.0 chalk: 4.1.2 ci-info: 3.3.0 deepmerge: 4.2.2 @@ -11450,7 +11473,7 @@ packages: resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/code-frame': 7.16.7 + '@babel/code-frame': 7.16.0 '@jest/types': 27.5.1 '@types/stack-utils': 2.0.1 chalk: 4.1.2 @@ -11508,7 +11531,7 @@ packages: jest-pnp-resolver: 1.2.2_jest-resolve@27.5.1 jest-util: 27.5.1 jest-validate: 27.5.1 - resolve: 1.22.0 + resolve: 1.20.0 resolve.exports: 1.1.0 slash: 3.0.0 dev: true @@ -11587,16 +11610,16 @@ packages: resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/core': 7.17.5 - '@babel/generator': 7.17.3 - '@babel/plugin-syntax-typescript': 7.16.0_@babel+core@7.17.5 - '@babel/traverse': 7.17.3 - '@babel/types': 7.17.0 + '@babel/core': 7.16.0 + '@babel/generator': 7.16.0 + '@babel/plugin-syntax-typescript': 7.16.0_@babel+core@7.16.0 + '@babel/traverse': 7.16.3 + '@babel/types': 7.16.0 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 '@types/babel__traverse': 7.14.2 '@types/prettier': 2.4.2 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.17.5 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.16.0 chalk: 4.1.2 expect: 27.5.1 graceful-fs: 4.2.9 @@ -11626,7 +11649,7 @@ packages: chalk: 4.1.2 ci-info: 3.3.0 graceful-fs: 4.2.9 - picomatch: 2.3.1 + picomatch: 2.3.0 dev: true /jest-validate/27.5.1: @@ -11634,7 +11657,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - camelcase: 6.3.0 + camelcase: 6.2.1 chalk: 4.1.2 jest-get-type: 27.5.1 leven: 3.1.0 @@ -11673,7 +11696,7 @@ packages: optional: true dependencies: '@jest/core': 27.5.1 - import-local: 3.1.0 + import-local: 3.0.3 jest-cli: 27.5.1 transitivePeerDependencies: - bufferutil @@ -11743,7 +11766,7 @@ packages: optional: true dependencies: abab: 2.0.5 - acorn: 8.7.0 + acorn: 8.6.0 acorn-globals: 6.0.0 cssom: 0.4.4 cssstyle: 2.3.0 @@ -11845,7 +11868,6 @@ packages: resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} engines: {node: '>=6'} hasBin: true - dev: false /jsonfile/6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -13021,6 +13043,7 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.0 + dev: true /micromatch/4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} @@ -13028,7 +13051,6 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: false /mime-db/1.33.0: resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} @@ -13122,7 +13144,6 @@ packages: resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} dependencies: brace-expansion: 1.1.11 - dev: false /minimatch/3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -14340,6 +14361,7 @@ packages: /picomatch/2.3.0: resolution: {integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==} engines: {node: '>=8.6'} + dev: true /picomatch/2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -15652,7 +15674,7 @@ packages: dependencies: '@babel/code-frame': 7.16.7 address: 1.1.2 - browserslist: 4.20.0 + browserslist: 4.20.2 chalk: 4.1.2 cross-spawn: 7.0.3 detect-port-alt: 1.1.6 @@ -15903,7 +15925,7 @@ packages: peerDependencies: react: '>=15' dependencies: - '@babel/runtime': 7.17.9 + '@babel/runtime': 7.16.3 history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -15952,6 +15974,11 @@ packages: react: 17.0.2 dev: false + /react-string-replace/1.0.0: + resolution: {integrity: sha512-+iLsyE4AeSmnfctgswXOf1PmKRgns6wJ4LVb+8ADMU6mDK3jvBE11QzfMQf7CYtPUUiBCDjZ9ZppzXOIYrzCRg==} + engines: {node: '>=0.12.0'} + dev: false + /react-textarea-autosize/8.3.3_cfedea9b3ed0faf0dded75c187406c5e: resolution: {integrity: sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==} engines: {node: '>=10'} @@ -16351,7 +16378,7 @@ packages: /renderkid/3.0.0: resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} dependencies: - css-select: 4.2.1 + css-select: 4.3.0 dom-converter: 0.2.0 htmlparser2: 6.1.0 lodash: 4.17.21 @@ -16454,7 +16481,6 @@ packages: dependencies: is-core-module: 2.8.0 path-parse: 1.0.7 - dev: false /resolve/1.22.0: resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} @@ -17844,7 +17870,7 @@ packages: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.0 - minimatch: 3.1.2 + minimatch: 3.0.4 dev: true /text-extensions/1.9.0: @@ -18012,7 +18038,7 @@ packages: fast-json-stable-stringify: 2.1.0 jest: 27.5.1 jest-util: 27.5.1 - json5: 2.2.0 + json5: 2.2.1 lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.3.5 @@ -18046,7 +18072,7 @@ packages: fast-json-stable-stringify: 2.1.0 jest: 27.5.1 jest-util: 27.5.1 - json5: 2.2.0 + json5: 2.2.1 lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.3.5