Skip to content

Commit 9c5297e

Browse files
authored
Merge pull request Expensify#45473 from VickyStash/feature/44327-edit-card-name
[No QA] Create new Edit Card Name page
2 parents dc85ce8 + fc47ec9 commit 9c5297e

File tree

11 files changed

+132
-2
lines changed

11 files changed

+132
-2
lines changed

src/ONYXKEYS.ts

+3
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,8 @@ const ONYXKEYS = {
572572
SUBSCRIPTION_SIZE_FORM_DRAFT: 'subscriptionSizeFormDraft',
573573
ISSUE_NEW_EXPENSIFY_CARD_FORM: 'issueNewExpensifyCard',
574574
ISSUE_NEW_EXPENSIFY_CARD_FORM_DRAFT: 'issueNewExpensifyCardDraft',
575+
EDIT_EXPENSIFY_CARD_NAME_FORM: 'editExpensifyCardName',
576+
EDIT_EXPENSIFY_CARD_NAME_DRAFT_FORM: 'editExpensifyCardNameDraft',
575577
SAGE_INTACCT_CREDENTIALS_FORM: 'sageIntacctCredentialsForm',
576578
SAGE_INTACCT_CREDENTIALS_FORM_DRAFT: 'sageIntacctCredentialsFormDraft',
577579
NETSUITE_CUSTOM_FIELD_FORM: 'netSuiteCustomFieldForm',
@@ -649,6 +651,7 @@ type OnyxFormValuesMapping = {
649651
[ONYXKEYS.FORMS.NEW_CHAT_NAME_FORM]: FormTypes.NewChatNameForm;
650652
[ONYXKEYS.FORMS.SUBSCRIPTION_SIZE_FORM]: FormTypes.SubscriptionSizeForm;
651653
[ONYXKEYS.FORMS.ISSUE_NEW_EXPENSIFY_CARD_FORM]: FormTypes.IssueNewExpensifyCardForm;
654+
[ONYXKEYS.FORMS.EDIT_EXPENSIFY_CARD_NAME_FORM]: FormTypes.EditExpensifyCardNameForm;
652655
[ONYXKEYS.FORMS.SAGE_INTACCT_CREDENTIALS_FORM]: FormTypes.SageIntactCredentialsForm;
653656
[ONYXKEYS.FORMS.NETSUITE_CUSTOM_FIELD_FORM]: FormTypes.NetSuiteCustomFieldForm;
654657
[ONYXKEYS.FORMS.NETSUITE_CUSTOM_LIST_ADD_FORM]: FormTypes.NetSuiteCustomFieldForm;

src/ROUTES.ts

+4
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,10 @@ const ROUTES = {
866866
route: 'settings/workspaces/:policyID/expensify-card/:cardID',
867867
getRoute: (policyID: string, cardID: string, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/expensify-card/${cardID}`, backTo),
868868
},
869+
WORKSPACE_EXPENSIFY_CARD_NAME: {
870+
route: 'settings/workspaces/:policyID/expensify-card/:cardID/edit/name',
871+
getRoute: (policyID: string, cardID: string) => `settings/workspaces/${policyID}/expensify-card/${cardID}/edit/name` as const,
872+
},
869873
WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW: {
870874
route: 'settings/workspaces/:policyID/expensify-card/issue-new',
871875
getRoute: (policyID: string) => `settings/workspaces/${policyID}/expensify-card/issue-new` as const,

src/SCREENS.ts

+1
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ const SCREENS = {
351351
EXPENSIFY_CARD: 'Workspace_ExpensifyCard',
352352
EXPENSIFY_CARD_DETAILS: 'Workspace_ExpensifyCard_Details',
353353
EXPENSIFY_CARD_ISSUE_NEW: 'Workspace_ExpensifyCard_New',
354+
EXPENSIFY_CARD_NAME: 'Workspace_ExpensifyCard_Name',
354355
EXPENSIFY_CARD_BANK_ACCOUNT: 'Workspace_ExpensifyCard_BankAccount',
355356
BILLS: 'Workspace_Bills',
356357
INVOICES: 'Workspace_Invoices',

src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
416416
[SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW]: () => require<ReactComponentModule>('../../../../pages/workspace/card/issueNew/IssueNewCardPage').default,
417417
[SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts').default,
418418
[SCREENS.WORKSPACE.EXPENSIFY_CARD_DETAILS]: () => require<ReactComponentModule>('../../../../pages/workspace/expensifyCard/WorkspaceExpensifyCardDetailsPage').default,
419+
[SCREENS.WORKSPACE.EXPENSIFY_CARD_NAME]: () => require<ReactComponentModule>('../../../../pages/workspace/expensifyCard/WorkspaceEditCardNamePage').default,
419420
[SCREENS.SETTINGS.SAVE_THE_WORLD]: () => require<ReactComponentModule>('../../../../pages/TeachersUnite/SaveTheWorldPage').default,
420421
[SCREENS.SETTINGS.SUBSCRIPTION.CHANGE_PAYMENT_CURRENCY]: () => require<ReactComponentModule>('../../../../pages/settings/PaymentCard/ChangeCurrency').default,
421422
[SCREENS.SETTINGS.SUBSCRIPTION.CHANGE_BILLING_CURRENCY]: () => require<ReactComponentModule>('../../../../pages/settings/Subscription/PaymentCard/ChangeBillingCurrency').default,

src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,12 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
156156
SCREENS.WORKSPACE.REPORT_FIELDS_EDIT_VALUE,
157157
SCREENS.WORKSPACE.REPORT_FIELDS_EDIT_INITIAL_VALUE,
158158
],
159-
[SCREENS.WORKSPACE.EXPENSIFY_CARD]: [SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW, SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT, SCREENS.WORKSPACE.EXPENSIFY_CARD_DETAILS],
159+
[SCREENS.WORKSPACE.EXPENSIFY_CARD]: [
160+
SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW,
161+
SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT,
162+
SCREENS.WORKSPACE.EXPENSIFY_CARD_DETAILS,
163+
SCREENS.WORKSPACE.EXPENSIFY_CARD_NAME,
164+
],
160165
};
161166

162167
export default FULL_SCREEN_TO_RHP_MAPPING;

src/libs/Navigation/linkingConfig/config.ts

+3
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,9 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
466466
[SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW]: {
467467
path: ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.route,
468468
},
469+
[SCREENS.WORKSPACE.EXPENSIFY_CARD_NAME]: {
470+
path: ROUTES.WORKSPACE_EXPENSIFY_CARD_NAME.route,
471+
},
469472
[SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: {
470473
path: ROUTES.WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT.route,
471474
},

src/libs/Navigation/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,10 @@ type SettingsNavigatorParamList = {
668668
cardID: string;
669669
backTo?: Routes;
670670
};
671+
[SCREENS.WORKSPACE.EXPENSIFY_CARD_NAME]: {
672+
policyID: string;
673+
cardID: string;
674+
};
671675
} & ReimbursementAccountNavigatorParamList;
672676

673677
type NewChatNavigatorParamList = {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import type {StackScreenProps} from '@react-navigation/stack';
2+
import React from 'react';
3+
import {useOnyx} from 'react-native-onyx';
4+
import FormProvider from '@components/Form/FormProvider';
5+
import InputWrapper from '@components/Form/InputWrapper';
6+
import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
7+
import HeaderWithBackButton from '@components/HeaderWithBackButton';
8+
import ScreenWrapper from '@components/ScreenWrapper';
9+
import TextInput from '@components/TextInput';
10+
import useAutoFocusInput from '@hooks/useAutoFocusInput';
11+
import useLocalize from '@hooks/useLocalize';
12+
import useThemeStyles from '@hooks/useThemeStyles';
13+
import * as ValidationUtils from '@libs/ValidationUtils';
14+
import Navigation from '@navigation/Navigation';
15+
import type {SettingsNavigatorParamList} from '@navigation/types';
16+
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
17+
import CONST from '@src/CONST';
18+
import ONYXKEYS from '@src/ONYXKEYS';
19+
import type SCREENS from '@src/SCREENS';
20+
import INPUT_IDS from '@src/types/form/EditExpensifyCardNameForm';
21+
22+
// TODO: remove when Onyx data is available
23+
const mockedCard = {
24+
accountID: 885646,
25+
availableSpend: 1000,
26+
nameValuePairs: {
27+
cardTitle: 'Test 1',
28+
isVirtual: true,
29+
limit: 2000,
30+
limitType: CONST.EXPENSIFY_CARD.LIMIT_TYPES.SMART,
31+
},
32+
lastFourPAN: '1234',
33+
};
34+
35+
type WorkspaceEditCardNamePageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.EXPENSIFY_CARD_NAME>;
36+
37+
function WorkspaceEditCardNamePage({route}: WorkspaceEditCardNamePageProps) {
38+
const {policyID, cardID} = route.params;
39+
40+
const {translate} = useLocalize();
41+
const {inputCallbackRef} = useAutoFocusInput();
42+
const styles = useThemeStyles();
43+
44+
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${policyID}_${CONST.EXPENSIFY_CARD.BANK}`);
45+
const card = cardsList?.[cardID] ?? mockedCard;
46+
47+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
48+
const submit = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_EXPENSIFY_CARD_NAME_FORM>) => {
49+
// TODO: add API call when it's supported https://github.com/Expensify/Expensify/issues/407832
50+
Navigation.goBack();
51+
};
52+
53+
const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.EDIT_EXPENSIFY_CARD_NAME_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.EDIT_EXPENSIFY_CARD_NAME_FORM> =>
54+
ValidationUtils.getFieldRequiredErrors(values, [INPUT_IDS.NAME]);
55+
56+
return (
57+
<AccessOrNotFoundWrapper
58+
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
59+
policyID={policyID}
60+
featureName={CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED}
61+
>
62+
<ScreenWrapper
63+
testID={WorkspaceEditCardNamePage.displayName}
64+
shouldEnablePickerAvoiding={false}
65+
shouldEnableMaxHeight
66+
>
67+
<HeaderWithBackButton title={translate('workspace.card.issueNewCard.cardName')} />
68+
<FormProvider
69+
formID={ONYXKEYS.FORMS.EDIT_EXPENSIFY_CARD_NAME_FORM}
70+
submitButtonText={translate('common.save')}
71+
onSubmit={submit}
72+
style={[styles.flex1, styles.mh5]}
73+
enabledWhenOffline
74+
validate={validate}
75+
>
76+
<InputWrapper
77+
InputComponent={TextInput}
78+
inputID={INPUT_IDS.NAME}
79+
label={translate('workspace.card.issueNewCard.cardName')}
80+
hint={translate('workspace.card.issueNewCard.giveItNameInstruction')}
81+
aria-label={translate('workspace.card.issueNewCard.cardName')}
82+
role={CONST.ROLE.PRESENTATION}
83+
defaultValue={card?.nameValuePairs?.cardTitle}
84+
ref={inputCallbackRef}
85+
/>
86+
</FormProvider>
87+
</ScreenWrapper>
88+
</AccessOrNotFoundWrapper>
89+
);
90+
}
91+
92+
WorkspaceEditCardNamePage.displayName = 'WorkspaceEditCardNamePage';
93+
94+
export default WorkspaceEditCardNamePage;

src/pages/workspace/expensifyCard/WorkspaceExpensifyCardDetailsPage.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
2424
import variables from '@styles/variables';
2525
import CONST from '@src/CONST';
2626
import ONYXKEYS from '@src/ONYXKEYS';
27+
import ROUTES from '@src/ROUTES';
2728
import type SCREENS from '@src/SCREENS';
2829

2930
// TODO: remove when Onyx data is available
@@ -127,7 +128,7 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
127128
description={translate('workspace.card.issueNewCard.cardName')}
128129
title={card.nameValuePairs?.cardTitle}
129130
shouldShowRightIcon
130-
onPress={() => {}} // TODO: navigate to Edit card name page https://github.com/Expensify/App/issues/44327
131+
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_NAME.getRoute(policyID, cardID))}
131132
/>
132133
<MenuItem
133134
icon={Expensicons.Trashcan}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type {ValueOf} from 'type-fest';
2+
import type Form from './Form';
3+
4+
const INPUT_IDS = {
5+
NAME: 'name',
6+
} as const;
7+
8+
type InputID = ValueOf<typeof INPUT_IDS>;
9+
10+
type EditExpensifyCardNameForm = Form<InputID, {[INPUT_IDS.NAME]: string}>;
11+
12+
export type {EditExpensifyCardNameForm};
13+
export default INPUT_IDS;

src/types/form/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type {HomeAddressForm} from './HomeAddressForm';
1010
export type {IKnowTeacherForm} from './IKnowTeacherForm';
1111
export type {IntroSchoolPrincipalForm} from './IntroSchoolPrincipalForm';
1212
export type {IssueNewExpensifyCardForm} from './IssueNewExpensifyCardForm';
13+
export type {EditExpensifyCardNameForm} from './EditExpensifyCardNameForm';
1314
export type {LegalNameForm} from './LegalNameForm';
1415
export type {MoneyRequestAmountForm} from './MoneyRequestAmountForm';
1516
export type {MoneyRequestDateForm} from './MoneyRequestDateForm';

0 commit comments

Comments
 (0)