Fixed validation and added toasts

This commit is contained in:
Ildar Kamalov 2019-01-21 11:55:39 +03:00 committed by Eugene Bujak
parent 2bd4840ba5
commit a7416f9c34
9 changed files with 68 additions and 34 deletions

View File

@ -179,13 +179,14 @@
"install_devices_desc": "In order for AdGuard Home to start working, you need to configure your devices to use it.",
"install_submit_title": "Congratulations!",
"install_submit_desc": "The setup procedure is finished and you are ready to start using AdGuard Home.",
"install_decices_router": "Router",
"install_decices_router_desc": "This setup will automatically cover all the devices connected to your home router and you will not need to configure each of them manually.",
"install_decices_router_list_1": "Open the preferences for your router. Usually, you can access it from your browser via a URL (like http://192.168.0.1/ or http://192.168.1.1/). You may be asked to enter the password. If you don't remember it, you can often reset the password by pressing a button on the router itself. Some routers require a specific application, which in that case should be already installed on your computer/phone.",
"install_decices_router_list_2": "Find the DHCP/DNS settings. Look for the DNS letters next to a field which allows two or three sets of numbers, each broken into four groups of one to three digits.",
"install_decices_router_list_3": "Enter your AdGuard Home server addresses there.",
"install_devices_router": "Router",
"install_devices_router_desc": "This setup will automatically cover all the devices connected to your home router and you will not need to configure each of them manually.",
"install_devices_router_list_1": "Open the preferences for your router. Usually, you can access it from your browser via a URL (like http://192.168.0.1/ or http://192.168.1.1/). You may be asked to enter the password. If you don't remember it, you can often reset the password by pressing a button on the router itself. Some routers require a specific application, which in that case should be already installed on your computer/phone.",
"install_devices_router_list_2": "Find the DHCP/DNS settings. Look for the DNS letters next to a field which allows two or three sets of numbers, each broken into four groups of one to three digits.",
"install_devices_router_list_3": "Enter your AdGuard Home server addresses there.",
"get_started": "Get Started",
"next": "Next",
"open_dashboard": "Open Dashboard",
"install_saved": "All settings saved"
"install_saved": "All settings saved",
"form_error_password": "Password mismatched"
}

View File

@ -5,6 +5,7 @@ const apiClient = new Api();
export const addErrorToast = createAction('ADD_ERROR_TOAST');
export const addSuccessToast = createAction('ADD_SUCCESS_TOAST');
export const removeToast = createAction('REMOVE_TOAST');
export const nextStep = createAction('NEXT_STEP');
export const prevStep = createAction('PREV_STEP');

View File

