Added components for web setup
This commit is contained in:
committed by
Eugene Bujak
parent
71259c5f19
commit
5349ec76fd
98
client/src/install/Setup/Auth.js
Normal file
98
client/src/install/Setup/Auth.js
Normal file
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { withNamespaces, Trans } from 'react-i18next';
|
||||
import flow from 'lodash/flow';
|
||||
|
||||
import Controls from './Controls';
|
||||
import validate from './validate';
|
||||
import renderField from './renderField';
|
||||
|
||||
const required = (value) => {
|
||||
if (value || value === 0) {
|
||||
return false;
|
||||
}
|
||||
return <Trans>form_error_required</Trans>;
|
||||
};
|
||||
|
||||
const Auth = (props) => {
|
||||
const {
|
||||
handleSubmit,
|
||||
submitting,
|
||||
pristine,
|
||||
t,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<form className="setup__step" onSubmit={handleSubmit}>
|
||||
<div className="setup__group">
|
||||
<div className="setup__subtitle">
|
||||
<Trans>install_auth_title</Trans>
|
||||
</div>
|
||||
<p className="setup__desc">
|
||||
<Trans>install_auth_desc</Trans>
|
||||
</p>
|
||||
<div className="form-group">
|
||||
<label>
|
||||
<Trans>install_auth_username</Trans>
|
||||
</label>
|
||||
<Field
|
||||
name="username"
|
||||
component={renderField}
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder={ t('install_auth_username_enter') }
|
||||
validate={[required]}
|
||||
autoComplete="username"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>
|
||||
<Trans>install_auth_password</Trans>
|
||||
</label>
|
||||
<Field
|
||||
name="password"
|
||||
component={renderField}
|
||||
type="password"
|
||||
className="form-control"
|
||||
placeholder={ t('install_auth_password_enter') }
|
||||
validate={[required]}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>
|
||||
<Trans>install_auth_confirm</Trans>
|
||||
</label>
|
||||
<Field
|
||||
name="confirm_password"
|
||||
component={renderField}
|
||||
type="password"
|
||||
className="form-control"
|
||||
placeholder={ t('install_auth_confirm') }
|
||||
validate={[required]}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Controls submitting={submitting} pristine={pristine} />
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
Auth.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
pristine: PropTypes.bool.isRequired,
|
||||
submitting: PropTypes.bool.isRequired,
|
||||
t: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default flow([
|
||||
withNamespaces(),
|
||||
reduxForm({
|
||||
form: 'install',
|
||||
destroyOnUnmount: false,
|
||||
forceUnregisterOnUnmount: true,
|
||||
validate,
|
||||
}),
|
||||
])(Auth);
|
||||
115
client/src/install/Setup/Controls.js
Normal file
115
client/src/install/Setup/Controls.js
Normal file
@@ -0,0 +1,115 @@
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import * as actionCreators from '../../actions/install';
|
||||
import { INSTALL_FIRST_STEP, INSTALL_TOTAL_STEPS } from '../../helpers/constants';
|
||||
|
||||
class Controls extends Component {
|
||||
nextStep = () => {
|
||||
if (this.props.step < INSTALL_TOTAL_STEPS) {
|
||||
this.props.nextStep();
|
||||
}
|
||||
}
|
||||
|
||||
prevStep = () => {
|
||||
if (this.props.step > INSTALL_FIRST_STEP) {
|
||||
this.props.prevStep();
|
||||
}
|
||||
}
|
||||
|
||||
renderButtons(step) {
|
||||
switch (step) {
|
||||
case 1:
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
onClick={this.props.nextStep}
|
||||
>
|
||||
<Trans>get_started</Trans>
|
||||
</button>
|
||||
);
|
||||
case 2:
|
||||
case 3:
|
||||
return (
|
||||
<div className="btn-list">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary btn-standard btn-lg"
|
||||
onClick={this.props.prevStep}
|
||||
>
|
||||
<Trans>back</Trans>
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
disabled={this.props.submitting || this.props.pristine}
|
||||
>
|
||||
<Trans>next</Trans>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
case 4:
|
||||
return (
|
||||
<div className="btn-list">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary btn-standard btn-lg"
|
||||
onClick={this.props.prevStep}
|
||||
>
|
||||
<Trans>back</Trans>
|
||||
</button>
|
||||
<button
|
||||
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>
|
||||
</div>
|
||||
);
|
||||
case 5:
|
||||
return (
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-success btn-standard btn-lg"
|
||||
disabled={this.props.submitting || this.props.pristine}
|
||||
>
|
||||
<Trans>open_dashboard</Trans>
|
||||
</button>
|
||||
);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="setup__nav">
|
||||
{this.renderButtons(this.props.step)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Controls.propTypes = {
|
||||
step: PropTypes.number.isRequired,
|
||||
nextStep: PropTypes.func,
|
||||
prevStep: PropTypes.func,
|
||||
pristine: PropTypes.bool,
|
||||
submitting: PropTypes.bool,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { step } = state.install;
|
||||
const props = { step };
|
||||
return props;
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
actionCreators,
|
||||
)(Controls);
|
||||
68
client/src/install/Setup/Devices.js
Normal file
68
client/src/install/Setup/Devices.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import Tabs from '../../components/ui/Tabs';
|
||||
import Icons from '../../components/ui/Icons';
|
||||
import Controls from './Controls';
|
||||
|
||||
const Devices = () => (
|
||||
<div className="setup__step">
|
||||
<div className="setup__group">
|
||||
<div className="setup__subtitle">
|
||||
<Trans>install_devices_title</Trans>
|
||||
</div>
|
||||
<p className="setup__desc">
|
||||
<Trans>install_devices_desc</Trans>
|
||||
</p>
|
||||
<Icons />
|
||||
<Tabs>
|
||||
<div label="Router">
|
||||
<div className="tab__title">
|
||||
<Trans>install_decices_router</Trans>
|
||||
</div>
|
||||
<div className="tab__text">
|
||||
<Trans>install_decices_router_desc</Trans>
|
||||
<ol>
|
||||
<li>
|
||||
<Trans>install_decices_router_list_1</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans>install_decices_router_list_2</Trans>
|
||||
</li>
|
||||
<li>
|
||||
<Trans>install_decices_router_list_3</Trans>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div label="Windows">
|
||||
<div className="tab__title">
|
||||
Windows
|
||||
</div>
|
||||
<div className="tab__text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti sapiente magnam autem excepturi repellendus, voluptatem officia sint quas nulla maiores velit odit dolore commodi quia reprehenderit vero repudiandae adipisci aliquam.</div>
|
||||
</div>
|
||||
<div label="macOS">
|
||||
<div className="tab__title">
|
||||
macOS
|
||||
</div>
|
||||
<div className="tab__text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti sapiente magnam autem excepturi repellendus, voluptatem officia sint quas nulla maiores velit odit dolore commodi quia reprehenderit vero repudiandae adipisci aliquam.</div>
|
||||
</div>
|
||||
<div label="Android">
|
||||
<div className="tab__title">
|
||||
Android
|
||||
</div>
|
||||
<div className="tab__text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti sapiente magnam autem excepturi repellendus, voluptatem officia sint quas nulla maiores velit odit dolore commodi quia reprehenderit vero repudiandae adipisci aliquam.</div>
|
||||
</div>
|
||||
<div label="iOS">
|
||||
<div className="tab__title">
|
||||
iOS
|
||||
</div>
|
||||
<div className="tab__text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti sapiente magnam autem excepturi repellendus, voluptatem officia sint quas nulla maiores velit odit dolore commodi quia reprehenderit vero repudiandae adipisci aliquam.</div>
|
||||
</div>
|
||||
</Tabs>
|
||||
</div>
|
||||
<Controls />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Devices;
|
||||
23
client/src/install/Setup/Greeting.js
Normal file
23
client/src/install/Setup/Greeting.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Trans } from 'react-i18next';
|
||||
import Controls from './Controls';
|
||||
|
||||
class Greeting extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="setup__step">
|
||||
<div className="setup__group">
|
||||
<h1 className="setup__title">
|
||||
<Trans>install_welcome_title</Trans>
|
||||
</h1>
|
||||
<p className="setup__desc">
|
||||
<Trans>install_welcome_desc</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<Controls />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Greeting;
|
||||
25
client/src/install/Setup/Progress.js
Normal file
25
client/src/install/Setup/Progress.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import { INSTALL_TOTAL_STEPS } from '../../helpers/constants';
|
||||
|
||||
const getProgressPercent = step => (step / INSTALL_TOTAL_STEPS) * 100;
|
||||
|
||||
const Progress = props => (
|
||||
<div className="setup__progress">
|
||||
<Trans>install_step</Trans> {props.step}/{INSTALL_TOTAL_STEPS}
|
||||
<div className="setup__progress-wrap">
|
||||
<div
|
||||
className="setup__progress-inner"
|
||||
style={{ width: `${getProgressPercent(props.step)}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Progress.propTypes = {
|
||||
step: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
export default Progress;
|
||||
160
client/src/install/Setup/Settings.js
Normal file
160
client/src/install/Setup/Settings.js
Normal file
@@ -0,0 +1,160 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm, formValueSelector } from 'redux-form';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import Controls from './Controls';
|
||||
import renderField from './renderField';
|
||||
import { R_IPV4 } from '../../helpers/constants';
|
||||
|
||||
const required = (value) => {
|
||||
if (value || value === 0) {
|
||||
return false;
|
||||
}
|
||||
return <Trans>form_error_required</Trans>;
|
||||
};
|
||||
|
||||
const ipv4 = (value) => {
|
||||
if (value && !new RegExp(R_IPV4).test(value)) {
|
||||
return <Trans>form_error_ip_format</Trans>;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const port = (value) => {
|
||||
if (value < 1 || value > 65535) {
|
||||
return <Trans>form_error_port</Trans>;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const toNumber = value => value && parseInt(value, 10);
|
||||
|
||||
let Settings = (props) => {
|
||||
const {
|
||||
handleSubmit,
|
||||
interfaceIp,
|
||||
dnsIp,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<form className="setup__step" onSubmit={handleSubmit}>
|
||||
<div className="setup__group">
|
||||
<div className="setup__subtitle">
|
||||
<Trans>install_settings_title</Trans>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-8">
|
||||
<div className="form-group">
|
||||
<label>
|
||||
<Trans>install_settings_listen</Trans>
|
||||
</label>
|
||||
<Field
|
||||
name="web.ip"
|
||||
component={renderField}
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="0.0.0.0"
|
||||
validate={[ipv4, required]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-4">
|
||||
<div className="form-group">
|
||||
<label>
|
||||
<Trans>install_settings_port</Trans>
|
||||
</label>
|
||||
<Field
|
||||
name="web.port"
|
||||
component={renderField}
|
||||
type="number"
|
||||
className="form-control"
|
||||
placeholder="80"
|
||||
validate={[port, required]}
|
||||
normalize={toNumber}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="setup__desc">
|
||||
<Trans>install_settings_interface_link</Trans> <a href={`http://${interfaceIp}`}>{`http://${interfaceIp}`}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="setup__group">
|
||||
<div className="setup__subtitle">
|
||||
<Trans>install_settings_dns</Trans>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-8">
|
||||
<div className="form-group">
|
||||
<label>
|
||||
<Trans>install_settings_listen</Trans>
|
||||
</label>
|
||||
<Field
|
||||
name="dns.ip"
|
||||
component={renderField}
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder="0.0.0.0"
|
||||
validate={[ipv4, required]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-4">
|
||||
<div className="form-group">
|
||||
<label>
|
||||
<Trans>install_settings_port</Trans>
|
||||
</label>
|
||||
<Field
|
||||
name="dns.port"
|
||||
component={renderField}
|
||||
type="number"
|
||||
className="form-control"
|
||||
placeholder="80"
|
||||
validate={[port, required]}
|
||||
normalize={toNumber}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="setup__desc">
|
||||
<Trans>install_settings_dns_desc</Trans> <strong>{dnsIp}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<Controls />
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
Settings.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
interfaceIp: PropTypes.string.isRequired,
|
||||
dnsIp: PropTypes.string.isRequired,
|
||||
pristine: PropTypes.bool.isRequired,
|
||||
submitting: PropTypes.bool.isRequired,
|
||||
initialValues: PropTypes.object,
|
||||
};
|
||||
|
||||
Settings.defaultProps = {
|
||||
interfaceIp: '192.168.0.1',
|
||||
dnsIp: '192.168.0.1',
|
||||
};
|
||||
|
||||
const selector = formValueSelector('install');
|
||||
|
||||
Settings = connect((state) => {
|
||||
const interfaceIp = selector(state, 'web.ip');
|
||||
const dnsIp = selector(state, 'dns.ip');
|
||||
|
||||
return {
|
||||
interfaceIp,
|
||||
dnsIp,
|
||||
};
|
||||
})(Settings);
|
||||
|
||||
export default reduxForm({
|
||||
form: 'install',
|
||||
destroyOnUnmount: false,
|
||||
forceUnregisterOnUnmount: true,
|
||||
})(Settings);
|
||||
105
client/src/install/Setup/Setup.css
Normal file
105
client/src/install/Setup/Setup.css
Normal file
@@ -0,0 +1,105 @@
|
||||
.setup {
|
||||
min-height: calc(100vh - 80px);
|
||||
padding: 50px 0;
|
||||
line-height: 1.48;
|
||||
}
|
||||
|
||||
.setup__container {
|
||||
max-width: 650px;
|
||||
margin: 0 auto;
|
||||
padding: 30px 20px;
|
||||
line-height: 1.6;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 4px rgba(74, 74, 74, .36);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.setup__container {
|
||||
width: 650px;
|
||||
padding: 40px 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.setup__logo {
|
||||
display: block;
|
||||
margin: 0 auto 40px;
|
||||
max-width: 140px;
|
||||
}
|
||||
|
||||
.setup__nav {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.setup__step {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.setup__title {
|
||||
margin-bottom: 30px;
|
||||
font-size: 28px;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.setup__subtitle {
|
||||
margin-bottom: 10px;
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.setup__desc {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.setup__group {
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.setup__group:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.setup__progress {
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.setup__progress-wrap {
|
||||
height: 4px;
|
||||
margin: 20px -20px -30px -20px;
|
||||
overflow: hidden;
|
||||
background-color: #eaeaea;
|
||||
border-radius: 0 0 3px 3px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.setup__progress-wrap {
|
||||
margin: 20px -30px -40px -30px;
|
||||
}
|
||||
}
|
||||
|
||||
.setup__progress-inner {
|
||||
width: 0;
|
||||
height: 100%;
|
||||
font-size: 1.2rem;
|
||||
line-height: 20px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
|
||||
transition: width 0.6s ease;
|
||||
background: linear-gradient(45deg, rgba(99, 125, 120, 1) 0%, rgba(88, 177, 101, 1) 100%);
|
||||
}
|
||||
|
||||
.btn-standard {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.form__message {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.form__message--error {
|
||||
color: #cd201f;
|
||||
}
|
||||
44
client/src/install/Setup/Submit.js
Normal file
44
client/src/install/Setup/Submit.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { reduxForm } from 'redux-form';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import Controls from './Controls';
|
||||
|
||||
class Submit extends Component {
|
||||
render() {
|
||||
const {
|
||||
handleSubmit,
|
||||
pristine,
|
||||
submitting,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className="setup__step">
|
||||
<div className="setup__group">
|
||||
<h1 className="setup__title">
|
||||
<Trans>install_submit_title</Trans>
|
||||
</h1>
|
||||
<p className="setup__desc">
|
||||
<Trans>install_submit_desc</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Controls submitting={submitting} pristine={pristine} />
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Submit.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
pristine: PropTypes.bool.isRequired,
|
||||
submitting: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default reduxForm({
|
||||
form: 'install',
|
||||
destroyOnUnmount: false,
|
||||
forceUnregisterOnUnmount: true,
|
||||
})(Submit);
|
||||
115
client/src/install/Setup/index.js
Normal file
115
client/src/install/Setup/index.js
Normal file
@@ -0,0 +1,115 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import * as actionCreators from '../../actions/install';
|
||||
import { INSTALL_FIRST_STEP, INSTALL_TOTAL_STEPS } from '../../helpers/constants';
|
||||
|
||||
import Loading from '../../components/ui/Loading';
|
||||
import Greeting from './Greeting';
|
||||
import Settings from './Settings';
|
||||
import Auth from './Auth';
|
||||
import Devices from './Devices';
|
||||
import Submit from './Submit';
|
||||
import Progress from './Progress';
|
||||
|
||||
import Footer from '../../components/ui/Footer';
|
||||
import logo from '../../components/ui/svg/logo.svg';
|
||||
|
||||
import './Setup.css';
|
||||
import '../../components/ui/Tabler.css';
|
||||
|
||||
class Setup extends Component {
|
||||
componentDidMount() {
|
||||
this.props.getDefaultAddresses();
|
||||
}
|
||||
|
||||
handleFormSubmit = (values) => {
|
||||
this.props.setAllSettings(values);
|
||||
};
|
||||
|
||||
nextStep = () => {
|
||||
if (this.props.install.step < INSTALL_TOTAL_STEPS) {
|
||||
this.props.nextStep();
|
||||
}
|
||||
}
|
||||
|
||||
prevStep = () => {
|
||||
if (this.props.install.step > INSTALL_FIRST_STEP) {
|
||||
this.props.prevStep();
|
||||
}
|
||||
}
|
||||
|
||||
renderPage(step, config) {
|
||||
switch (step) {
|
||||
case 1:
|
||||
return <Greeting />;
|
||||
case 2:
|
||||
return (
|
||||
<Settings
|
||||
initialValues={config}
|
||||
onSubmit={this.nextStep}
|
||||
/>
|
||||
);
|
||||
case 3:
|
||||
return (
|
||||
<Auth onSubmit={this.nextStep} />
|
||||
);
|
||||
case 4:
|
||||
return <Devices />;
|
||||
case 5:
|
||||
return <Submit onSubmit={this.handleFormSubmit} />;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
processingDefault,
|
||||
step,
|
||||
web,
|
||||
dns,
|
||||
} = this.props.install;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{processingDefault && <Loading />}
|
||||
{!processingDefault &&
|
||||
<Fragment>
|
||||
<div className="setup">
|
||||
<div className="setup__container">
|
||||
<img src={logo} className="setup__logo" alt="logo" />
|
||||
{this.renderPage(step, { web, dns })}
|
||||
<Progress step={step} />
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</Fragment>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Setup.propTypes = {
|
||||
getDefaultAddresses: PropTypes.func.isRequired,
|
||||
setAllSettings: PropTypes.func.isRequired,
|
||||
nextStep: PropTypes.func.isRequired,
|
||||
prevStep: PropTypes.func.isRequired,
|
||||
install: PropTypes.object.isRequired,
|
||||
step: PropTypes.number,
|
||||
web: PropTypes.object,
|
||||
dns: PropTypes.object,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { install } = state;
|
||||
const props = { install };
|
||||
return props;
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
actionCreators,
|
||||
)(Setup);
|
||||
19
client/src/install/Setup/renderField.js
Normal file
19
client/src/install/Setup/renderField.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
const renderField = ({
|
||||
input, className, placeholder, type, disabled, autoComplete, meta: { touched, error },
|
||||
}) => (
|
||||
<Fragment>
|
||||
<input
|
||||
{...input}
|
||||
placeholder={placeholder}
|
||||
type={type}
|
||||
className={className}
|
||||
disabled={disabled}
|
||||
autoComplete={autoComplete}
|
||||
/>
|
||||
{!disabled && touched && (error && <span className="form__message form__message--error">{error}</span>)}
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
export default renderField;
|
||||
11
client/src/install/Setup/validate.js
Normal file
11
client/src/install/Setup/validate.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const validate = (values) => {
|
||||
const errors = {};
|
||||
|
||||
if (values.confirm_password !== values.password) {
|
||||
errors.confirm_password = 'Password mismatched';
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
export default validate;
|
||||
Reference in New Issue
Block a user