Skip to content

Commit 3c4b56c

Browse files
committed
refactor into functional component
1 parent 7129342 commit 3c4b56c

File tree

1 file changed

+85
-107
lines changed

1 file changed

+85
-107
lines changed

src/pages/workspace/reimburse/WorkspaceRateAndUnitPage.js

+85-107
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import lodashGet from 'lodash/get';
2-
import React from 'react';
2+
import React, {useCallback, useEffect} from 'react';
33
import {Keyboard, View} from 'react-native';
44
import {withOnyx} from 'react-native-onyx';
55
import _ from 'underscore';
@@ -36,56 +36,34 @@ const defaultProps = {
3636
...policyDefaultProps,
3737
};
3838

39-
class WorkspaceRateAndUnitPage extends React.Component {
40-
constructor(props) {
41-
super(props);
42-
this.submit = this.submit.bind(this);
43-
this.validate = this.validate.bind(this);
44-
}
45-
46-
componentDidMount() {
47-
if (lodashGet(this.props, 'policy.customUnits', []).length !== 0) {
39+
function WorkspaceRateAndUnitPage(props) {
40+
const fetchData = useCallback(() => {
41+
if (lodashGet(props, 'policy.customUnits', []).length !== 0) {
4842
return;
4943
}
50-
// When this page is accessed directly from url, the policy.customUnits data won't be available,
51-
// and we should trigger Policy.openWorkspaceReimburseView to get the data
5244

5345
BankAccounts.setReimbursementAccountLoading(true);
54-
Policy.openWorkspaceReimburseView(this.props.policy.id);
55-
}
56-
57-
getUnitItems() {
58-
return [
59-
{label: this.props.translate('common.kilometers'), value: CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS},
60-
{label: this.props.translate('common.miles'), value: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES},
61-
];
62-
}
46+
Policy.openWorkspaceReimburseView(props.policy.id);
47+
}, [props]);
6348

64-
getRateDisplayValue(value) {
65-
const numValue = this.getNumericValue(value);
66-
if (Number.isNaN(numValue)) {
67-
return '';
68-
}
69-
return numValue.toString().replace('.', this.props.toLocaleDigit('.')).substring(0, value.length);
70-
}
49+
useEffect(() => {
50+
fetchData();
51+
}, [fetchData]);
7152

72-
getNumericValue(value) {
73-
const numValue = NumberUtils.parseFloatAnyLocale(value.toString());
74-
if (Number.isNaN(numValue)) {
75-
return NaN;
76-
}
77-
return numValue.toFixed(3);
78-
}
53+
const getUnitItems = () => [
54+
{label: props.translate('common.kilometers'), value: CONST.CUSTOM_UNITS.DISTANCE_UNIT_KILOMETERS},
55+
{label: props.translate('common.miles'), value: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES},
56+
];
7957

80-
saveUnitAndRate(unit, rate) {
81-
const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), (u) => u.name === CONST.CUSTOM_UNITS.NAME_DISTANCE);
58+
const saveUnitAndRate = (unit, rate) => {
59+
const distanceCustomUnit = _.find(lodashGet(props, 'policy.customUnits', {}), (u) => u.name === CONST.CUSTOM_UNITS.NAME_DISTANCE);
8260
if (!distanceCustomUnit) {
8361
return;
8462
}
8563
const currentCustomUnitRate = _.find(lodashGet(distanceCustomUnit, 'rates', {}), (r) => r.name === CONST.CUSTOM_UNITS.DEFAULT_RATE);
8664
const unitID = lodashGet(distanceCustomUnit, 'customUnitID', '');
8765
const unitName = lodashGet(distanceCustomUnit, 'name', '');
88-
const rateNumValue = PolicyUtils.getNumericValue(rate, this.props.toLocaleDigit);
66+
const rateNumValue = PolicyUtils.getNumericValue(rate, props.toLocaleDigit);
8967

9068
const newCustomUnit = {
9169
customUnitID: unitID,
@@ -96,19 +74,19 @@ class WorkspaceRateAndUnitPage extends React.Component {
9674
rate: rateNumValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET,
9775
},
9876
};
99-
Policy.updateWorkspaceCustomUnitAndRate(this.props.policy.id, distanceCustomUnit, newCustomUnit, this.props.policy.lastModified);
100-
}
77+
Policy.updateWorkspaceCustomUnitAndRate(props.policy.id, distanceCustomUnit, newCustomUnit, props.policy.lastModified);
78+
};
10179

102-
submit(values) {
103-
this.saveUnitAndRate(values.unit, values.rate);
80+
const submit = (values) => {
81+
saveUnitAndRate(values.unit, values.rate);
10482
Keyboard.dismiss();
105-
Navigation.goBack(ROUTES.WORKSPACE_REIMBURSE.getRoute(this.props.policy.id));
106-
}
83+
Navigation.goBack(ROUTES.WORKSPACE_REIMBURSE.getRoute(props.policy.id));
84+
};
10785

108-
validate(values) {
86+
const validate = (values) => {
10987
const errors = {};
110-
const decimalSeparator = this.props.toLocaleDigit('.');
111-
const outputCurrency = lodashGet(this.props, 'policy.outputCurrency', CONST.CURRENCY.USD);
88+
const decimalSeparator = props.toLocaleDigit('.');
89+
const outputCurrency = lodashGet(props, 'policy.outputCurrency', CONST.CURRENCY.USD);
11290
// Allow one more decimal place for accuracy
11391
const rateValueRegex = RegExp(String.raw`^-?\d{0,8}([${getPermittedDecimalSeparator(decimalSeparator)}]\d{1,${CurrencyUtils.getCurrencyDecimals(outputCurrency) + 1}})?$`, 'i');
11492
if (!rateValueRegex.test(values.rate) || values.rate === '') {
@@ -117,73 +95,73 @@ class WorkspaceRateAndUnitPage extends React.Component {
11795
errors.rate = 'workspace.reimburse.lowRateError';
11896
}
11997
return errors;
120-
}
121-
122-
render() {
123-
const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), (unit) => unit.name === CONST.CUSTOM_UNITS.NAME_DISTANCE);
124-
const distanceCustomRate = _.find(lodashGet(distanceCustomUnit, 'rates', {}), (rate) => rate.name === CONST.CUSTOM_UNITS.DEFAULT_RATE);
125-
return (
126-
<WorkspacePageWithSections
127-
headerText={this.props.translate('workspace.reimburse.trackDistance')}
128-
route={this.props.route}
129-
guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_REIMBURSE}
130-
shouldSkipVBBACall
131-
backButtonRoute={ROUTES.WORKSPACE_REIMBURSE.getRoute(this.props.policy.id)}
132-
>
133-
{() => (
134-
<FormProvider
135-
formID={ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM}
136-
submitButtonText={this.props.translate('common.save')}
137-
style={[this.props.themeStyles.mh5, this.props.themeStyles.flexGrow1]}
138-
scrollContextEnabled
139-
validate={this.validate}
140-
onSubmit={this.submit}
141-
enabledWhenOffline
98+
};
99+
100+
const distanceCustomUnit = _.find(lodashGet(props, 'policy.customUnits', {}), (unit) => unit.name === CONST.CUSTOM_UNITS.NAME_DISTANCE);
101+
const distanceCustomRate = _.find(lodashGet(distanceCustomUnit, 'rates', {}), (rate) => rate.name === CONST.CUSTOM_UNITS.DEFAULT_RATE);
102+
103+
return (
104+
<WorkspacePageWithSections
105+
headerText={props.translate('workspace.reimburse.trackDistance')}
106+
route={props.route}
107+
guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_REIMBURSE}
108+
shouldSkipVBBACall
109+
backButtonRoute={ROUTES.WORKSPACE_REIMBURSE.getRoute(props.policy.id)}
110+
>
111+
{() => (
112+
<FormProvider
113+
formID={ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM}
114+
submitButtonText={props.translate('common.save')}
115+
style={[props.themeStyles.mh5, props.themeStyles.flexGrow1]}
116+
scrollContextEnabled
117+
validate={validate}
118+
onSubmit={submit}
119+
enabledWhenOffline
120+
>
121+
<OfflineWithFeedback
122+
errors={{
123+
...lodashGet(distanceCustomUnit, 'errors', {}),
124+
...lodashGet(distanceCustomRate, 'errors', {}),
125+
}}
126+
pendingAction={lodashGet(distanceCustomUnit, 'pendingAction') || lodashGet(distanceCustomRate, 'pendingAction')}
127+
onClose={() =>
128+
Policy.clearCustomUnitErrors(props.policy.id, lodashGet(distanceCustomUnit, 'customUnitID', ''), lodashGet(distanceCustomRate, 'customUnitRateID', ''))
129+
}
142130
>
143-
<OfflineWithFeedback
144-
errors={{
145-
...lodashGet(distanceCustomUnit, 'errors', {}),
146-
...lodashGet(distanceCustomRate, 'errors', {}),
147-
}}
148-
pendingAction={lodashGet(distanceCustomUnit, 'pendingAction') || lodashGet(distanceCustomRate, 'pendingAction')}
149-
onClose={() =>
150-
Policy.clearCustomUnitErrors(this.props.policy.id, lodashGet(distanceCustomUnit, 'customUnitID', ''), lodashGet(distanceCustomRate, 'customUnitRateID', ''))
151-
}
152-
>
131+
<InputWrapper
132+
InputComponent={TextInput}
133+
role={CONST.ACCESSIBILITY_ROLE.TEXT}
134+
inputID="rate"
135+
containerStyles={[props.themeStyles.mt4]}
136+
defaultValue={PolicyUtils.getUnitRateValue(distanceCustomRate, props.toLocaleDigit)}
137+
label={props.translate('workspace.reimburse.trackDistanceRate')}
138+
aria-label={props.translate('workspace.reimburse.trackDistanceRate')}
139+
placeholder={lodashGet(props, 'policy.outputCurrency', CONST.CURRENCY.USD)}
140+
autoCompleteType="off"
141+
autoCorrect={false}
142+
inputMode={CONST.INPUT_MODE.DECIMAL}
143+
maxLength={12}
144+
/>
145+
146+
<View style={[props.themeStyles.mt4]}>
153147
<InputWrapper
154-
InputComponent={TextInput}
155-
role={CONST.ACCESSIBILITY_ROLE.TEXT}
156-
inputID="rate"
157-
containerStyles={[this.props.themeStyles.mt4]}
158-
defaultValue={PolicyUtils.getUnitRateValue(distanceCustomRate, this.props.toLocaleDigit)}
159-
label={this.props.translate('workspace.reimburse.trackDistanceRate')}
160-
aria-label={this.props.translate('workspace.reimburse.trackDistanceRate')}
161-
placeholder={lodashGet(this.props, 'policy.outputCurrency', CONST.CURRENCY.USD)}
162-
autoCompleteType="off"
163-
autoCorrect={false}
164-
inputMode={CONST.INPUT_MODE.DECIMAL}
165-
maxLength={12}
148+
InputComponent={Picker}
149+
inputID="unit"
150+
label={props.translate('workspace.reimburse.trackDistanceUnit')}
151+
items={getUnitItems()}
152+
defaultValue={lodashGet(distanceCustomUnit, 'attributes.unit', CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES)}
166153
/>
167-
168-
<View style={[this.props.themeStyles.mt4]}>
169-
<InputWrapper
170-
InputComponent={Picker}
171-
inputID="unit"
172-
label={this.props.translate('workspace.reimburse.trackDistanceUnit')}
173-
items={this.getUnitItems()}
174-
defaultValue={lodashGet(distanceCustomUnit, 'attributes.unit', CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES)}
175-
/>
176-
</View>
177-
</OfflineWithFeedback>
178-
</FormProvider>
179-
)}
180-
</WorkspacePageWithSections>
181-
);
182-
}
154+
</View>
155+
</OfflineWithFeedback>
156+
</FormProvider>
157+
)}
158+
</WorkspacePageWithSections>
159+
);
183160
}
184161

185162
WorkspaceRateAndUnitPage.propTypes = propTypes;
186163
WorkspaceRateAndUnitPage.defaultProps = defaultProps;
164+
WorkspaceRateAndUnitPage.displayName = 'WorkspaceRateAndUnitPage';
187165

188166
export default compose(
189167
withPolicy,

0 commit comments

Comments
 (0)