@ -4,8 +4,8 @@ import { Field, reduxForm } from 'redux-form';
import { withNamespaces, Trans } from 'react-i18next';
import flow from 'lodash/flow';
import i18n from '../../i18n';
import Controls from './Controls';
import validate from './validate';
import renderField from './renderField';
const required = (value) => {
@ -15,11 +15,21 @@ const required = (value) => {
return <Trans>form_error_required</Trans>;
};
const validate = (values) => {
const errors = {};
if (values.confirm_password !== values.password) {
errors.confirm_password = i18n.t('form_error_password');
}
return errors;
};
const Auth = (props) => {
const {
handleSubmit,
submitting,
pristine,
invalid,
t,
} = props;
@ -75,7 +85,7 @@ const Auth = (props) => {
/>
</div>
</div>
<Controls submitting={submitting} pristine={pristine} />
<Controls pristine={pristine} invalid={invalid} />
</form>
);
};
@ -83,7 +93,7 @@ const Auth = (props) => {
Auth.propTypes = {
handleSubmit: PropTypes.func.isRequired,
pristine: PropTypes.bool.isRequired,
submitting: PropTypes.bool.isRequired,
invalid: PropTypes.bool.isRequired,
t: PropTypes.func.isRequired,
};

View File

@ -45,7 +45,7 @@ class Controls extends Component {
<button
type="submit"
className="btn btn-success btn-standard btn-lg"
disabled={this.props.submitting || this.props.pristine}
disabled={this.props.invalid || this.props.pristine}
>
<Trans>next</Trans>
</button>
@ -65,7 +65,6 @@ class Controls extends Component {
type="button"
className="btn btn-success btn-standard btn-lg"
onClick={this.props.nextStep}
disabled={this.props.submitting || this.props.pristine}
>
<Trans>next</Trans>
</button>
@ -101,6 +100,7 @@ Controls.propTypes = {
prevStep: PropTypes.func,
pristine: PropTypes.bool,
submitting: PropTypes.bool,
invalid: PropTypes.bool,
};
const mapStateToProps = (state) => {

View File

@ -18,19 +18,19 @@ const Devices = () => (
<Tabs>
<div label="Router">
<div className="tab__title">
<Trans>install_decices_router</Trans>
<Trans>install_devices_router</Trans>
</div>
<div className="tab__text">
<Trans>install_decices_router_desc</Trans>
<Trans>install_devices_router_desc</Trans>
<ol>
<li>
<Trans>install_decices_router_list_1</Trans>
<Trans>install_devices_router_list_1</Trans>
</li>
<li>
<Trans>install_decices_router_list_2</Trans>
<Trans>install_devices_router_list_2</Trans>
</li>
<li>
<Trans>install_decices_router_list_3</Trans>
<Trans>install_devices_router_list_3</Trans>
</li>
</ol>
</div>

View File

@ -36,6 +36,7 @@ let Settings = (props) => {
handleSubmit,
interfaceIp,
dnsIp,
invalid,
} = props;
return (
@ -122,7 +123,7 @@ let Settings = (props) => {
<Trans>install_settings_dns_desc</Trans> <strong>{dnsIp}</strong>
</p>
</div>
<Controls />
<Controls invalid={invalid} />
</form>
);
};
@ -131,8 +132,7 @@ Settings.propTypes = {
handleSubmit: PropTypes.func.isRequired,
interfaceIp: PropTypes.string.isRequired,
dnsIp: PropTypes.string.isRequired,
pristine: PropTypes.bool.isRequired,
submitting: PropTypes.bool.isRequired,
invalid: PropTypes.bool.isRequired,
initialValues: PropTypes.object,
};

View File

@ -13,6 +13,7 @@ import Devices from './Devices';
import Submit from './Submit';
import Progress from './Progress';
import Toasts from '../../components/Toasts';
import Footer from '../../components/ui/Footer';
import logo from '../../components/ui/svg/logo.svg';
@ -85,6 +86,7 @@ class Setup extends Component {
</div>
</div>
<Footer />
<Toasts />
</Fragment>
}
</Fragment>
@ -104,8 +106,8 @@ Setup.propTypes = {
};
const mapStateToProps = (state) => {
const { install } = state;
const props = { install };
const { install, toasts } = state;
const props = { install, toasts };
return props;
};

View File

@ -1,11 +0,0 @@
const validate = (values) => {
const errors = {};
if (values.confirm_password !== values.password) {
errors.confirm_password = 'Password mismatched';
}
return errors;
};
export default validate;

View File

@ -1,8 +1,10 @@
import { combineReducers } from 'redux';
import { handleActions } from 'redux-actions';
import { reducer as formReducer } from 'redux-form';
import nanoid from 'nanoid';
import * as actions from '../actions/install';
import { INSTALL_FIRST_STEP } from '../helpers/constants';
const install = handleActions({
[actions.getDefaultAddressesRequest]: state => ({ ...state, processingDefault: true }),
@ -19,11 +21,40 @@ const install = handleActions({
[actions.setAllSettingsFailure]: state => ({ ...state, processingSubmit: false }),
[actions.setAllSettingsSuccess]: state => ({ ...state, processingSubmit: false }),
}, {
step: 1,
step: INSTALL_FIRST_STEP,
processingDefault: true,
});
const toasts = handleActions({
[actions.addErrorToast]: (state, { payload }) => {
const errorToast = {
id: nanoid(),
message: payload.error.toString(),
type: 'error',
};
const newState = { ...state, notices: [...state.notices, errorToast] };
return newState;
},
[actions.addSuccessToast]: (state, { payload }) => {
const successToast = {
id: nanoid(),
message: payload,
type: 'success',
};
const newState = { ...state, notices: [...state.notices, successToast] };
return newState;
},
[actions.removeToast]: (state, { payload }) => {
const filtered = state.notices.filter(notice => notice.id !== payload);
const newState = { ...state, notices: filtered };
return newState;
},
}, { notices: [] });
export default combineReducers({
install,
toasts,
form: formReducer,
});