Skip to content

Commit

Permalink
Merge pull request #52028 from callstack-internal/VickyStash/feature/…
Browse files Browse the repository at this point in the history
…51908-card-name-on-confirmation-page

[Workspace Feeds] Card name field on confirmation page
  • Loading branch information
mountiny authored Nov 7, 2024
2 parents 160a2d2 + 98bf01c commit 59c7a2e
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2699,6 +2699,7 @@ const CONST = {
STEP: {
ASSIGNEE: 'Assignee',
CARD: 'Card',
CARD_NAME: 'CardName',
TRANSACTION_START_DATE: 'TransactionStartDate',
CONFIRMATION: 'Confirmation',
},
Expand Down
1 change: 1 addition & 0 deletions src/libs/API/parameters/AssignCompanyCardParams.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
type AssignCompanyCardParams = {
policyID: string;
bankName: string;
cardName: string;
encryptedCardNumber: string;
email: string;
startDate: string;
Expand Down
2 changes: 1 addition & 1 deletion src/libs/CardUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function getCompanyCardNumber(cardList: Record<string, string>, lastFourPAN?: st
return '';
}

return Object.keys(cardList).find((card) => card.endsWith(lastFourPAN)) ?? '';
return Object.keys(cardList).find((card) => card.endsWith(lastFourPAN)) ?? maskCard(lastFourPAN);
}

function getCardFeedIcon(cardFeed: CompanyCardFeed | typeof CONST.EXPENSIFY_CARD.BANK): IconAsset {
Expand Down
3 changes: 2 additions & 1 deletion src/libs/actions/CompanyCards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,15 @@ function assignWorkspaceCompanyCard(policyID: string, data?: Partial<AssignCardD
if (!data) {
return;
}
const {bankName = '', email = '', encryptedCardNumber = '', startDate = ''} = data;
const {bankName = '', email = '', encryptedCardNumber = '', startDate = '', cardName = ''} = data;
const assigneeDetails = PersonalDetailsUtils.getPersonalDetailByEmail(email);
const optimisticCardAssignedReportAction = ReportUtils.buildOptimisticCardAssignedReportAction(assigneeDetails?.accountID ?? -1);

const parameters: AssignCompanyCardParams = {
policyID,
bankName,
encryptedCardNumber,
cardName,
email,
startDate,
reportActionID: optimisticCardAssignedReportAction.reportActionID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';
import AssigneeStep from './AssigneeStep';
import CardNameStep from './CardNameStep';
import CardSelectionStep from './CardSelectionStep';
import ConfirmationStep from './ConfirmationStep';
import TransactionStartDateStep from './TransactionStartDateStep';
Expand Down Expand Up @@ -39,6 +40,8 @@ function AssignCardFeedPage({route, policy}: AssignCardFeedPageProps) {
);
case CONST.COMPANY_CARD.STEP.TRANSACTION_START_DATE:
return <TransactionStartDateStep />;
case CONST.COMPANY_CARD.STEP.CARD_NAME:
return <CardNameStep policyID={policyID} />;
case CONST.COMPANY_CARD.STEP.CONFIRMATION:
return (
<ConfirmationStep
Expand Down
5 changes: 5 additions & 0 deletions src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,15 @@ function AssigneeStep({policy}: AssigneeStepProps) {
setShouldShowError(true);
return;
}

const personalDetail = PersonalDetailsUtils.getPersonalDetailByEmail(selectedMember);
const memberName = personalDetail?.firstName ? personalDetail.firstName : personalDetail?.login;

CompanyCards.setAssignCardStepAndData({
currentStep: isEditing ? CONST.COMPANY_CARD.STEP.CONFIRMATION : CONST.COMPANY_CARD.STEP.CARD,
data: {
email: selectedMember,
cardName: `${memberName}'s card`,
},
isEditing: false,
});
Expand Down
95 changes: 95 additions & 0 deletions src/pages/workspace/companyCards/assignCard/CardNameStep.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React 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 HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import Text from '@components/Text';
import TextInput from '@components/TextInput';
import useAutoFocusInput from '@hooks/useAutoFocusInput';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import * as ValidationUtils from '@libs/ValidationUtils';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import * as CompanyCards from '@userActions/CompanyCards';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import INPUT_IDS from '@src/types/form/EditExpensifyCardNameForm';

type CardNameStepProps = {
/** Current policy id */
policyID: string;
};

function CardNameStep({policyID}: CardNameStepProps) {
const {translate} = useLocalize();
const {inputCallbackRef} = useAutoFocusInput();
const styles = useThemeStyles();
const [assignCard] = useOnyx(ONYXKEYS.ASSIGN_CARD);

const data = assignCard?.data;

const submit = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_WORKSPACE_COMPANY_CARD_NAME_FORM>) => {
CompanyCards.setAssignCardStepAndData({
currentStep: CONST.COMPANY_CARD.STEP.CONFIRMATION,
data: {
cardName: values.name,
},
isEditing: false,
});
};

const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_WORKSPACE_COMPANY_CARD_NAME_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.EDIT_WORKSPACE_COMPANY_CARD_NAME_FORM> => {
const errors = ValidationUtils.getFieldRequiredErrors(values, [INPUT_IDS.NAME]);
const length = values.name.length;

if (length > CONST.STANDARD_LENGTH_LIMIT) {
ErrorUtils.addErrorMessage(errors, INPUT_IDS.NAME, translate('common.error.characterLimitExceedCounter', {length, limit: CONST.STANDARD_LENGTH_LIMIT}));
}

return errors;
};

return (
<AccessOrNotFoundWrapper
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED}
>
<ScreenWrapper
testID={CardNameStep.displayName}
shouldEnablePickerAvoiding={false}
includeSafeAreaPaddingBottom={false}
>
<HeaderWithBackButton
title={translate('workspace.moreFeatures.companyCards.cardName')}
onBackButtonPress={() => CompanyCards.setAssignCardStepAndData({currentStep: CONST.COMPANY_CARD.STEP.CONFIRMATION, isEditing: false})}
/>
<Text style={[styles.mh5, styles.mt3, styles.mb5]}>{translate('workspace.moreFeatures.companyCards.giveItNameInstruction')}</Text>
<FormProvider
formID={ONYXKEYS.FORMS.EDIT_WORKSPACE_COMPANY_CARD_NAME_FORM}
submitButtonText={translate('common.confirm')}
onSubmit={submit}
style={[styles.flex1, styles.mh5]}
enabledWhenOffline
validate={validate}
>
<InputWrapper
InputComponent={TextInput}
inputID={INPUT_IDS.NAME}
label={translate('workspace.moreFeatures.companyCards.cardName')}
aria-label={translate('workspace.moreFeatures.companyCards.cardName')}
role={CONST.ROLE.PRESENTATION}
defaultValue={data?.cardName}
ref={inputCallbackRef}
/>
</FormProvider>
</ScreenWrapper>
</AccessOrNotFoundWrapper>
);
}

CardNameStep.displayName = 'CardNameStep';

export default CardNameStep;
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ function CardSelectionStep({feed, policyID}: CardSelectionStepProps) {
return;
}

const cardName =
const cardNumber =
Object.entries(filteredCardList)
.find(([, encryptedCardNumber]) => encryptedCardNumber === cardSelected)
?.at(0) ?? '';

CompanyCards.setAssignCardStepAndData({
currentStep: isEditing ? CONST.COMPANY_CARD.STEP.CONFIRMATION : CONST.COMPANY_CARD.STEP.TRANSACTION_START_DATE,
data: {encryptedCardNumber: cardSelected, cardName: accountCardList?.length > 0 ? cardSelected : cardName},
data: {encryptedCardNumber: cardSelected, cardNumber: accountCardList?.length > 0 ? cardSelected : cardNumber},
isEditing: false,
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function ConfirmationStep({policyID, backTo}: ConfirmationStepProps) {
/>
<MenuItemWithTopDescription
description={translate('workspace.companyCards.card')}
title={data?.cardName}
title={data?.cardNumber}
shouldShowRightIcon
onPress={() => editStep(CONST.COMPANY_CARD.STEP.CARD)}
/>
Expand All @@ -85,6 +85,12 @@ function ConfirmationStep({policyID, backTo}: ConfirmationStepProps) {
shouldShowRightIcon
onPress={() => editStep(CONST.COMPANY_CARD.STEP.TRANSACTION_START_DATE)}
/>
<MenuItemWithTopDescription
description={translate('workspace.companyCards.cardName')}
title={data?.cardName}
shouldShowRightIcon
onPress={() => editStep(CONST.COMPANY_CARD.STEP.CARD_NAME)}
/>
<View style={[styles.mh5, styles.pb5, styles.mt3, styles.flexGrow1, styles.justifyContentEnd]}>
<Button
isDisabled={isOffline}
Expand Down
5 changes: 4 additions & 1 deletion src/types/onyx/AssignCard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ type AssignCardData = {
/** The email address of the assignee */
email: string;

/** Number of the selected card */
/** Encrypted number of the selected card */
encryptedCardNumber: string;

/** Number of the selected card */
cardNumber: string;

/** The name of the feed */
bankName: string;

Expand Down

0 comments on commit 59c7a2e

Please sign in to comment.