Skip to content

Commit

Permalink
Merge pull request #29098 from software-mansion-labs/form-migration/e…
Browse files Browse the repository at this point in the history
…dit-request-created-page

Form migration NewDatePicker, DateOfBirthPage, EditRequestCreatedPage
  • Loading branch information
luacmartins authored Oct 11, 2023
2 parents 64d3e39 + afb0282 commit bbb5728
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/components/Form/FormProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function FormProvider({validate, shouldValidateOnBlur, shouldValidateOnChange, c

const onValidate = useCallback(
(values) => {
const validateErrors = validate(values);
const validateErrors = validate(values) || {};
setErrors(validateErrors);
return validateErrors;
},
Expand Down
108 changes: 52 additions & 56 deletions src/components/NewDatePicker/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React from 'react';
import React, {useEffect, useState} from 'react';
import {View} from 'react-native';
import moment from 'moment';
import PropTypes from 'prop-types';
import _ from 'lodash';
import TextInput from '../TextInput';
import CONST from '../../CONST';
import styles from '../../styles/styles';
import * as Expensicons from '../Icon/Expensicons';
import {propTypes as baseTextInputPropTypes, defaultProps as defaultBaseTextInputPropTypes} from '../TextInput/baseTextInputPropTypes';
import {defaultProps as defaultBaseTextInputPropTypes, propTypes as baseTextInputPropTypes} from '../TextInput/baseTextInputPropTypes';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';
import CalendarPicker from './CalendarPicker';
import InputWrapper from '../Form/InputWrapper';

const propTypes = {
/**
Expand All @@ -23,6 +25,8 @@ const propTypes = {
*/
defaultValue: PropTypes.string,

inputID: PropTypes.string.isRequired,

/** A minimum date of calendar to select */
minDate: PropTypes.objectOf(Date),

Expand All @@ -40,66 +44,58 @@ const datePickerDefaultProps = {
value: undefined,
};

class NewDatePicker extends React.Component {
constructor(props) {
super(props);

this.state = {
selectedDate: props.value || props.defaultValue || undefined,
};
function NewDatePicker({containerStyles, defaultValue, disabled, errorText, inputID, isSmallScreenWidth, label, maxDate, minDate, onInputChange, onTouched, placeholder, translate, value}) {
const [selectedDate, setSelectedDate] = useState(value || defaultValue || undefined);

this.setDate = this.setDate.bind(this);
}

componentDidUpdate(prevProps) {
if (prevProps.value === this.props.value) {
useEffect(() => {
if (selectedDate === value || _.isUndefined(value)) {
return;
}
this.setDate(this.props.value);
}
setSelectedDate(value);
}, [selectedDate, value]);

/**
* Trigger the `onInputChange` handler when the user input has a complete date or is cleared
* @param {string} selectedDate
*/
setDate(selectedDate) {
this.setState({selectedDate}, () => {
this.props.onTouched();
this.props.onInputChange(selectedDate);
});
}
useEffect(() => {
if (_.isFunction(onTouched)) {
onTouched();
}
if (_.isFunction(onInputChange)) {
onInputChange(selectedDate);
}
// To keep behavior from class component state update callback, we want to run effect only when the selected date is changed.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedDate]);

render() {
return (
<View style={styles.datePickerRoot}>
<View style={[this.props.isSmallScreenWidth ? styles.flex2 : {}, styles.pointerEventsNone]}>
<TextInput
forceActiveLabel
icon={Expensicons.Calendar}
label={this.props.label}
accessibilityLabel={this.props.label}
accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT}
value={this.props.value || ''}
placeholder={this.props.placeholder || this.props.translate('common.dateFormat')}
errorText={this.props.errorText}
containerStyles={this.props.containerStyles}
textInputContainerStyles={[styles.borderColorFocus]}
inputStyle={[styles.pointerEventsNone]}
disabled={this.props.disabled}
editable={false}
/>
</View>
<View style={[styles.datePickerPopover, styles.border]}>
<CalendarPicker
minDate={this.props.minDate}
maxDate={this.props.maxDate}
value={this.state.selectedDate}
onSelected={this.setDate}
/>
</View>
return (
<View style={styles.datePickerRoot}>
<View style={[isSmallScreenWidth ? styles.flex2 : {}, styles.pointerEventsNone]}>
<InputWrapper
InputComponent={TextInput}
inputID={inputID}
forceActiveLabel
icon={Expensicons.Calendar}
label={label}
accessibilityLabel={label}
accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT}
value={value || selectedDate || ''}
placeholder={placeholder || translate('common.dateFormat')}
errorText={errorText}
containerStyles={containerStyles}
textInputContainerStyles={[styles.borderColorFocus]}
inputStyle={[styles.pointerEventsNone]}
disabled={disabled}
editable={false}
/>
</View>
<View style={[styles.datePickerPopover, styles.border]}>
<CalendarPicker
minDate={minDate}
maxDate={maxDate}
value={selectedDate}
onSelected={setSelectedDate}
/>
</View>
);
}
</View>
);
}

NewDatePicker.propTypes = propTypes;
Expand Down
6 changes: 3 additions & 3 deletions src/pages/EditRequestCreatedPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import React from 'react';
import PropTypes from 'prop-types';
import ScreenWrapper from '../components/ScreenWrapper';
import HeaderWithBackButton from '../components/HeaderWithBackButton';
import Form from '../components/Form';
import ONYXKEYS from '../ONYXKEYS';
import styles from '../styles/styles';
import useLocalize from '../hooks/useLocalize';
import NewDatePicker from '../components/NewDatePicker';
import FormProvider from '../components/Form/FormProvider';

const propTypes = {
/** Transaction defailt created value */
Expand All @@ -26,7 +26,7 @@ function EditRequestCreatedPage({defaultCreated, onSubmit}) {
testID={EditRequestCreatedPage.displayName}
>
<HeaderWithBackButton title={translate('common.date')} />
<Form
<FormProvider
style={[styles.flexGrow1, styles.ph5]}
formID={ONYXKEYS.FORMS.MONEY_REQUEST_DATE_FORM}
onSubmit={onSubmit}
Expand All @@ -39,7 +39,7 @@ function EditRequestCreatedPage({defaultCreated, onSubmit}) {
defaultValue={defaultCreated}
maxDate={new Date()}
/>
</Form>
</FormProvider>
</ScreenWrapper>
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/pages/iou/MoneyRequestDatePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import _ from 'underscore';
import lodashGet from 'lodash/get';
import ScreenWrapper from '../../components/ScreenWrapper';
import HeaderWithBackButton from '../../components/HeaderWithBackButton';
import Form from '../../components/Form';
import ONYXKEYS from '../../ONYXKEYS';
import styles from '../../styles/styles';
import Navigation from '../../libs/Navigation/Navigation';
Expand All @@ -16,6 +15,7 @@ import NewDatePicker from '../../components/NewDatePicker';
import useLocalize from '../../hooks/useLocalize';
import CONST from '../../CONST';
import {iouPropTypes, iouDefaultProps} from './propTypes';
import FormProvider from '../../components/Form/FormProvider';

const propTypes = {
/** Onyx Props */
Expand Down Expand Up @@ -91,7 +91,7 @@ function MoneyRequestDatePage({iou, route, selectedTab}) {
title={translate('common.date')}
onBackButtonPress={() => navigateBack()}
/>
<Form
<FormProvider
style={[styles.flexGrow1, styles.ph5]}
formID={ONYXKEYS.FORMS.MONEY_REQUEST_DATE_FORM}
onSubmit={(value) => updateDate(value)}
Expand All @@ -104,7 +104,7 @@ function MoneyRequestDatePage({iou, route, selectedTab}) {
defaultValue={iou.created}
maxDate={new Date()}
/>
</Form>
</FormProvider>
</ScreenWrapper>
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {subYears} from 'date-fns';
import CONST from '../../../../CONST';
import ONYXKEYS from '../../../../ONYXKEYS';
import ROUTES from '../../../../ROUTES';
import Form from '../../../../components/Form';
import HeaderWithBackButton from '../../../../components/HeaderWithBackButton';
import NewDatePicker from '../../../../components/NewDatePicker';
import ScreenWrapper from '../../../../components/ScreenWrapper';
Expand All @@ -18,6 +17,7 @@ import compose from '../../../../libs/compose';
import styles from '../../../../styles/styles';
import usePrivatePersonalDetails from '../../../../hooks/usePrivatePersonalDetails';
import FullscreenLoadingIndicator from '../../../../components/FullscreenLoadingIndicator';
import FormProvider from '../../../../components/Form/FormProvider';

const propTypes = {
/* Onyx Props */
Expand Down Expand Up @@ -72,7 +72,7 @@ function DateOfBirthPage({translate, privatePersonalDetails}) {
{isLoadingPersonalDetails ? (
<FullscreenLoadingIndicator style={[styles.flex1, styles.pRelative]} />
) : (
<Form
<FormProvider
style={[styles.flexGrow1, styles.ph5]}
formID={ONYXKEYS.FORMS.DATE_OF_BIRTH_FORM}
validate={validate}
Expand All @@ -87,7 +87,7 @@ function DateOfBirthPage({translate, privatePersonalDetails}) {
minDate={subYears(new Date(), CONST.DATE_BIRTH.MAX_AGE)}
maxDate={subYears(new Date(), CONST.DATE_BIRTH.MIN_AGE)}
/>
</Form>
</FormProvider>
)}
</ScreenWrapper>
);
Expand Down

0 comments on commit bbb5728

Please sign in to comment.