-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'Expensify:main' into krishna2323/issue/36140
- Loading branch information
Showing
107 changed files
with
1,458 additions
and
897 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
src/components/AddPaymentCard/PaymentCardChangeCurrencyForm.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import React, {useCallback, useMemo, useState} from 'react'; | ||
import {View} from 'react-native'; | ||
import type {ValueOf} from 'type-fest'; | ||
import FormProvider from '@components/Form/FormProvider'; | ||
import InputWrapper from '@components/Form/InputWrapper'; | ||
import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; | ||
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; | ||
import SelectionList from '@components/SelectionList'; | ||
import RadioListItem from '@components/SelectionList/RadioListItem'; | ||
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/ChangeBillingCurrencyForm'; | ||
import PaymentCardCurrencyHeader from './PaymentCardCurrencyHeader'; | ||
import PaymentCardCurrencyModal from './PaymentCardCurrencyModal'; | ||
|
||
type PaymentCardFormProps = { | ||
initialCurrency?: ValueOf<typeof CONST.CURRENCY>; | ||
isSecurityCodeRequired?: boolean; | ||
changeBillingCurrency: (currency?: ValueOf<typeof CONST.CURRENCY>, values?: FormOnyxValues<typeof ONYXKEYS.FORMS.CHANGE_BILLING_CURRENCY_FORM>) => void; | ||
}; | ||
|
||
const REQUIRED_FIELDS = [INPUT_IDS.SECURITY_CODE]; | ||
|
||
function PaymentCardChangeCurrencyForm({changeBillingCurrency, isSecurityCodeRequired, initialCurrency}: PaymentCardFormProps) { | ||
const styles = useThemeStyles(); | ||
const {translate} = useLocalize(); | ||
|
||
const [isCurrencyModalVisible, setIsCurrencyModalVisible] = useState(false); | ||
const [currency, setCurrency] = useState<ValueOf<typeof CONST.CURRENCY>>(initialCurrency ?? CONST.CURRENCY.USD); | ||
|
||
const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.CHANGE_BILLING_CURRENCY_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.CHANGE_BILLING_CURRENCY_FORM> => { | ||
const errors = ValidationUtils.getFieldRequiredErrors(values, REQUIRED_FIELDS); | ||
|
||
if (values.securityCode && !ValidationUtils.isValidSecurityCode(values.securityCode)) { | ||
errors.securityCode = translate('addPaymentCardPage.error.securityCode'); | ||
} | ||
|
||
return errors; | ||
}; | ||
|
||
const {sections} = useMemo( | ||
() => ({ | ||
sections: [ | ||
{ | ||
data: (Object.keys(CONST.CURRENCY) as Array<ValueOf<typeof CONST.CURRENCY>>).map((currencyItem) => ({ | ||
text: currencyItem, | ||
value: currencyItem, | ||
keyForList: currencyItem, | ||
isSelected: currencyItem === currency, | ||
})), | ||
}, | ||
], | ||
}), | ||
[currency], | ||
); | ||
|
||
const showCurrenciesModal = useCallback(() => { | ||
setIsCurrencyModalVisible(true); | ||
}, []); | ||
|
||
const changeCurrency = useCallback((selectedCurrency: ValueOf<typeof CONST.CURRENCY>) => { | ||
setCurrency(selectedCurrency); | ||
setIsCurrencyModalVisible(false); | ||
}, []); | ||
|
||
const selectCurrency = useCallback( | ||
(selectedCurrency: ValueOf<typeof CONST.CURRENCY>) => { | ||
setCurrency(selectedCurrency); | ||
changeBillingCurrency(selectedCurrency); | ||
}, | ||
[changeBillingCurrency], | ||
); | ||
|
||
if (isSecurityCodeRequired) { | ||
return ( | ||
<FormProvider | ||
formID={ONYXKEYS.FORMS.CHANGE_BILLING_CURRENCY_FORM} | ||
validate={validate} | ||
onSubmit={(values) => changeBillingCurrency(currency, values)} | ||
submitButtonText={translate('common.save')} | ||
scrollContextEnabled | ||
style={[styles.mh5, styles.flexGrow1]} | ||
> | ||
<PaymentCardCurrencyHeader /> | ||
<> | ||
<View style={[styles.mt5, styles.mhn5]}> | ||
<MenuItemWithTopDescription | ||
shouldShowRightIcon | ||
title={currency} | ||
descriptionTextStyle={styles.textNormal} | ||
description={translate('common.currency')} | ||
onPress={showCurrenciesModal} | ||
/> | ||
</View> | ||
<InputWrapper | ||
InputComponent={TextInput} | ||
inputID={INPUT_IDS.SECURITY_CODE} | ||
label={translate('addDebitCardPage.cvv')} | ||
aria-label={translate('addDebitCardPage.cvv')} | ||
role={CONST.ROLE.PRESENTATION} | ||
maxLength={4} | ||
containerStyles={[styles.mt5]} | ||
inputMode={CONST.INPUT_MODE.NUMERIC} | ||
/> | ||
</> | ||
<PaymentCardCurrencyModal | ||
isVisible={isCurrencyModalVisible} | ||
currencies={Object.keys(CONST.CURRENCY) as Array<ValueOf<typeof CONST.CURRENCY>>} | ||
currentCurrency={currency} | ||
onCurrencyChange={changeCurrency} | ||
onClose={() => setIsCurrencyModalVisible(false)} | ||
/> | ||
</FormProvider> | ||
); | ||
} | ||
|
||
return ( | ||
<View style={[styles.mh5, styles.flexGrow1]}> | ||
<SelectionList | ||
headerContent={<PaymentCardCurrencyHeader isSectionList />} | ||
initiallyFocusedOptionKey={currency} | ||
containerStyle={[styles.mhn5]} | ||
sections={sections} | ||
onSelectRow={(option) => { | ||
selectCurrency(option.value); | ||
}} | ||
showScrollIndicator | ||
shouldStopPropagation | ||
shouldUseDynamicMaxToRenderPerBatch | ||
ListItem={RadioListItem} | ||
/> | ||
</View> | ||
); | ||
} | ||
|
||
PaymentCardChangeCurrencyForm.displayName = 'PaymentCardChangeCurrencyForm'; | ||
|
||
export default PaymentCardChangeCurrencyForm; |
28 changes: 28 additions & 0 deletions
28
src/components/AddPaymentCard/PaymentCardCurrencyHeader.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import Text from '@components/Text'; | ||
import TextLink from '@components/TextLink'; | ||
import useLocalize from '@hooks/useLocalize'; | ||
import useThemeStyles from '@hooks/useThemeStyles'; | ||
import CONST from '@src/CONST'; | ||
|
||
function PaymentCardCurrencyHeader({isSectionList}: {isSectionList?: boolean}) { | ||
const styles = useThemeStyles(); | ||
const {translate} = useLocalize(); | ||
return ( | ||
<View style={[isSectionList && styles.mh5]}> | ||
<Text style={[styles.mt3, isSectionList && styles.mb5]}> | ||
{`${translate('billingCurrency.note')}`}{' '} | ||
<TextLink | ||
style={styles.link} | ||
href={CONST.PRICING} | ||
>{`${translate('billingCurrency.noteLink')}`}</TextLink>{' '} | ||
{`${translate('billingCurrency.noteDetails')}`} | ||
</Text> | ||
</View> | ||
); | ||
} | ||
|
||
PaymentCardCurrencyHeader.displayName = 'PaymentCardCurrencyHeader'; | ||
|
||
export default PaymentCardCurrencyHeader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.