diff --git a/package.json b/package.json
index e432200..6c5a13e 100644
--- a/package.json
+++ b/package.json
@@ -13,14 +13,17 @@
"@testing-library/user-event": "^12.1.10",
"connected-react-router": "^6.8.0",
"date-fns": "^2.16.1",
+ "formik": "^2.2.6",
"history": "4.10.1",
"immer": "^8.0.0",
+ "joi": "^17.3.0",
"lodash": "^4.17.20",
"prop-types": "^15.7.2",
"quagga": "^0.12.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-helmet": "^6.1.0",
+ "react-hook-form": "^6.13.1",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.0",
diff --git a/src/components/GoalForm/index.js b/src/components/GoalForm/index.js
index a5f77b1..1561c82 100644
--- a/src/components/GoalForm/index.js
+++ b/src/components/GoalForm/index.js
@@ -1,62 +1,103 @@
-import React, { useEffect } from 'react';
-import { Grid, Button, Typography, Radio, RadioGroup } from '@material-ui/core';
-import {useInjectReducer, useInjectSaga} from "redux-injectors";
-import { useSelector, useDispatch } from 'react-redux';
+import React from 'react';
+import {Grid, FormControlLabel, Slider, Button, Typography, Radio, RadioGroup, Box} from '@material-ui/core';
+import {useInjectReducer} from "redux-injectors";
+import { useSelector } from 'react-redux';
import {createStructuredSelector} from "reselect";
+import { useFormContext, Controller } from "react-hook-form";
import reducer from "pages/Profile/reducer";
-import saga from "pages/Profile/saga";
-import { profileInputChange, getGoalsAction } from 'pages/Profile/actions'
import {
- makeSelectError,
- makeSelectIsLoading,
makeSelectGoals,
+ makeSelectActivities,
+ makeSelectRatesOfChange,
} from "pages/Profile/selectors";
-import Loader from './Loader'
const stateSelector = createStructuredSelector({
- isLoading: makeSelectIsLoading(),
- error: makeSelectError(),
goals: makeSelectGoals(),
+ activities: makeSelectActivities(),
});
const key = 'profilePage'
const GoalForm = () => {
useInjectReducer({ key, reducer });
- useInjectSaga({ key, saga });
- const dispatch = useDispatch()
- const { goals, error, isLoading } = useSelector(stateSelector)
-
- const handleChangeGoal = ({ target: { name, value }}) => {
- dispatch(profileInputChange({ name, value }))
- }
-
- useEffect(() => {
- dispatch(getGoalsAction())
- }, [])
+ const { goals, activities, ratesOfChange } = useSelector(stateSelector)
+ const { control } = useFormContext()
return (
- Your goal
+ Goal
-
-
- {isLoading ? (
-
- ) : (
-
- {goals.map(({ name, value }, index) => (
-
-
-
- ))}
-
- )}
+
+
+
+
+ {goals.map(({ label, value }) => (
+
+
+
+ ))}
+
+
+ }
+ />
-
+
+
+ Activity
+
+
+ (
+ onChange(value)}
+ min={1.2}
+ step={null}
+ max={1.9}
+ marks={activities}
+ />
+ )}
+ />
+
+
+
+
+ Rate of change
+
+
+ (
+ onChange(value)}
+ min={0}
+ step={0.1}
+ max={1}
+ valueLabelDisplay="auto"
+ marks={ratesOfChange}
+ />
+ )}
+ />
+
+
+
);
}
diff --git a/src/components/PersonalDetailsForm/index.js b/src/components/PersonalDetailsForm/index.js
index ba900e6..af8d426 100644
--- a/src/components/PersonalDetailsForm/index.js
+++ b/src/components/PersonalDetailsForm/index.js
@@ -1,56 +1,32 @@
import 'date-fns';
-import React, { useEffect } from 'react';
+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,
- KeyboardDatePicker,
+ DatePicker,
} from '@material-ui/pickers';
-import {useInjectReducer, useInjectSaga} from "redux-injectors";
-import { useSelector, useDispatch } from 'react-redux';
+import {useInjectReducer} from "redux-injectors";
+import { useSelector } from 'react-redux';
import {createStructuredSelector} from "reselect";
import reducer from "pages/Profile/reducer";
-import saga from "pages/Profile/saga";
-import { profileInputChange, getActivitiesAction, getGendersAction } from 'pages/Profile/actions'
import {
- makeSelectError,
- makeSelectIsLoading,
makeSelectActivities,
makeSelectGenders,
- makeSelectWeight,
- makeSelectHeight,
- makeSelectBirthday,
- makeSelectActivity,
- makeSelectGender,
} from "pages/Profile/selectors";
const stateSelector = createStructuredSelector({
- isLoading: makeSelectIsLoading(),
- error: makeSelectError(),
activities: makeSelectActivities(),
genders: makeSelectGenders(),
- weight: makeSelectWeight(),
- height: makeSelectHeight(),
- birthday: makeSelectBirthday(),
- activity: makeSelectActivity(),
- gender: makeSelectGender(),
});
const key = 'profilePage'
const PersonalDetailsForm = () => {
useInjectReducer({ key, reducer });
- useInjectSaga({ key, saga });
- const dispatch = useDispatch()
- const { gender, activity, birthday, height, weight, activities, genders, error, isLoading } = useSelector(stateSelector)
+ const { activities, genders } = useSelector(stateSelector)
+ const { register, control } = useFormContext()
- const handleChangeValue = ({ target: { name, value }}) => {
- dispatch(profileInputChange({ name, value }))
- }
-
- useEffect(() => {
- dispatch(getActivitiesAction())
- dispatch(getGendersAction())
- }, [])
return (
@@ -61,79 +37,93 @@ const PersonalDetailsForm = () => {
Gender
-
+ as={
+
+ }
+ />
-
-
-
+ selected}
+ name="birthday"
+ render={({ onChange, value }) => (
+
+
+
+ )}
+ />
- cm
- }}
+ as={
+ cm
+ }}
+ />
+ }
/>
- Kg
- }}
+ Kg
+ }}
+ />
+ }
/>
-
- Activity
-
-
- ({
- name,
- value: factor
- }))}
- />
-
+ Kg
+ }}
+ />
+ }
+ />
diff --git a/src/pages/Profile/actions.js b/src/pages/Profile/actions.js
index adfe348..aa0bb98 100644
--- a/src/pages/Profile/actions.js
+++ b/src/pages/Profile/actions.js
@@ -1,13 +1,4 @@
import {
- GET_GOALS_REQUEST,
- GET_GOALS_SUCCESS,
- GET_GOALS_ERROR,
- GET_ACTIVITIES_REQUEST,
- GET_ACTIVITIES_SUCCESS,
- GET_ACTIVITIES_ERROR,
- GET_GENDERS_ERROR,
- GET_GENDERS_REQUEST,
- GET_GENDERS_SUCCESS,
PROFILE_INPUT_CHANGE,
GET_PROFILE_REQUEST,
GET_PROFILE_SUCCESS,
@@ -43,15 +34,15 @@ export const getProfileErrorAction = ({error}) => ({
error,
})
-
export const updateProfileAction = () => ({
type: UPDATE_PROFILE_REQUEST,
})
-export const updateProfileSuccessAction = ({birthday, gender, height, weight, goalWeight, rateOfChange, activity}) => ({
+export const updateProfileSuccessAction = ({birthday, goal, gender, height, weight, goalWeight, rateOfChange, activity}) => ({
type: UPDATE_PROFILE_SUCCESS,
birthday,
gender,
+ goal,
height,
weight,
goalWeight,
@@ -64,45 +55,3 @@ export const updateProfileErrorAction = ({error}) => ({
error,
})
-export const getActivitiesAction = () => ({
- type: GET_ACTIVITIES_REQUEST,
-})
-
-export const getActivitiesSuccessAction = ({ activities }) => ({
- type: GET_ACTIVITIES_SUCCESS,
- activities,
-})
-
-export const getActivitiesErrorAction = ({error}) => ({
- type: GET_ACTIVITIES_ERROR,
- error,
-})
-
-export const getGendersAction = () => ({
- type: GET_GENDERS_REQUEST,
-})
-
-export const getGendersSuccessAction = ({ genders }) => ({
- type: GET_GENDERS_SUCCESS,
- genders,
-})
-
-export const getGendersErrorAction = ({error}) => ({
- type: GET_GENDERS_ERROR,
- error,
-})
-
-export const getGoalsAction = () => ({
- type: GET_GOALS_REQUEST,
-})
-
-export const getGoalsSuccessAction = ({ goals }) => ({
- type: GET_GOALS_SUCCESS,
- goals,
-})
-
-export const getGoalsErrorAction = ({error}) => ({
- type: GET_GOALS_ERROR,
- error,
-})
-
diff --git a/src/pages/Profile/constants.js b/src/pages/Profile/constants.js
index 4ce361c..f1e7d02 100644
--- a/src/pages/Profile/constants.js
+++ b/src/pages/Profile/constants.js
@@ -6,18 +6,4 @@ export const UPDATE_PROFILE_REQUEST = 'app/ProfilePage/UPDATE_PROFILE_REQUEST';
export const UPDATE_PROFILE_SUCCESS = 'app/ProfilePage/UPDATE_PROFILE_SUCCESS';
export const UPDATE_PROFILE_ERROR = 'app/ProfilePage/UPDATE_PROFILE_ERROR';
-export const GET_GENDERS_REQUEST = 'app/ProfilePage/GET_GENDERS_REQUEST';
-export const GET_GENDERS_SUCCESS = 'app/ProfilePage/GET_GENDERS_SUCCESS';
-export const GET_GENDERS_ERROR = 'app/ProfilePage/GET_GENDERS_ERROR';
-
-export const GET_GOALS_REQUEST = 'app/ProfilePage/GET_GOALS_REQUEST';
-export const GET_GOALS_SUCCESS = 'app/ProfilePage/GET_GOALS_SUCCESS';
-export const GET_GOALS_ERROR = 'app/ProfilePage/GET_GOALS_ERROR';
-
-export const GET_ACTIVITIES_REQUEST = 'app/ProfilePage/GET_ACTIVITIES_REQUEST';
-export const GET_ACTIVITIES_SUCCESS = 'app/ProfilePage/GET_ACTIVITIES_SUCCESS';
-export const GET_ACTIVITIES_ERROR = 'app/ProfilePage/GET_ACTIVITIES_ERROR';
-
-
-
export const PROFILE_INPUT_CHANGE = 'app/ProfilePage/PROFILE_INPUT_CHANGE';
diff --git a/src/pages/Profile/index.js b/src/pages/Profile/index.js
index d7434f8..9674528 100644
--- a/src/pages/Profile/index.js
+++ b/src/pages/Profile/index.js
@@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles';
import {Paper, Stepper, Step, StepLabel, Button, Typography } from '@material-ui/core';
import {useInjectReducer, useInjectSaga} from "redux-injectors";
import { useDispatch } from 'react-redux';
+import { useForm, useFormContext, FormProvider } from "react-hook-form";
import GoalForm from 'components/GoalForm';
import PersonalDetailsForm from 'components/PersonalDetailsForm';
import ReviewProfileForm from 'components/ReviewProfileForm';
@@ -49,11 +50,11 @@ const steps = ['Your goal', 'Personal details', 'Review your profile'];
const getStepContent = (step) => {
switch (step) {
case 0:
- return ;
+ return ;
case 1:
- return ;
+ return ;
case 2:
- return ;
+ return ;
default:
throw new Error('Unknown step');
}
@@ -63,6 +64,20 @@ const key = 'profilePage'
const ProfilePage = () => {
const classes = useStyles();
const [activeStep, setActiveStep] = useState(0);
+ const methods = useForm({
+ defaultValues: {
+ gender: '',
+ goal: 0,
+ birthday: '',
+ height: 0,
+ weight: {
+ current: 0,
+ goal: 0,
+ },
+ rateOfChange: 0,
+ activity: 0,
+ }
+ });
useInjectReducer({ key, reducer });
useInjectSaga({ key, saga });
@@ -77,9 +92,8 @@ const ProfilePage = () => {
setActiveStep(activeStep - 1);
};
- const handleSubmitProfile = (event) => {
- event.preventDefault();
- dispatch(updateProfileAction())
+ const handleSubmitProfile = data => {
+ console.log('data', data)
}
return (
@@ -107,25 +121,28 @@ const ProfilePage = () => {
) : (
-
+
+
+
)}
diff --git a/src/pages/Profile/reducer.js b/src/pages/Profile/reducer.js
index 20bc36d..dbbf8d1 100644
--- a/src/pages/Profile/reducer.js
+++ b/src/pages/Profile/reducer.js
@@ -1,14 +1,5 @@
import produce from 'immer';
import {
- GET_GOALS_REQUEST,
- GET_GOALS_SUCCESS,
- GET_GOALS_ERROR,
- GET_ACTIVITIES_SUCCESS,
- GET_GENDERS_SUCCESS,
- GET_ACTIVITIES_ERROR,
- GET_GENDERS_ERROR,
- GET_ACTIVITIES_REQUEST,
- GET_GENDERS_REQUEST,
PROFILE_INPUT_CHANGE,
GET_PROFILE_REQUEST,
GET_PROFILE_SUCCESS,
@@ -19,61 +10,78 @@ import {
} from './constants';
export const initialState = {
- activities: [],
- goals: [],
- genders: [],
+ activities: [
+ {
+ label: 'very low',
+ value: 1.2
+ },
+ {
+ label: 'low',
+ value: 1.375
+ },
+ {
+ label: 'medium',
+ value: 1.55
+ },{
+ label: 'high',
+ value: 1.725
+ },
+ {
+ label: 'very high',
+ value: 1.9
+ },
+ ],
+ goals: [
+ {
+ label: 'lose weight',
+ value: -1,
+ },
+ {
+ label: 'maintain weight',
+ value: 0,
+ },
+ {
+ label: 'put on weight',
+ value: 1,
+ }
+ ],
+ ratesOfChange: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
+ genders: ['male', 'female'],
isLoading: false,
error: {},
gender: '',
+ goal: 0,
birthday: new Date(),
height: 0,
- weight: 0,
- goalWeight: 0,
+ weight: {
+ current: 0,
+ goal: 0,
+ },
rateOfChange: 0,
activity: 0,
};
const loginPageReducer = produce((draft, action) => {
switch(action.type) {
- case GET_ACTIVITIES_SUCCESS:
- draft.activities = action.activities;
- draft.isLoading = false;
- break;
-
- case GET_GOALS_SUCCESS:
- draft.goals = action.goals;
- draft.isLoading = false;
- break;
-
- case GET_GENDERS_SUCCESS:
- draft.genders = action.genders;
- draft.isLoading = false;
- break;
-
case GET_PROFILE_SUCCESS:
case UPDATE_PROFILE_SUCCESS:
draft.birthday = action.birthday;
draft.gender = action.gender;
+ draft.goal = action.goal;
draft.height = action.height;
- draft.weight = action.weight;
- draft.goalWeight = action.goalWeight;
+ draft.weight.current = action.weight.current;
+ draft.weight.goal = action.weight.goal;
draft.rateOfChange = action.rateOfChange;
draft.activity = action.activity;
draft.isLoading = false;
break;
- case GET_ACTIVITIES_REQUEST:
- case GET_GENDERS_REQUEST:
case GET_PROFILE_REQUEST:
- case GET_GOALS_REQUEST:
case UPDATE_PROFILE_REQUEST:
draft.isLoading = true;
break;
- case GET_ACTIVITIES_ERROR:
- case GET_GENDERS_ERROR:
case GET_PROFILE_ERROR:
- case GET_GOALS_ERROR:
case UPDATE_PROFILE_ERROR:
draft.isLoading = false;
draft.error = action.error;
diff --git a/src/pages/Profile/saga.js b/src/pages/Profile/saga.js
index 533acfc..bb439c5 100644
--- a/src/pages/Profile/saga.js
+++ b/src/pages/Profile/saga.js
@@ -1,16 +1,16 @@
import { takeLatest, call, put, select } from 'redux-saga/effects';
import { api, request } from 'utils';
-import { GET_GOALS_REQUEST, GET_ACTIVITIES_REQUEST, GET_GENDERS_REQUEST, GET_PROFILE_REQUEST, UPDATE_PROFILE_REQUEST } from './constants';
+import { GET_PROFILE_REQUEST, UPDATE_PROFILE_REQUEST } from './constants';
import {
makeSelectBirthday,
makeSelectHeight,
makeSelectWeight,
makeSelectRateOfChange,
makeSelectActivity,
- makeSelectGoalWeight,
+ makeSelectGoal,
makeSelectGender
} from './selectors';
-import { getGoalsErrorAction, getGoalsSuccessAction, getActivitiesSuccessAction, getActivitiesErrorAction, getGendersSuccessAction, getGendersErrorAction, updateProfileErrorAction, updateProfileSuccessAction, getProfileErrorAction, getProfileSuccessAction } from './actions';
+import { updateProfileErrorAction, updateProfileSuccessAction, getProfileErrorAction, getProfileSuccessAction } from './actions';
import { makeSelectTokens } from 'containers/App/selectors'
@@ -37,11 +37,11 @@ export function* getProfile() {
export function* updateProfile() {
const { access } = yield select(makeSelectTokens());
- const birthday = yield select(makeSelectBirthday());
const gender = yield select(makeSelectGender());
+ const goal = yield select(makeSelectGoal());
+ const birthday = yield select(makeSelectBirthday());
const height = yield select(makeSelectHeight());
const weight = yield select(makeSelectWeight());
- const goalWeight = yield select(makeSelectGoalWeight());
const rateOfChange = yield select(makeSelectRateOfChange());
const activity = yield select(makeSelectActivity());
@@ -50,7 +50,7 @@ export function* updateProfile() {
const requestParameters = {
method: 'POST',
headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${access.token}`, },
- body: JSON.stringify({ birthday, gender, height, weight, goalWeight, rateOfChange, activity }),
+ body: JSON.stringify({ birthday, gender, height, weight, goal, rateOfChange, activity }),
};
try {
@@ -61,70 +61,7 @@ export function* updateProfile() {
}
}
-export function* getActivities() {
- const { access } = yield select(makeSelectTokens());
-
- const requestURL = api.activities;
-
- const requestParameters = {
- method: 'GET',
- headers: {
- Authorization: `Bearer ${access.token}`,
- },
- };
-
- try {
- const { results } = yield call(request, requestURL, requestParameters);
- yield put(getActivitiesSuccessAction({ activities: results }));
- } catch (error) {
- yield put(getActivitiesErrorAction({error: error.message}));
- }
-}
-
-export function* getGenders() {
- const { access } = yield select(makeSelectTokens());
-
- const requestURL = api.genders;
-
- const requestParameters = {
- method: 'GET',
- headers: {
- Authorization: `Bearer ${access.token}`,
- },
- };
-
- try {
- const { results } = yield call(request, requestURL, requestParameters);
- yield put(getGendersSuccessAction({ genders: results }));
- } catch (error) {
- yield put(getGendersErrorAction({ error: error.message }));
- }
-}
-export function* getGoals() {
- const { access } = yield select(makeSelectTokens());
-
- const requestURL = api.goals;
-
- const requestParameters = {
- method: 'GET',
- headers: {
- Authorization: `Bearer ${access.token}`,
- },
- };
-
- try {
- const { results } = yield call(request, requestURL, requestParameters);
- yield put(getGoalsSuccessAction({ goals: results }));
- } catch (error) {
- yield put(getGoalsErrorAction({ error: error.message }));
- }
-}
-
export default function* profilePageSaga() {
yield takeLatest(GET_PROFILE_REQUEST, getProfile);
- yield takeLatest(GET_ACTIVITIES_REQUEST, getActivities);
- yield takeLatest(GET_GENDERS_REQUEST, getGenders);
- yield takeLatest(GET_PROFILE_REQUEST, getProfile);
- yield takeLatest(GET_GOALS_REQUEST, getGoals);
yield takeLatest(UPDATE_PROFILE_REQUEST, updateProfile);
}
diff --git a/src/pages/Profile/selectors.js b/src/pages/Profile/selectors.js
index 8deee14..a209fde 100644
--- a/src/pages/Profile/selectors.js
+++ b/src/pages/Profile/selectors.js
@@ -21,8 +21,8 @@ const makeSelectRateOfChange = () =>
const makeSelectActivity = () =>
createSelector(selectProfilePageDomain, (substate) => substate.activity);
-const makeSelectGoalWeight = () =>
- createSelector(selectProfilePageDomain, (substate) => substate.goalWeight);
+const makeSelectGoal = () =>
+ createSelector(selectProfilePageDomain, (substate) => substate.goal);
const makeSelectGender = () =>
createSelector(selectProfilePageDomain, (substate) => substate.gender);
@@ -39,6 +39,10 @@ const makeSelectActivities = () =>
const makeSelectGenders = () =>
createSelector(selectProfilePageDomain, (substate) => substate.genders);
+const makeSelectRatesOfChange = () =>
+ createSelector(selectProfilePageDomain, (substate) => substate.ratesOfChange);
+
+
export {
selectProfilePageDomain,
makeSelectError,
@@ -47,10 +51,11 @@ export {
makeSelectWeight,
makeSelectRateOfChange,
makeSelectActivity,
- makeSelectGoalWeight,
+ makeSelectGoal,
makeSelectGender,
makeSelectIsLoading,
makeSelectGoals,
makeSelectActivities,
makeSelectGenders,
+ makeSelectRatesOfChange
};
diff --git a/src/utils/api.js b/src/utils/api.js
index 2a6cd90..cbd4991 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -1,9 +1,6 @@
const API_BASE_URL = 'http://localhost:3001/v1'
const AUTH = 'auth';
const PROFILE = 'profiles';
-const ACTIVITY = 'activities';
-const GENDER = 'genders';
-const GOALS = 'goals';
const urls = {
auth: {
@@ -11,9 +8,6 @@ const urls = {
register: `${API_BASE_URL}/${AUTH}/register`,
},
profile: `${API_BASE_URL}/${PROFILE}`,
- activities: `${API_BASE_URL}/${ACTIVITY}`,
- genders: `${API_BASE_URL}/${GENDER}`,
- goals: `${API_BASE_URL}/${GOALS}`,
}
export default urls
diff --git a/yarn.lock b/yarn.lock
index 71e1b29..4d9d28c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1081,6 +1081,11 @@
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06"
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":
version "15.1.1"
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7"
@@ -1098,6 +1103,13 @@
dependencies:
"@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":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@@ -1511,6 +1523,23 @@
estree-walker "^1.0.1"
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":
version "1.8.1"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217"
@@ -4045,6 +4074,11 @@ deep-is@^0.1.3, deep-is@~0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
+deepmerge@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
+ integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
+
deepmerge@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
@@ -5224,6 +5258,19 @@ form-data@~2.3.2:
combined-stream "^1.0.6"
mime-types "^2.1.12"
+formik@^2.2.6:
+ version "2.2.6"
+ resolved "https://registry.yarnpkg.com/formik/-/formik-2.2.6.tgz#378a4bafe4b95caf6acf6db01f81f3fe5147559d"
+ integrity sha512-Kxk2zQRafy56zhLmrzcbryUpMBvT0tal5IvcifK5+4YNGelKsnrODFJ0sZQRMQboblWNym4lAW3bt+tf2vApSA==
+ dependencies:
+ deepmerge "^2.1.1"
+ hoist-non-react-statics "^3.3.0"
+ lodash "^4.17.14"
+ lodash-es "^4.17.14"
+ react-fast-compare "^2.0.1"
+ tiny-warning "^1.0.2"
+ tslib "^1.10.0"
+
forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
@@ -5625,7 +5672,7 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
-hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2:
+hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -6869,6 +6916,17 @@ jest@26.6.0:
import-local "^3.0.2"
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:
version "0.3.7"
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d"
@@ -7266,6 +7324,11 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
+lodash-es@^4.17.14:
+ version "4.17.15"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
+ integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
+
lodash._reinterpolate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
@@ -9453,6 +9516,11 @@ react-error-overlay@^6.0.8:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.8.tgz#474ed11d04fc6bda3af643447d85e9127ed6b5de"
integrity sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw==
+react-fast-compare@^2.0.1:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
+ integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
+
react-fast-compare@^3.1.1:
version "3.2.0"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
@@ -9468,6 +9536,11 @@ react-helmet@^6.1.0:
react-fast-compare "^3.1.1"
react-side-effect "^2.1.0"
+react-hook-form@^6.13.1:
+ version "6.13.1"
+ resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-6.13.1.tgz#b9c0aa61f746db8169ed5e1050de21cacb1947d6"
+ integrity sha512-Q0N7MYcbA8SigYufb02h9z97ZKCpIbe62rywOTPsK4Ntvh6fRTGDXSuzWuRhLHhArLoWbGrWYSNSS4tlb+OFXg==
+
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"