Skip to content

Commit b433ae6

Browse files
committed
using semantic redux form for Survey Form and updated React-Hot-Load
1 parent 9ce537a commit b433ae6

File tree

10 files changed

+111
-143
lines changed

10 files changed

+111
-143
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@
237237
"prettier-eslint-cli": "^4.4.2",
238238
"react-a11y": "^1.0.0",
239239
"react-addons-test-utils": "^15.4.2",
240-
"react-hot-loader": "^3.0.0-beta.3",
240+
"react-hot-loader": "^3.1.2",
241241
"react-to-html-webpack-plugin": "^2.2.0",
242242
"redux-devtools": "^3.3.2",
243243
"redux-devtools-dock-monitor": "^1.1.1",

src/client.js

+2
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,7 @@ global.socket = initSocket();
139139
await navigator.serviceWorker.ready;
140140
console.log('Service Worker Ready');
141141
});
142+
} else {
143+
console.log('I am DEV');
142144
}
143145
})();

src/components/CounterButton/CounterButton.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default class CounterButton extends Component {
2323
render() {
2424
const { count, increment, color } = this.props;
2525
return (
26-
<Button color={color} onClick={increment}>
26+
<Button color={color} onClick={increment} style={{ marginBottom: '10px' }}>
2727
You have clicked me {count} time{count === 1 ? '' : 's'}.
2828
</Button>
2929
);

src/components/SurveyForm/SurveyForm.js

+73-91
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
33
import { reduxForm, Field, fieldPropTypes } from 'redux-form';
4+
import { Form, Label, Input as InputComponent, Table, Button } from 'semantic-ui-react';
5+
import { CheckboxField } from 'react-semantic-redux-form';
46
import { connect } from 'react-redux';
57
import { isValidEmail } from 'redux/modules/survey';
68
import surveyValidation from './surveyValidation';
@@ -15,44 +17,46 @@ const Input = ({
1517
label,
1618
type,
1719
showAsyncValidating,
18-
className,
1920
styles,
21+
required,
22+
width,
2023
meta: {
2124
touched, error, dirty, active, visited, asyncValidating
22-
}
25+
},
26+
...rest
2327
}) => (
24-
<div className={`form-group ${error && touched ? 'has-error' : ''}`}>
25-
<label htmlFor={input.name} className="col-sm-2">
26-
{label}
27-
</label>
28-
<div className={`col-sm-8 ${styles.inputGroup}`}>
29-
{showAsyncValidating && asyncValidating && <i className={`fa fa-cog fa-spin ${styles.cog}`} />}
30-
<input {...input} type={type} className={className} id={input.name} />
31-
{error && touched && <div className="text-danger">{error}</div>}
32-
<div className={styles.flags}>
33-
{dirty && (
34-
<span className={styles.dirty} title="Dirty">
35-
D
36-
</span>
37-
)}
38-
{active && (
39-
<span className={styles.active} title="Active">
40-
A
41-
</span>
42-
)}
43-
{visited && (
44-
<span className={styles.visited} title="Visited">
45-
V
46-
</span>
47-
)}
48-
{touched && (
49-
<span className={styles.touched} title="Touched">
50-
T
51-
</span>
52-
)}
53-
</div>
28+
<Form.Field error={!!(touched && error)} required={required} className={styles.inputGroup}>
29+
{label && <label>{label}</label>}
30+
{showAsyncValidating && asyncValidating && <i className={`fa fa-cog fa-spin ${styles.cog}`} />}
31+
<InputComponent required={required} {...input} {...rest} />
32+
<div className={styles.flags}>
33+
{dirty && (
34+
<span className={styles.dirty} title="Dirty">
35+
D
36+
</span>
37+
)}
38+
{active && (
39+
<span className={styles.active} title="Active">
40+
A
41+
</span>
42+
)}
43+
{visited && (
44+
<span className={styles.visited} title="Visited">
45+
V
46+
</span>
47+
)}
48+
{touched && (
49+
<span className={styles.touched} title="Touched">
50+
T
51+
</span>
52+
)}
5453
</div>
55-
</div>
54+
{touched && error ? (
55+
<Label basic color="red" pointing>
56+
{error}
57+
</Label>
58+
) : null}
59+
</Form.Field>
5660
);
5761

5862
Input.propTypes = fieldPropTypes;
@@ -64,7 +68,7 @@ Input.propTypes = fieldPropTypes;
6468
asyncBlurFields: ['email']
6569
})
6670
@connect(state => ({
67-
active: state.form.survey.active
71+
active: state.form.survey ? state.form.survey.active : ''
6872
}))
6973
export default class SurveyForm extends Component {
7074
static propTypes = {
@@ -90,8 +94,8 @@ export default class SurveyForm extends Component {
9094

9195
return (
9296
<div>
93-
<form className="form-horizontal" onSubmit={handleSubmit}>
94-
<Field name="name" type="text" component={Input} label="Full Name" className="form-control" styles={styles} />
97+
<Form onSubmit={handleSubmit}>
98+
<Field name="name" type="text" component={Input} label="Full Name" styles={styles} />
9599

96100
<Field
97101
name="email"
@@ -112,66 +116,44 @@ export default class SurveyForm extends Component {
112116
styles={styles}
113117
/>
114118

115-
<Field
116-
name="currentlyEmployed"
117-
type="checkbox"
118-
component={Input}
119-
label="Currently Employed?"
120-
styles={styles}
121-
/>
122-
123-
<div className="form-group">
124-
<label htmlFor="sex" className="col-sm-2">
125-
Sex
126-
</label>
127-
<div className="col-sm-8">
128-
<label htmlFor="sex-male" className={styles.radioLabel}>
129-
<Field name="sex" component="input" type="radio" id="sex-male" value="male" /> Male
130-
</label>
131-
<label htmlFor="sex-female" className={styles.radioLabel}>
132-
<Field name="sex" component="input" type="radio" id="sex-female" value="female" /> Female
133-
</label>
134-
</div>
135-
</div>
119+
<Field name="currentlyEmployed" component={CheckboxField} label="Currently Employed?" styles={styles} />
136120

137-
<div className="form-group">
138-
<div className="col-sm-offset-2 col-sm-10">
139-
<button className="btn btn-success" onClick={handleSubmit}>
140-
<i className="fa fa-paper-plane" /> Submit
141-
</button>
142-
<button className="btn btn-warning" type="button" onClick={reset} style={{ marginLeft: 15 }}>
143-
<i className="fa fa-undo" /> Reset
144-
</button>
145-
</div>
121+
<div>
122+
<Button positive onClick={handleSubmit}>
123+
Submit
124+
</Button>
125+
<Button as="a" negative onClick={reset}>
126+
Reset
127+
</Button>
146128
</div>
147-
</form>
129+
</Form>
148130

149131
<h4>Props from redux-form</h4>
150132

151-
<table className="table table-striped">
152-
<tbody>
153-
<tr>
154-
<th>Active Field</th>
155-
<td>{active}</td>
156-
</tr>
157-
<tr>
158-
<th>Dirty</th>
159-
<td className={dirty ? 'success' : 'danger'}>{dirty ? 'true' : 'false'}</td>
160-
</tr>
161-
<tr>
162-
<th>Pristine</th>
163-
<td className={pristine ? 'success' : 'danger'}>{pristine ? 'true' : 'false'}</td>
164-
</tr>
165-
<tr>
166-
<th>Valid</th>
167-
<td className={valid ? 'success' : 'danger'}>{valid ? 'true' : 'false'}</td>
168-
</tr>
169-
<tr>
170-
<th>Invalid</th>
171-
<td className={invalid ? 'success' : 'danger'}>{invalid ? 'true' : 'false'}</td>
172-
</tr>
173-
</tbody>
174-
</table>
133+
<Table celled>
134+
<Table.Body>
135+
<Table.Row>
136+
<Table.Cell>Active Field</Table.Cell>
137+
<Table.Cell>{active}</Table.Cell>
138+
</Table.Row>
139+
<Table.Row>
140+
<Table.Cell>Dirty</Table.Cell>
141+
<Table.Cell className={dirty ? 'positive' : 'negative'}>{dirty ? 'true' : 'false'}</Table.Cell>
142+
</Table.Row>
143+
<Table.Row>
144+
<Table.Cell>Pristine</Table.Cell>
145+
<Table.Cell className={pristine ? 'positive' : 'negative'}>{pristine ? 'true' : 'false'}</Table.Cell>
146+
</Table.Row>
147+
<Table.Row>
148+
<Table.Cell>Valid</Table.Cell>
149+
<Table.Cell className={valid ? 'positive' : 'negative'}>{valid ? 'true' : 'false'}</Table.Cell>
150+
</Table.Row>
151+
<Table.Row>
152+
<Table.Cell>Invalid</Table.Cell>
153+
<Table.Cell className={invalid ? 'positive' : 'negative'}>{invalid ? 'true' : 'false'}</Table.Cell>
154+
</Table.Row>
155+
</Table.Body>
156+
</Table>
175157
</div>
176158
);
177159
}

src/components/SurveyForm/SurveyForm.scss

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
.flags {
66
position: absolute;
7-
right: 20px;
8-
top: 7px;
7+
right: 15px;
8+
top: 32px;
99
& > * {
1010
margin: 0 2px;
1111
width: 20px;

src/components/WidgetForm/WidgetForm.js

+17-38
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,12 @@
11
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
33
import { connect } from 'react-redux';
4-
import { reduxForm, Field, getFormValues, SubmissionError, fieldPropTypes } from 'redux-form';
4+
import { reduxForm, Field, getFormValues, SubmissionError } from 'redux-form';
5+
import { InputField, SelectField } from 'react-semantic-redux-form';
6+
import { Button, Message } from 'semantic-ui-react';
57
import * as widgetActions from 'redux/modules/widgets';
68
import widgetValidation, { colors } from './widgetValidation';
79

8-
const Input = ({ input, className, meta: { touched, error } }) => (
9-
<div>
10-
<input type="text" className={className} {...input} />
11-
{error && touched && <div className="text-danger">{error}</div>}
12-
</div>
13-
);
14-
15-
Input.propTypes = fieldPropTypes;
16-
17-
const Select = ({
18-
options, input, className, meta: { touched, error }
19-
}) => (
20-
<div>
21-
<select className={className} {...input}>
22-
{options.map(option => (
23-
<option value={option} key={option}>
24-
{option}
25-
</option>
26-
))}
27-
</select>
28-
{error && touched && <div className="text-danger">{error}</div>}
29-
</div>
30-
);
31-
32-
Select.propTypes = fieldPropTypes;
33-
3410
@reduxForm({
3511
form: 'widget',
3612
validate: widgetValidation
@@ -75,20 +51,19 @@ export default class WidgetForm extends Component {
7551
<Field name="id" type="hidden" component="input" />
7652
</td>
7753
<td className={styles.colorCol}>
78-
<Field name="color" className="ui input" component={Select} options={colors} />
54+
<Field name="color" component={SelectField} options={colors} />
7955
</td>
8056
<td className={styles.sprocketsCol}>
81-
<Field name="sprocketCount" className="ui input" component={Input} />
57+
<Field name="sprocketCount" component={InputField} />
8258
</td>
8359
<td className={styles.ownerCol}>
84-
<Field name="owner" className="ui input" component={Input} />
60+
<Field name="owner" component={InputField} />
8561
</td>
8662
<td className={styles.buttonCol}>
87-
<button className="btn btn-default" onClick={() => editStop(form)} disabled={submitting}>
88-
<i className="fa fa-ban" /> Cancel
89-
</button>
90-
<button
91-
className="btn btn-success"
63+
<Button onClick={() => editStop(form)} disabled={submitting}>
64+
Cancel
65+
</Button>
66+
<Button
9267
onClick={handleSubmit(() =>
9368
save(values).catch(err => {
9469
if (typeof err === 'object') {
@@ -98,9 +73,13 @@ export default class WidgetForm extends Component {
9873
}))}
9974
disabled={pristine || invalid || submitting}
10075
>
101-
<i className={`fa ${submitting ? 'fa-cog fa-spin' : 'fa-cloud'}`} /> Save
102-
</button>
103-
{saveError && <div className="text-danger">{saveError}</div>}
76+
Save
77+
</Button>
78+
{saveError && (
79+
<Message negative>
80+
<p>{saveError}</p>
81+
</Message>
82+
)}
10483
</td>
10584
</tr>
10685
);

src/components/WidgetForm/widgetValidation.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import { createValidator, required, maxLength, integer, oneOf } from 'utils/validation';
22

3-
export const colors = ['Blue', 'Fuchsia', 'Green', 'Orange', 'Red', 'Taupe'];
3+
export const colors = [
4+
{ key: 'blue', value: 'Blue', text: 'Blue' },
5+
{ key: 'fuchsia', value: 'Fuchsia', text: 'Fuchsia' },
6+
{ key: 'green', value: 'Green', text: 'Green' },
7+
{ key: 'orange', value: 'Orange', text: 'Orange' },
8+
{ key: 'red', value: 'Red', text: 'Red' },
9+
{ key: 'taupe', value: 'Taupe', text: 'Taupe' }
10+
];
411

512
const widgetValidation = createValidator({
6-
color: [required, oneOf(colors)],
13+
color: [required, oneOf(colors.map(item => item.value))],
714
sprocketCount: [required, integer],
815
owner: [required, maxLength(30)]
916
});

src/containers/Home/Home.scss

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
.counterContainer {
22
text-align: center;
3-
margin: 20px;
3+
margin: 20px 20px 10px;
44
}
5-
65
.logo img {
76
width: 150px;
87
margin: 0 10px;

src/containers/Survey/Survey.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { provideHooks } from 'redial';
44
import { connect } from 'react-redux';
55
import Helmet from 'react-helmet';
66
import { initialize } from 'redux-form';
7+
import { Button, Icon } from 'semantic-ui-react';
78
import reducer from 'redux/modules/survey';
89
import SurveyForm from 'components/SurveyForm/SurveyForm';
910

@@ -66,9 +67,9 @@ export default class Survey extends Component {
6667
</p>
6768

6869
<div style={{ textAlign: 'center', margin: 15 }}>
69-
<button className="btn btn-primary" onClick={this.handleInitialize}>
70-
<i className="fa fa-pencil" /> Initialize Form
71-
</button>
70+
<Button primary onClick={this.handleInitialize} icon>
71+
<Icon name="edit" /> Initialize Form
72+
</Button>
7273
</div>
7374

7475
<p>

src/containers/Widgets/Widgets.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,7 @@ export default class Widgets extends Component {
9999
<Table.Cell>{widget.sprocketCount}</Table.Cell>
100100
<Table.Cell>{widget.owner}</Table.Cell>
101101
<Table.Cell>
102-
<Button primary icon="edit" onClick={handleEdit(widget)}>
103-
Edit
104-
</Button>
102+
<Button onClick={handleEdit(widget)}>Edit</Button>
105103
</Table.Cell>
106104
</Table.Row>
107105
))}

0 commit comments

Comments
 (0)