Add create profile form validation
This commit is contained in:
parent
0a4461bbe4
commit
81277d0d75
@ -16,7 +16,6 @@
|
|||||||
"formik": "^2.2.6",
|
"formik": "^2.2.6",
|
||||||
"history": "4.10.1",
|
"history": "4.10.1",
|
||||||
"immer": "^8.0.0",
|
"immer": "^8.0.0",
|
||||||
"joi": "^17.3.0",
|
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"quagga": "^0.12.1",
|
"quagga": "^0.12.1",
|
||||||
@ -31,7 +30,8 @@
|
|||||||
"redux-saga": "^1.1.3",
|
"redux-saga": "^1.1.3",
|
||||||
"reselect": "^4.0.0",
|
"reselect": "^4.0.0",
|
||||||
"web-vitals": "^0.2.4",
|
"web-vitals": "^0.2.4",
|
||||||
"yarn": "^1.22.10"
|
"yarn": "^1.22.10",
|
||||||
|
"yup": "^0.32.8"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
@ -4,9 +4,10 @@ import { useField } from 'formik';
|
|||||||
import { TextField } from '@material-ui/core';
|
import { TextField } from '@material-ui/core';
|
||||||
|
|
||||||
const InputField = (props) => {
|
const InputField = (props) => {
|
||||||
|
const { errorText, ...rest } = props;
|
||||||
const [field, meta] = useField(props);
|
const [field, meta] = useField(props);
|
||||||
|
|
||||||
const _renderHelperText = () => {
|
const renderHelperText = () => {
|
||||||
const [touched, error] = at(meta, 'touched', 'error');
|
const [touched, error] = at(meta, 'touched', 'error');
|
||||||
if (touched && error) {
|
if (touched && error) {
|
||||||
return error;
|
return error;
|
||||||
@ -17,9 +18,9 @@ const InputField = (props) => {
|
|||||||
<TextField
|
<TextField
|
||||||
type="text"
|
type="text"
|
||||||
error={meta.touched && meta.error && true}
|
error={meta.touched && meta.error && true}
|
||||||
helperText={_renderHelperText()}
|
helperText={renderHelperText()}
|
||||||
{...field}
|
{...field}
|
||||||
{...props}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,132 +0,0 @@
|
|||||||
import 'date-fns';
|
|
||||||
import React from 'react';
|
|
||||||
import {Typography, InputLabel, Box, Grid, InputAdornment, Select, FormControl, MenuItem, TextField, Slider} from '@material-ui/core';
|
|
||||||
import DateFnsUtils from '@date-io/date-fns';
|
|
||||||
import { useFormContext, Controller } from "react-hook-form";
|
|
||||||
import {
|
|
||||||
MuiPickersUtilsProvider,
|
|
||||||
DatePicker,
|
|
||||||
} from '@material-ui/pickers';
|
|
||||||
import {useInjectReducer} from "redux-injectors";
|
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import {createStructuredSelector} from "reselect";
|
|
||||||
import reducer from "pages/Profile/reducer";
|
|
||||||
import {
|
|
||||||
makeSelectActivities,
|
|
||||||
makeSelectGenders,
|
|
||||||
} from "pages/Profile/selectors";
|
|
||||||
|
|
||||||
const stateSelector = createStructuredSelector({
|
|
||||||
activities: makeSelectActivities(),
|
|
||||||
genders: makeSelectGenders(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const key = 'profilePage'
|
|
||||||
const PersonalDetailsForm = () => {
|
|
||||||
useInjectReducer({ key, reducer });
|
|
||||||
const { activities, genders } = useSelector(stateSelector)
|
|
||||||
const { register, control } = useFormContext()
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Typography variant="h6" gutterBottom>
|
|
||||||
Personal details
|
|
||||||
</Typography>
|
|
||||||
<Grid container spacing={3}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<FormControl variant="outlined" fullWidth>
|
|
||||||
<InputLabel>Gender</InputLabel>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="gender"
|
|
||||||
as={
|
|
||||||
<Select
|
|
||||||
label="Gender"
|
|
||||||
name="gender"
|
|
||||||
>
|
|
||||||
{genders.map(label => (
|
|
||||||
<MenuItem value={label} key={label}>{label}</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
onChange={([selected]) => selected}
|
|
||||||
name="birthday"
|
|
||||||
render={({ onChange, value }) => (
|
|
||||||
<MuiPickersUtilsProvider utils={DateFnsUtils}>
|
|
||||||
<DatePicker
|
|
||||||
disableFuture
|
|
||||||
fullWidth
|
|
||||||
openTo="year"
|
|
||||||
format="dd/MM/yyyy"
|
|
||||||
label="Date of birth"
|
|
||||||
views={["year", "month", "date"]}
|
|
||||||
onChange={onChange}
|
|
||||||
value={value}
|
|
||||||
/>
|
|
||||||
</MuiPickersUtilsProvider>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="height"
|
|
||||||
as={
|
|
||||||
<TextField
|
|
||||||
type="number"
|
|
||||||
label="Height"
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
InputProps={{
|
|
||||||
endAdornment: <InputAdornment position="end">cm</InputAdornment>
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="weight.current"
|
|
||||||
as={
|
|
||||||
<TextField
|
|
||||||
type="number"
|
|
||||||
label="Current Weight"
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
InputProps={{
|
|
||||||
endAdornment: <InputAdornment position="end">Kg</InputAdornment>
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="weight.goal"
|
|
||||||
as={
|
|
||||||
<TextField
|
|
||||||
type="number"
|
|
||||||
label="Goal Weight"
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
InputProps={{
|
|
||||||
endAdornment: <InputAdornment position="end">Kg</InputAdornment>
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export default PersonalDetailsForm
|
|
@ -16,7 +16,7 @@ const SelectField = ({ label, data, ...rest }) => {
|
|||||||
const [touched, error] = at(meta, 'touched', 'error');
|
const [touched, error] = at(meta, 'touched', 'error');
|
||||||
const isError = touched && error && true;
|
const isError = touched && error && true;
|
||||||
|
|
||||||
const _renderHelperText = () => {
|
const renderHelperText = () => {
|
||||||
if (isError) {
|
if (isError) {
|
||||||
return <FormHelperText>{error}</FormHelperText>;
|
return <FormHelperText>{error}</FormHelperText>;
|
||||||
}
|
}
|
||||||
@ -32,16 +32,13 @@ const SelectField = ({ label, data, ...rest }) => {
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
{_renderHelperText()}
|
{renderHelperText()}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectField.defaultProps = {
|
|
||||||
data: []
|
|
||||||
};
|
|
||||||
|
|
||||||
SelectField.propTypes = {
|
SelectField.propTypes = {
|
||||||
|
label: PropTypes.string.isRequired,
|
||||||
data: PropTypes.array.isRequired
|
data: PropTypes.array.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
26
src/pages/Profile/FormModel/formInitialValues.js
Normal file
26
src/pages/Profile/FormModel/formInitialValues.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import checkoutFormModel from './profileFormModel';
|
||||||
|
const {
|
||||||
|
formField: {
|
||||||
|
gender,
|
||||||
|
goal,
|
||||||
|
birthday,
|
||||||
|
height,
|
||||||
|
currentWeight,
|
||||||
|
goalWeight,
|
||||||
|
rateOfChange,
|
||||||
|
activity
|
||||||
|
}
|
||||||
|
} = checkoutFormModel;
|
||||||
|
|
||||||
|
const formInitialValues = {
|
||||||
|
[gender.name]: '',
|
||||||
|
[goal.name]: '',
|
||||||
|
[birthday.name]: '',
|
||||||
|
[height.name]: '',
|
||||||
|
[currentWeight.name]: '',
|
||||||
|
[goalWeight.name]: '',
|
||||||
|
[rateOfChange.name]: '',
|
||||||
|
[activity.name]: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default formInitialValues
|
51
src/pages/Profile/FormModel/profileFormModel.js
Normal file
51
src/pages/Profile/FormModel/profileFormModel.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
const profileFormModel = {
|
||||||
|
formId: 'createProfileForm',
|
||||||
|
formField: {
|
||||||
|
gender: {
|
||||||
|
name: 'gender',
|
||||||
|
label: 'Gender*',
|
||||||
|
requiredErrorMsg: 'Gender is required'
|
||||||
|
},
|
||||||
|
goal: {
|
||||||
|
name: 'goal',
|
||||||
|
label: 'Goal*',
|
||||||
|
requiredErrorMsg: 'Goal is required'
|
||||||
|
},
|
||||||
|
birthday: {
|
||||||
|
name: 'birthday',
|
||||||
|
label: 'Birthday*',
|
||||||
|
requiredErrorMsg: 'Birthday date is required',
|
||||||
|
invalidErrorMsg: 'Birthday date is not valid'
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
name: 'height',
|
||||||
|
label: 'Height*',
|
||||||
|
requiredErrorMsg: 'Height is required',
|
||||||
|
invalidErrorMsg: 'Height is invalid (e.g. 175)'
|
||||||
|
},
|
||||||
|
currentWeight: {
|
||||||
|
name: 'currentWeight',
|
||||||
|
label: 'Current weight*',
|
||||||
|
requiredErrorMsg: 'Current weight is required',
|
||||||
|
invalidErrorMsg: 'Current weight is invalid (e.g. 75)'
|
||||||
|
},
|
||||||
|
goalWeight: {
|
||||||
|
name: 'goalWeight',
|
||||||
|
label: 'Goal weight*',
|
||||||
|
requiredErrorMsg: 'Goal weight is required',
|
||||||
|
invalidErrorMsg: 'Goal weight is invalid (e.g. 70)'
|
||||||
|
},
|
||||||
|
rateOfChange: {
|
||||||
|
name: 'rateOfChange',
|
||||||
|
label: 'Rate of change*',
|
||||||
|
requiredErrorMsg: 'Rate of change is required'
|
||||||
|
},
|
||||||
|
activity: {
|
||||||
|
name: 'activity',
|
||||||
|
label: 'Activity*',
|
||||||
|
requiredErrorMsg: 'Activity is required'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default profileFormModel
|
46
src/pages/Profile/FormModel/validationSchema.js
Normal file
46
src/pages/Profile/FormModel/validationSchema.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import * as Yup from 'yup';
|
||||||
|
import checkoutFormModel from './profileFormModel';
|
||||||
|
const {
|
||||||
|
formField: {
|
||||||
|
gender,
|
||||||
|
goal,
|
||||||
|
birthday,
|
||||||
|
height,
|
||||||
|
currentWeight,
|
||||||
|
goalWeight,
|
||||||
|
rateOfChange,
|
||||||
|
activity
|
||||||
|
}
|
||||||
|
} = checkoutFormModel;
|
||||||
|
|
||||||
|
const validationSchema = [
|
||||||
|
Yup.object().shape({
|
||||||
|
[goal.name]: Yup.string().required(`${goal.requiredErrorMsg}`),
|
||||||
|
[rateOfChange.name]: Yup.string().required(`${goal.requiredErrorMsg}`),
|
||||||
|
[activity.name]: Yup.string().required(`${activity.requiredErrorMsg}`),
|
||||||
|
}),
|
||||||
|
Yup.object().shape({
|
||||||
|
[gender.name]: Yup.string().required(`${gender.requiredErrorMsg}`),
|
||||||
|
[birthday.name]: Yup.string().required(`${birthday.requiredErrorMsg}`),
|
||||||
|
[height.name]: Yup.string().required(`${height.requiredErrorMsg}`)
|
||||||
|
.test(
|
||||||
|
'len',
|
||||||
|
`${height.invalidErrorMsg}`,
|
||||||
|
value => value && value.toString().length === 3
|
||||||
|
),
|
||||||
|
[currentWeight.name]: Yup.string().required(`${currentWeight.requiredErrorMsg}`)
|
||||||
|
.test(
|
||||||
|
'len',
|
||||||
|
`${currentWeight.invalidErrorMsg}`,
|
||||||
|
value => value && value.toString().length >= 2 && value.toString().length <= 3
|
||||||
|
),
|
||||||
|
[goalWeight.name]: Yup.string().required(`${goalWeight.requiredErrorMsg}`)
|
||||||
|
.test(
|
||||||
|
'len',
|
||||||
|
`${goalWeight.invalidErrorMsg}`,
|
||||||
|
value => value && value.toString().length >= 2 && value.toString().length <= 3
|
||||||
|
),
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
export default validationSchema
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Grid, Typography, Box} from '@material-ui/core';
|
import {Grid, Typography} from '@material-ui/core';
|
||||||
import {useInjectReducer} from "redux-injectors";
|
import {useInjectReducer} from "redux-injectors";
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import {createStructuredSelector} from "reselect";
|
import {createStructuredSelector} from "reselect";
|
||||||
@ -19,7 +19,13 @@ const stateSelector = createStructuredSelector({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const key = 'profilePage'
|
const key = 'profilePage'
|
||||||
const GoalForm = () => {
|
const GoalForm = ({
|
||||||
|
formField: {
|
||||||
|
rateOfChange,
|
||||||
|
goal,
|
||||||
|
activity
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
useInjectReducer({ key, reducer });
|
useInjectReducer({ key, reducer });
|
||||||
const { goals, activities, ratesOfChange } = useSelector(stateSelector)
|
const { goals, activities, ratesOfChange } = useSelector(stateSelector)
|
||||||
|
|
||||||
@ -30,19 +36,19 @@ const GoalForm = () => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<SelectField label="goal" name="goal" data={goals} fullWidth />
|
<SelectField label={goal.label} name={goal.name} data={goals} fullWidth />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="h6" gutterBottom>
|
<Typography variant="h6" gutterBottom>
|
||||||
Activity
|
Activity
|
||||||
</Typography>
|
</Typography>
|
||||||
<SelectField label="activity" name="activity" data={activities} fullWidth />
|
<SelectField label={activity.label} name={activity.name} data={activities} fullWidth />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="h6" gutterBottom>
|
<Typography variant="h6" gutterBottom>
|
||||||
Rate of change
|
Rate of change
|
||||||
</Typography>
|
</Typography>
|
||||||
<SelectField label="Rate of Change" name="rateOfChange" data={ratesOfChange} fullWidth />
|
<SelectField label={rateOfChange.label} name={rateOfChange.name} data={ratesOfChange} fullWidth />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
@ -1,6 +1,6 @@
|
|||||||
import 'date-fns';
|
import 'date-fns';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Typography, InputLabel, Grid, InputAdornment, Select, FormControl, MenuItem, TextField, Slider} from '@material-ui/core';
|
import {Typography, Grid, InputAdornment} from '@material-ui/core';
|
||||||
import DatePickerField from 'components/DatePickerField'
|
import DatePickerField from 'components/DatePickerField'
|
||||||
import InputField from 'components/InputField'
|
import InputField from 'components/InputField'
|
||||||
import {useInjectReducer} from "redux-injectors";
|
import {useInjectReducer} from "redux-injectors";
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
makeSelectActivities,
|
makeSelectActivities,
|
||||||
makeSelectGenders,
|
makeSelectGenders,
|
||||||
} from "pages/Profile/selectors";
|
} from "pages/Profile/selectors";
|
||||||
import SelectField from "../../../components/SelectField";
|
import SelectField from "components/SelectField";
|
||||||
|
|
||||||
const stateSelector = createStructuredSelector({
|
const stateSelector = createStructuredSelector({
|
||||||
activities: makeSelectActivities(),
|
activities: makeSelectActivities(),
|
||||||
@ -19,7 +19,15 @@ const stateSelector = createStructuredSelector({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const key = 'profilePage'
|
const key = 'profilePage'
|
||||||
const PersonalDetailsForm = () => {
|
const Index = ({
|
||||||
|
formField: {
|
||||||
|
gender,
|
||||||
|
birthday,
|
||||||
|
height,
|
||||||
|
currentWeight,
|
||||||
|
goalWeight,
|
||||||
|
}
|
||||||
|
}) => {
|
||||||
useInjectReducer({ key, reducer });
|
useInjectReducer({ key, reducer });
|
||||||
const { genders } = useSelector(stateSelector)
|
const { genders } = useSelector(stateSelector)
|
||||||
|
|
||||||
@ -30,12 +38,12 @@ const PersonalDetailsForm = () => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<SelectField label="gender" name="gender" data={genders} fullWidth />
|
<SelectField label={gender.label} name={gender.name} data={genders} fullWidth />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<DatePickerField
|
<DatePickerField
|
||||||
name="birthday"
|
label={birthday.label}
|
||||||
label="birthday"
|
name={birthday.name}
|
||||||
format="MM/yy"
|
format="MM/yy"
|
||||||
views={['year', 'month']}
|
views={['year', 'month']}
|
||||||
minDate={new Date('1900/01/01')}
|
minDate={new Date('1900/01/01')}
|
||||||
@ -46,8 +54,8 @@ const PersonalDetailsForm = () => {
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<InputField
|
<InputField
|
||||||
type="number"
|
type="number"
|
||||||
name="height"
|
label={height.label}
|
||||||
label="Height"
|
name={height.name}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
InputProps={{
|
InputProps={{
|
||||||
@ -58,8 +66,8 @@ const PersonalDetailsForm = () => {
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<InputField
|
<InputField
|
||||||
type="number"
|
type="number"
|
||||||
label="Current Weight"
|
label={currentWeight.label}
|
||||||
name="weight.current"
|
name={currentWeight.name}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
InputProps={{
|
InputProps={{
|
||||||
@ -70,8 +78,8 @@ const PersonalDetailsForm = () => {
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<InputField
|
<InputField
|
||||||
type="number"
|
type="number"
|
||||||
label="Goal Weight"
|
label={goalWeight.label}
|
||||||
name="weight.goal"
|
name={goalWeight.name}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
InputProps={{
|
InputProps={{
|
||||||
@ -83,4 +91,4 @@ const PersonalDetailsForm = () => {
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
export default PersonalDetailsForm
|
export default Index
|
@ -1,11 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
const ReviewProfileForm = () => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
ReviewProfileForm
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ReviewProfileForm;
|
|
@ -38,13 +38,13 @@ export const updateProfileAction = () => ({
|
|||||||
type: UPDATE_PROFILE_REQUEST,
|
type: UPDATE_PROFILE_REQUEST,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const updateProfileSuccessAction = ({birthday, goal, gender, height, weight, goalWeight, rateOfChange, activity}) => ({
|
export const updateProfileSuccessAction = ({birthday, goal, gender, height, currentWeight, goalWeight, rateOfChange, activity}) => ({
|
||||||
type: UPDATE_PROFILE_SUCCESS,
|
type: UPDATE_PROFILE_SUCCESS,
|
||||||
birthday,
|
birthday,
|
||||||
gender,
|
gender,
|
||||||
goal,
|
goal,
|
||||||
height,
|
height,
|
||||||
weight,
|
currentWeight,
|
||||||
goalWeight,
|
goalWeight,
|
||||||
rateOfChange,
|
rateOfChange,
|
||||||
activity
|
activity
|
||||||
|
@ -1,57 +1,27 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
|
||||||
import {Paper, Stepper, Step, StepLabel, Button, Typography } from '@material-ui/core';
|
import {Paper, Stepper, Step, StepLabel, Button, Typography } from '@material-ui/core';
|
||||||
import {useInjectReducer, useInjectSaga} from "redux-injectors";
|
import {useInjectReducer, useInjectSaga} from "redux-injectors";
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { Formik, Form } from 'formik';
|
import { Formik, Form } from 'formik';
|
||||||
import GoalForm from './GoalForm';
|
import GoalForm from './Forms/GoalForm';
|
||||||
import PersonalDetailsForm from './PersonalDetailsForm';
|
import PersonalDetailsForm from './Forms/PersonalDetailsForm';
|
||||||
import ReviewProfileForm from './ReviewProfileForm';
|
import ReviewProfileForm from './Forms/ReviewProfileForm';
|
||||||
import reducer from "./reducer";
|
import reducer from "./reducer";
|
||||||
import saga from "./saga";
|
import saga from "./saga";
|
||||||
|
import useStyles from './styles';
|
||||||
const useStyles = makeStyles((theme) => ({
|
import validationSchema from './FormModel/validationSchema'
|
||||||
layout: {
|
import formInitialValues from './FormModel/formInitialValues'
|
||||||
width: 'auto',
|
import profileFormModel from './FormModel/profileFormModel'
|
||||||
marginLeft: theme.spacing(2),
|
|
||||||
marginRight: theme.spacing(2),
|
|
||||||
[theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {
|
|
||||||
width: 600,
|
|
||||||
marginLeft: 'auto',
|
|
||||||
marginRight: 'auto',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
paper: {
|
|
||||||
marginTop: theme.spacing(3),
|
|
||||||
marginBottom: theme.spacing(3),
|
|
||||||
padding: theme.spacing(2),
|
|
||||||
[theme.breakpoints.up(600 + theme.spacing(3) * 2)]: {
|
|
||||||
marginTop: theme.spacing(6),
|
|
||||||
marginBottom: theme.spacing(6),
|
|
||||||
padding: theme.spacing(3),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
stepper: {
|
|
||||||
padding: theme.spacing(3, 0, 5),
|
|
||||||
},
|
|
||||||
buttons: {
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'flex-end',
|
|
||||||
},
|
|
||||||
button: {
|
|
||||||
marginTop: theme.spacing(3),
|
|
||||||
marginLeft: theme.spacing(1),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const steps = ['Your goal', 'Personal details', 'Review your profile'];
|
const steps = ['Your goal', 'Personal details', 'Review your profile'];
|
||||||
|
const { formId, formField } = profileFormModel;
|
||||||
|
|
||||||
const renderStepContent = (step) => {
|
const renderStepContent = (step) => {
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case 0:
|
case 0:
|
||||||
return <GoalForm/>;
|
return <GoalForm formField={formField} />;
|
||||||
case 1:
|
case 1:
|
||||||
return <PersonalDetailsForm/>;
|
return <PersonalDetailsForm formField={formField} />;
|
||||||
case 2:
|
case 2:
|
||||||
return <ReviewProfileForm/>;
|
return <ReviewProfileForm/>;
|
||||||
default:
|
default:
|
||||||
@ -59,37 +29,19 @@ const renderStepContent = (step) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const formInitialValues = {
|
|
||||||
gender: '',
|
|
||||||
goal: '',
|
|
||||||
birthday: '',
|
|
||||||
height: '',
|
|
||||||
weight: {
|
|
||||||
current: '',
|
|
||||||
goal: '',
|
|
||||||
},
|
|
||||||
rateOfChange: '',
|
|
||||||
activity: '',
|
|
||||||
}
|
|
||||||
|
|
||||||
const key = 'profilePage'
|
const key = 'profilePage'
|
||||||
const ProfilePage = () => {
|
const ProfilePage = () => {
|
||||||
const [activeStep, setActiveStep] = useState(0);
|
const [activeStep, setActiveStep] = useState(0);
|
||||||
|
const currentValidationSchema = validationSchema[activeStep];
|
||||||
const isLastStep = activeStep === steps.length - 1;
|
const isLastStep = activeStep === steps.length - 1;
|
||||||
const isFirstStep = activeStep === 0;
|
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
||||||
useInjectReducer({ key, reducer });
|
useInjectReducer({ key, reducer });
|
||||||
useInjectSaga({ key, saga });
|
useInjectSaga({ key, saga });
|
||||||
|
|
||||||
const sleep = (ms) => {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
const submitForm = async (values, actions) => {
|
const submitForm = async (values, actions) => {
|
||||||
console.log(JSON.stringify(values, null, 2));
|
console.log(JSON.stringify(values, null, 2));
|
||||||
actions.setSubmitting(false);
|
actions.setSubmitting(false);
|
||||||
|
|
||||||
setActiveStep(activeStep + 1);
|
setActiveStep(activeStep + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,10 +59,6 @@ const ProfilePage = () => {
|
|||||||
setActiveStep(activeStep - 1);
|
setActiveStep(activeStep - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleNext = () => {
|
|
||||||
setActiveStep(activeStep + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className={classes.layout}>
|
<main className={classes.layout}>
|
||||||
<Paper className={classes.paper}>
|
<Paper className={classes.paper}>
|
||||||
@ -138,10 +86,11 @@ const ProfilePage = () => {
|
|||||||
) : (
|
) : (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={formInitialValues}
|
initialValues={formInitialValues}
|
||||||
|
validationSchema={currentValidationSchema}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
{({ isSubmitting }) => (
|
{({ isSubmitting }) => (
|
||||||
<Form id="createProfileForm">
|
<Form id={formId}>
|
||||||
{renderStepContent(activeStep)}
|
{renderStepContent(activeStep)}
|
||||||
<div className={classes.buttons}>
|
<div className={classes.buttons}>
|
||||||
{activeStep !== 0 && (
|
{activeStep !== 0 && (
|
||||||
@ -153,8 +102,7 @@ const ProfilePage = () => {
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
onClick={handleNext}
|
type="submit"
|
||||||
type={isLastStep ? 'submit' : 'button'}
|
|
||||||
className={classes.button}
|
className={classes.button}
|
||||||
>
|
>
|
||||||
{isLastStep ? 'Create profile' : 'Next'}
|
{isLastStep ? 'Create profile' : 'Next'}
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
|
|
||||||
export const initialState = {
|
export const initialState = {
|
||||||
activities: [
|
activities: [
|
||||||
|
{ label: 'None', value: undefined },
|
||||||
{
|
{
|
||||||
label: 'very low',
|
label: 'very low',
|
||||||
value: 1.2
|
value: 1.2
|
||||||
@ -32,6 +33,10 @@ export const initialState = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
goals: [
|
goals: [
|
||||||
|
{
|
||||||
|
label: 'None',
|
||||||
|
value: undefined,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'lose weight',
|
label: 'lose weight',
|
||||||
value: 1,
|
value: 1,
|
||||||
@ -46,11 +51,13 @@ export const initialState = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
ratesOfChange: [
|
ratesOfChange: [
|
||||||
|
{ label: 'None', value: undefined },
|
||||||
{ value: 1, label: '0 kg' },
|
{ value: 1, label: '0 kg' },
|
||||||
{ value: 2, label: '0.5 kg' },
|
{ value: 2, label: '0.5 kg' },
|
||||||
{ value: 3, label: '1 kg' },
|
{ value: 3, label: '1 kg' },
|
||||||
],
|
],
|
||||||
genders: [
|
genders: [
|
||||||
|
{ label: 'None', value: undefined },
|
||||||
{value: 1, label: 'male' },
|
{value: 1, label: 'male' },
|
||||||
{value: 2, label: 'female' },
|
{value: 2, label: 'female' },
|
||||||
],
|
],
|
||||||
@ -60,10 +67,8 @@ export const initialState = {
|
|||||||
goal: 0,
|
goal: 0,
|
||||||
birthday: new Date(),
|
birthday: new Date(),
|
||||||
height: 0,
|
height: 0,
|
||||||
weight: {
|
currentWeight: 0,
|
||||||
current: 0,
|
goalWeight: 0,
|
||||||
goal: 0,
|
|
||||||
},
|
|
||||||
rateOfChange: 0,
|
rateOfChange: 0,
|
||||||
activity: 0,
|
activity: 0,
|
||||||
};
|
};
|
||||||
@ -76,8 +81,8 @@ const loginPageReducer = produce((draft, action) => {
|
|||||||
draft.gender = action.gender;
|
draft.gender = action.gender;
|
||||||
draft.goal = action.goal;
|
draft.goal = action.goal;
|
||||||
draft.height = action.height;
|
draft.height = action.height;
|
||||||
draft.weight.current = action.weight.current;
|
draft.currentWeight = action.currentWeight;
|
||||||
draft.weight.goal = action.weight.goal;
|
draft.goalWeight = action.goalWeight;
|
||||||
draft.rateOfChange = action.rateOfChange;
|
draft.rateOfChange = action.rateOfChange;
|
||||||
draft.activity = action.activity;
|
draft.activity = action.activity;
|
||||||
draft.isLoading = false;
|
draft.isLoading = false;
|
||||||
|
@ -4,7 +4,8 @@ import { GET_PROFILE_REQUEST, UPDATE_PROFILE_REQUEST } from './constants';
|
|||||||
import {
|
import {
|
||||||
makeSelectBirthday,
|
makeSelectBirthday,
|
||||||
makeSelectHeight,
|
makeSelectHeight,
|
||||||
makeSelectWeight,
|
makeSelectCurrentWeight,
|
||||||
|
makeSelectGoalWeight,
|
||||||
makeSelectRateOfChange,
|
makeSelectRateOfChange,
|
||||||
makeSelectActivity,
|
makeSelectActivity,
|
||||||
makeSelectGoal,
|
makeSelectGoal,
|
||||||
@ -41,7 +42,8 @@ export function* updateProfile() {
|
|||||||
const goal = yield select(makeSelectGoal());
|
const goal = yield select(makeSelectGoal());
|
||||||
const birthday = yield select(makeSelectBirthday());
|
const birthday = yield select(makeSelectBirthday());
|
||||||
const height = yield select(makeSelectHeight());
|
const height = yield select(makeSelectHeight());
|
||||||
const weight = yield select(makeSelectWeight());
|
const currentWeight = yield select(makeSelectCurrentWeight());
|
||||||
|
const goalWeight = yield select(makeSelectGoalWeight());
|
||||||
const rateOfChange = yield select(makeSelectRateOfChange());
|
const rateOfChange = yield select(makeSelectRateOfChange());
|
||||||
const activity = yield select(makeSelectActivity());
|
const activity = yield select(makeSelectActivity());
|
||||||
|
|
||||||
@ -50,12 +52,12 @@ export function* updateProfile() {
|
|||||||
const requestParameters = {
|
const requestParameters = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${access.token}`, },
|
headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${access.token}`, },
|
||||||
body: JSON.stringify({ birthday, gender, height, weight, goal, rateOfChange, activity }),
|
body: JSON.stringify({ birthday, gender, height, currentWeight, goalWeight, goal, rateOfChange, activity }),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { birthday, gender, height, weight, goalWeight, rateOfChange, activity } = yield call(request, requestURL, requestParameters);
|
const { birthday, gender, height, currentWeight, goalWeight, rateOfChange, activity } = yield call(request, requestURL, requestParameters);
|
||||||
yield put(updateProfileSuccessAction({birthday, gender, height, weight, goalWeight, rateOfChange, activity}));
|
yield put(updateProfileSuccessAction({birthday, gender, height, currentWeight, goalWeight, rateOfChange, activity}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
yield put(updateProfileErrorAction({error: error.message}));
|
yield put(updateProfileErrorAction({error: error.message}));
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,13 @@ const makeSelectBirthday = () =>
|
|||||||
createSelector(selectProfilePageDomain, (substate) => substate.birthday);
|
createSelector(selectProfilePageDomain, (substate) => substate.birthday);
|
||||||
|
|
||||||
const makeSelectHeight = () =>
|
const makeSelectHeight = () =>
|
||||||
createSelector(selectProfilePageDomain, (substate) => substate.height);
|
createSelector(selectProfilePageDomain, (substate) => substate.height)
|
||||||
|
|
||||||
const makeSelectWeight = () =>
|
const makeSelectCurrentWeight = () =>
|
||||||
createSelector(selectProfilePageDomain, (substate) => substate.weight);
|
createSelector(selectProfilePageDomain, (substate) => substate.currentWeight);
|
||||||
|
|
||||||
|
const makeSelectGoalWeight = () =>
|
||||||
|
createSelector(selectProfilePageDomain, (substate) => substate.goalWeight);
|
||||||
|
|
||||||
const makeSelectRateOfChange = () =>
|
const makeSelectRateOfChange = () =>
|
||||||
createSelector(selectProfilePageDomain, (substate) => substate.rateOfChange);
|
createSelector(selectProfilePageDomain, (substate) => substate.rateOfChange);
|
||||||
@ -48,7 +51,8 @@ export {
|
|||||||
makeSelectError,
|
makeSelectError,
|
||||||
makeSelectBirthday,
|
makeSelectBirthday,
|
||||||
makeSelectHeight,
|
makeSelectHeight,
|
||||||
makeSelectWeight,
|
makeSelectCurrentWeight,
|
||||||
|
makeSelectGoalWeight,
|
||||||
makeSelectRateOfChange,
|
makeSelectRateOfChange,
|
||||||
makeSelectActivity,
|
makeSelectActivity,
|
||||||
makeSelectGoal,
|
makeSelectGoal,
|
||||||
|
37
src/pages/Profile/styles.js
Normal file
37
src/pages/Profile/styles.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme) => ({
|
||||||
|
layout: {
|
||||||
|
width: 'auto',
|
||||||
|
marginLeft: theme.spacing(2),
|
||||||
|
marginRight: theme.spacing(2),
|
||||||
|
[theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {
|
||||||
|
width: 600,
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: 'auto',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
paper: {
|
||||||
|
marginTop: theme.spacing(3),
|
||||||
|
marginBottom: theme.spacing(3),
|
||||||
|
padding: theme.spacing(2),
|
||||||
|
[theme.breakpoints.up(600 + theme.spacing(3) * 2)]: {
|
||||||
|
marginTop: theme.spacing(6),
|
||||||
|
marginBottom: theme.spacing(6),
|
||||||
|
padding: theme.spacing(3),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stepper: {
|
||||||
|
padding: theme.spacing(3, 0, 5),
|
||||||
|
},
|
||||||
|
buttons: {
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
marginTop: theme.spacing(3),
|
||||||
|
marginLeft: theme.spacing(1),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export default useStyles
|
77
yarn.lock
77
yarn.lock
@ -970,7 +970,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.13.4"
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||||
version "7.12.5"
|
version "7.12.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
|
||||||
integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
|
integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
|
||||||
@ -1081,11 +1081,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06"
|
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06"
|
||||||
integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==
|
integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==
|
||||||
|
|
||||||
"@hapi/hoek@^9.0.0":
|
|
||||||
version "9.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.0.tgz#6c9eafc78c1529248f8f4d92b0799a712b6052c6"
|
|
||||||
integrity sha512-i9YbZPN3QgfighY/1X1Pu118VUz2Fmmhd6b2n0/O8YVgGGfw0FbUYoA97k7FkpGJ+pLCFEDLUmAPPV4D1kpeFw==
|
|
||||||
|
|
||||||
"@hapi/joi@^15.1.0":
|
"@hapi/joi@^15.1.0":
|
||||||
version "15.1.1"
|
version "15.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7"
|
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7"
|
||||||
@ -1103,13 +1098,6 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@hapi/hoek" "^8.3.0"
|
"@hapi/hoek" "^8.3.0"
|
||||||
|
|
||||||
"@hapi/topo@^5.0.0":
|
|
||||||
version "5.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7"
|
|
||||||
integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==
|
|
||||||
dependencies:
|
|
||||||
"@hapi/hoek" "^9.0.0"
|
|
||||||
|
|
||||||
"@istanbuljs/load-nyc-config@^1.0.0":
|
"@istanbuljs/load-nyc-config@^1.0.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
||||||
@ -1523,23 +1511,6 @@
|
|||||||
estree-walker "^1.0.1"
|
estree-walker "^1.0.1"
|
||||||
picomatch "^2.2.2"
|
picomatch "^2.2.2"
|
||||||
|
|
||||||
"@sideway/address@^4.1.0":
|
|
||||||
version "4.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.0.tgz#0b301ada10ac4e0e3fa525c90615e0b61a72b78d"
|
|
||||||
integrity sha512-wAH/JYRXeIFQRsxerIuLjgUu2Xszam+O5xKeatJ4oudShOOirfmsQ1D6LL54XOU2tizpCYku+s1wmU0SYdpoSA==
|
|
||||||
dependencies:
|
|
||||||
"@hapi/hoek" "^9.0.0"
|
|
||||||
|
|
||||||
"@sideway/formula@^3.0.0":
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c"
|
|
||||||
integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==
|
|
||||||
|
|
||||||
"@sideway/pinpoint@^2.0.0":
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
|
|
||||||
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
|
|
||||||
|
|
||||||
"@sinonjs/commons@^1.7.0":
|
"@sinonjs/commons@^1.7.0":
|
||||||
version "1.8.1"
|
version "1.8.1"
|
||||||
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217"
|
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217"
|
||||||
@ -1826,6 +1797,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||||
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||||
|
|
||||||
|
"@types/lodash@^4.14.165":
|
||||||
|
version "4.14.165"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.165.tgz#74d55d947452e2de0742bad65270433b63a8c30f"
|
||||||
|
integrity sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==
|
||||||
|
|
||||||
"@types/minimatch@*":
|
"@types/minimatch@*":
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||||
@ -6916,17 +6892,6 @@ jest@26.6.0:
|
|||||||
import-local "^3.0.2"
|
import-local "^3.0.2"
|
||||||
jest-cli "^26.6.0"
|
jest-cli "^26.6.0"
|
||||||
|
|
||||||
joi@^17.3.0:
|
|
||||||
version "17.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/joi/-/joi-17.3.0.tgz#f1be4a6ce29bc1716665819ac361dfa139fff5d2"
|
|
||||||
integrity sha512-Qh5gdU6niuYbUIUV5ejbsMiiFmBdw8Kcp8Buj2JntszCkCfxJ9Cz76OtHxOZMPXrt5810iDIXs+n1nNVoquHgg==
|
|
||||||
dependencies:
|
|
||||||
"@hapi/hoek" "^9.0.0"
|
|
||||||
"@hapi/topo" "^5.0.0"
|
|
||||||
"@sideway/address" "^4.1.0"
|
|
||||||
"@sideway/formula" "^3.0.0"
|
|
||||||
"@sideway/pinpoint" "^2.0.0"
|
|
||||||
|
|
||||||
jpeg-js@^0.3.2:
|
jpeg-js@^0.3.2:
|
||||||
version "0.3.7"
|
version "0.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d"
|
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d"
|
||||||
@ -7324,7 +7289,7 @@ locate-path@^5.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
p-locate "^4.1.0"
|
p-locate "^4.1.0"
|
||||||
|
|
||||||
lodash-es@^4.17.14:
|
lodash-es@^4.17.11, lodash-es@^4.17.14:
|
||||||
version "4.17.15"
|
version "4.17.15"
|
||||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
|
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
|
||||||
integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
|
integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
|
||||||
@ -7764,6 +7729,11 @@ nan@^2.12.1:
|
|||||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
|
||||||
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
|
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
|
||||||
|
|
||||||
|
nanoclone@^0.2.1:
|
||||||
|
version "0.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4"
|
||||||
|
integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==
|
||||||
|
|
||||||
nanoid@^3.1.15:
|
nanoid@^3.1.15:
|
||||||
version "3.1.15"
|
version "3.1.15"
|
||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.15.tgz#28e7c4ce56aff2d0c2d37814c7aef9d6c5b3e6f3"
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.15.tgz#28e7c4ce56aff2d0c2d37814c7aef9d6c5b3e6f3"
|
||||||
@ -9302,6 +9272,11 @@ prop-types@^15.6.2, prop-types@^15.7.2:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
react-is "^16.8.1"
|
react-is "^16.8.1"
|
||||||
|
|
||||||
|
property-expr@^2.0.4:
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.4.tgz#37b925478e58965031bb612ec5b3260f8241e910"
|
||||||
|
integrity sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==
|
||||||
|
|
||||||
proxy-addr@~2.0.5:
|
proxy-addr@~2.0.5:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
|
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
|
||||||
@ -11205,6 +11180,11 @@ toidentifier@1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
||||||
|
|
||||||
|
toposort@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330"
|
||||||
|
integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=
|
||||||
|
|
||||||
tough-cookie@^2.3.3, tough-cookie@~2.5.0:
|
tough-cookie@^2.3.3, tough-cookie@~2.5.0:
|
||||||
version "2.5.0"
|
version "2.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||||
@ -12157,3 +12137,16 @@ yarn@^1.22.10:
|
|||||||
version "1.22.10"
|
version "1.22.10"
|
||||||
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c"
|
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c"
|
||||||
integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==
|
integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==
|
||||||
|
|
||||||
|
yup@^0.32.8:
|
||||||
|
version "0.32.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.8.tgz#16e4a949a86a69505abf99fd0941305ac9adfc39"
|
||||||
|
integrity sha512-SZulv5FIZ9d5H99EN5tRCRPXL0eyoYxWIP1AacCrjC9d4DfP13J1dROdKGfpfRHT3eQB6/ikBl5jG21smAfCkA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.10.5"
|
||||||
|
"@types/lodash" "^4.14.165"
|
||||||
|
lodash "^4.17.20"
|
||||||
|
lodash-es "^4.17.11"
|
||||||
|
nanoclone "^0.2.1"
|
||||||
|
property-expr "^2.0.4"
|
||||||
|
toposort "^2.0.2"
|
||||||
|
Loading…
Reference in New Issue
Block a user