From 597791ac2162aa03430c6cb895dc414a5aa53a6a Mon Sep 17 00:00:00 2001 From: burczu Date: Tue, 29 Oct 2024 13:18:10 +0100 Subject: [PATCH 01/23] enter email, hang tight and director check components added --- .../simple-illustration__pillow.svg | 28 +++++ src/components/Icon/Illustrations.ts | 2 + src/languages/en.ts | 21 ++++ src/languages/es.ts | 23 +++- src/languages/params.ts | 5 + .../NonUSD/SignerInfo/DirectorCheck.tsx | 65 ++++++++++ .../NonUSD/SignerInfo/EnterEmail.tsx | 83 +++++++++++++ .../NonUSD/SignerInfo/HangTight.tsx | 58 +++++++++ src/types/form/ReimbursementAccountForm.ts | 117 ++++++++++++++++++ 9 files changed, 401 insertions(+), 1 deletion(-) create mode 100644 assets/images/simple-illustrations/simple-illustration__pillow.svg create mode 100644 src/pages/ReimbursementAccount/NonUSD/SignerInfo/DirectorCheck.tsx create mode 100644 src/pages/ReimbursementAccount/NonUSD/SignerInfo/EnterEmail.tsx create mode 100644 src/pages/ReimbursementAccount/NonUSD/SignerInfo/HangTight.tsx diff --git a/assets/images/simple-illustrations/simple-illustration__pillow.svg b/assets/images/simple-illustrations/simple-illustration__pillow.svg new file mode 100644 index 000000000000..97a0811266ae --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__pillow.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts index 0efb65ed7a61..98142ec02def 100644 --- a/src/components/Icon/Illustrations.ts +++ b/src/components/Icon/Illustrations.ts @@ -102,6 +102,7 @@ import OpenSafe from '@assets/images/simple-illustrations/simple-illustration__o import PalmTree from '@assets/images/simple-illustrations/simple-illustration__palmtree.svg'; import Pencil from '@assets/images/simple-illustrations/simple-illustration__pencil.svg'; import PiggyBank from '@assets/images/simple-illustrations/simple-illustration__piggybank.svg'; +import Pillow from '@assets/images/simple-illustrations/simple-illustration__pillow.svg'; import Profile from '@assets/images/simple-illustrations/simple-illustration__profile.svg'; import QRCode from '@assets/images/simple-illustrations/simple-illustration__qr-code.svg'; import ReceiptEnvelope from '@assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg'; @@ -222,6 +223,7 @@ export { ExpensifyCardIllustration, SplitBill, PiggyBank, + Pillow, Accounting, Car, Coins, diff --git a/src/languages/en.ts b/src/languages/en.ts index f1339ed88373..0ac1767687d7 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -41,6 +41,7 @@ import type { CharacterLimitParams, CompanyCardBankName, CompanyCardFeedNameParams, + CompanyNameParams, ConfirmThatParams, ConnectionNameParams, ConnectionParams, @@ -2257,6 +2258,26 @@ const translations = { }, signerInfoStep: { signerInfo: 'Signer info', + areYouDirector: ({companyName}: CompanyNameParams) => `Are you a director or senior officer at ${companyName}?`, + regulationRequiresUs: 'Regulation requires us to verify if the signer has the authority to take this action on behalf of the business.', + whatsYourName: "What's your legal name", + fullName: 'Legal full name', + whatsYourJobTitle: "What's your job title?", + jobTitle: 'Job title', + whatsYourDOB: "What's your date of birth?", + uploadID: 'Upload ID and proof of address', + id: "ID (driver's license or passport)", + personalAddress: 'Proof of personal address (e.g. utility bill)', + letsDoubleCheck: 'Let’s double check that everything looks right.', + legalName: 'Legal name', + proofOf: 'Proof of personal address', + enterOneEmail: 'Enter the email of director or senior officer at', + regulationRequiresOneMoreDirector: 'Regulation requires one more director or senior officer as a signer.', + hangTight: 'Hang tight...', + enterTwoEmails: 'Enter the emails of two directors or senior officers at', + sendReminder: 'Send a reminder', + chooseFile: 'Choose file', + weAreWaiting: "We're waiting for others to verify their identities as directors or senior officers of the business.", }, agreementsStep: { agreements: 'Agreements', diff --git a/src/languages/es.ts b/src/languages/es.ts index a9ebfedf1cc3..12e1de851c67 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -39,6 +39,7 @@ import type { CharacterLimitParams, CompanyCardBankName, CompanyCardFeedNameParams, + CompanyNameParams, ConfirmThatParams, ConnectionNameParams, ConnectionParams, @@ -2279,7 +2280,27 @@ const translations = { selectCountry: 'Seleccione su país', }, signerInfoStep: { - signerInfo: 'Información del firmante', + signerInfo: 'Signer info', + areYouDirector: ({companyName}: CompanyNameParams) => `Are you a director or senior officer at ${companyName}?`, + regulationRequiresUs: 'Regulation requires us to verify if the signer has the authority to take this action on behalf of the business.', + whatsYourName: "What's your legal name", + fullName: 'Legal full name', + whatsYourJobTitle: "What's your job title?", + jobTitle: 'Job title', + whatsYourDOB: "What's your date of birth?", + uploadID: 'Upload ID and proof of address', + id: "ID (driver's license or passport)", + personalAddress: 'Proof of personal address (e.g. utility bill)', + letsDoubleCheck: 'Let’s double check that everything looks right.', + legalName: 'Legal name', + proofOf: 'Proof of personal address', + enterOneEmail: 'Enter the email of director or senior officer at', + regulationRequiresOneMoreDirector: 'Regulation requires one more director or senior officer as a signer.', + hangTight: 'Hang tight...', + enterTwoEmails: 'Enter the emails of two directors or senior officers at', + sendReminder: 'Send a reminder', + chooseFile: 'Choose file', + weAreWaiting: "We're waiting for others to verify their identities as directors or senior officers of the business.", }, agreementsStep: { agreements: 'Acuerdos', diff --git a/src/languages/params.ts b/src/languages/params.ts index e9f0c4370357..79eae25ae9a6 100644 --- a/src/languages/params.ts +++ b/src/languages/params.ts @@ -547,6 +547,10 @@ type CompanyCardBankName = { bankName: string; }; +type CompanyNameParams = { + companyName: string; +}; + export type { AuthenticationErrorParams, ImportMembersSuccessfullDescriptionParams, @@ -746,4 +750,5 @@ export type { OptionalParam, AssignCardParams, ImportedTypesParams, + CompanyNameParams, }; diff --git a/src/pages/ReimbursementAccount/NonUSD/SignerInfo/DirectorCheck.tsx b/src/pages/ReimbursementAccount/NonUSD/SignerInfo/DirectorCheck.tsx new file mode 100644 index 000000000000..648fd37e543b --- /dev/null +++ b/src/pages/ReimbursementAccount/NonUSD/SignerInfo/DirectorCheck.tsx @@ -0,0 +1,65 @@ +import React, {useMemo, useState} from 'react'; +import FormProvider from '@components/Form/FormProvider'; +import type {Choice} from '@components/RadioButtons'; +import RadioButtons from '@components/RadioButtons'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import ONYXKEYS from '@src/ONYXKEYS'; + +type DirectorCheckProps = { + /** The title of the question */ + title: string; + + /** The default value of the radio button */ + defaultValue: boolean; + + /** Callback when the value is selected */ + onSelectedValue: (value: boolean) => void; +}; + +function DirectorCheck({title, onSelectedValue, defaultValue}: DirectorCheckProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const [value, setValue] = useState(defaultValue); + + const handleSubmit = () => { + onSelectedValue(value); + }; + const handleSelectValue = (newValue: string) => setValue(newValue === 'true'); + const options = useMemo( + () => [ + { + label: translate('common.yes'), + value: 'true', + }, + { + label: translate('common.no'), + value: 'false', + }, + ], + [translate], + ); + + return ( + + {title} + {translate('signerInfoStep.regulationRequiresUs')} + + + ); +} + +DirectorCheck.displayName = 'DirectorCheck'; + +export default DirectorCheck; diff --git a/src/pages/ReimbursementAccount/NonUSD/SignerInfo/EnterEmail.tsx b/src/pages/ReimbursementAccount/NonUSD/SignerInfo/EnterEmail.tsx new file mode 100644 index 000000000000..338820c78cf1 --- /dev/null +++ b/src/pages/ReimbursementAccount/NonUSD/SignerInfo/EnterEmail.tsx @@ -0,0 +1,83 @@ +import {Str} from 'expensify-common'; +import React, {useCallback} from 'react'; +import {useOnyx} from 'react-native-onyx'; +import FormProvider from '@components/Form/FormProvider'; +import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; +import Text from '@components/Text'; +import TextInput from '@components/TextInput'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as ValidationUtils from '@libs/ValidationUtils'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; + +type EnterEmailProps = { + onSubmit: () => void; + + isUserDirector: boolean; +}; + +const {SIGNER_EMAIL, SECOND_SIGNER_EMAIL} = INPUT_IDS.ADDITIONAL_DATA.CORPAY; + +function EnterEmail({onSubmit, isUserDirector}: EnterEmailProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + + const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT); + const policyID = reimbursementAccount?.achData?.policyID ?? '-1'; + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + const currency = policy?.outputCurrency ?? ''; + const shouldGatherBothEmails = currency === CONST.CURRENCY.AUD && !isUserDirector; + + const validate = useCallback( + (values: FormOnyxValues): FormInputErrors => { + const errors = ValidationUtils.getFieldRequiredErrors(values, shouldGatherBothEmails ? [SIGNER_EMAIL, SECOND_SIGNER_EMAIL] : [SIGNER_EMAIL]); + if (values[SIGNER_EMAIL] && !Str.isValidEmail(values[SIGNER_EMAIL])) { + errors[SIGNER_EMAIL] = translate('bankAccount.error.firstName'); + } + + if (shouldGatherBothEmails && values[SECOND_SIGNER_EMAIL] && !Str.isValidEmail(values[SECOND_SIGNER_EMAIL])) { + errors[SECOND_SIGNER_EMAIL] = translate('bankAccount.error.lastName'); + } + + return errors; + }, + [shouldGatherBothEmails, translate], + ); + + return ( + + {translate(shouldGatherBothEmails ? 'signerInfoStep.enterTwoEmails' : 'signerInfoStep.enterOneEmail')} + + {shouldGatherBothEmails && ( + + )} + + ); +} + +EnterEmail.displayName = 'EnterEmail'; + +export default EnterEmail; diff --git a/src/pages/ReimbursementAccount/NonUSD/SignerInfo/HangTight.tsx b/src/pages/ReimbursementAccount/NonUSD/SignerInfo/HangTight.tsx new file mode 100644 index 000000000000..15fea5e46691 --- /dev/null +++ b/src/pages/ReimbursementAccount/NonUSD/SignerInfo/HangTight.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import {View} from 'react-native'; +import Button from '@components/Button'; +import Icon from '@components/Icon'; +import * as Expensicons from '@components/Icon/Expensicons'; +import * as Illustrations from '@components/Icon/Illustrations'; +import SafeAreaConsumer from '@components/SafeAreaConsumer'; +import ScrollView from '@components/ScrollView'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; + +function HangTight({tempSubmit}: {tempSubmit: () => void}) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + + const handleSendReminder = () => { + // TODO remove that + tempSubmit(); + }; + + return ( + + {({safeAreaPaddingBottomStyle}) => ( + + + + + + {translate('signerInfoStep.hangTight')} + {translate('signerInfoStep.weAreWaiting')} + + +