diff --git a/client-render.js b/client-render.js index def88ba..23af70e 100644 --- a/client-render.js +++ b/client-render.js @@ -4,8 +4,6 @@ import { Router, browserHistory } from 'react-router'; import { routes } from './routes'; -// import createBrowserHistory from 'history/lib/createBrowserHistory'; - ReactDOM.render( , document.getElementById('app') diff --git a/components/about.js b/components/about.js index 2601496..659336f 100644 --- a/components/about.js +++ b/components/about.js @@ -1,10 +1,23 @@ import React from 'react'; +import EmailForm from './email-form'; export default class AboutComponent extends React.Component { + constructor(props) { + super(props); + const { success, errors, value } = this.props.location.query; + if (success) { + this.emailFormProps = { + success: success === "true", + errors: errors && errors.split(',') || [], + value + } + } + } render() { return (

A little bit about me.

+
); } diff --git a/components/email-form.js b/components/email-form.js new file mode 100644 index 0000000..77085da --- /dev/null +++ b/components/email-form.js @@ -0,0 +1,115 @@ +import React from 'react'; +import { Link } from 'react-router'; +import validateEmailForm from './validate-email-form'; + +export default class EmailForm extends React.Component { + constructor(props) { + super(props); + const { success, errors, value } = props; + this.state = { + success, + errors, + value: value || '' + }; + this.formSubmit = this.formSubmit.bind(this); + this.inputChange = this.inputChange.bind(this); + this.resetForm = this.resetForm.bind(this); + } + + formSubmittedSuccessfully() { + return this.state.success === true; + } + + inputChange(e) { + this.setState({ + value: e.target.value + }); + } + + resetForm(e) { + e.preventDefault(); + this.setState({ + success: undefined, + errors: [], + value: '' + }); + } + + formSubmit(e) { + e.preventDefault(); + const emailValue = this.state.value; + // note how this is the same validator we ran on the server! + const result = validateEmailForm(emailValue); + // at this point you could POST to an endpoint to save + // this to the database, or do whatever you need to + this.setState({ + errors: result.errors, + success: result.valid + }); + } + + renderErrorsList() { + return this.state.errors.map((err) => { + return ( +
  • +

    {err}

    +
  • + ); + }); + } + + renderForm() { + return ( +
    + +
    + + +
    + +
    + ); + } + + renderSuccess() { + return ( +
    +

    Thanks, {this.state.value} has been added to our totally cool list.

    + Reset page +
    + ) + } + + renderErrors() { + if (this.state.errors && this.state.errors.length > 0) { + return ( +
    +
    There were errors submitting this form.
    + +
    + ); + } else { + return null; + } + } + + render() { + return ( +
    + { this.renderErrors() } + { this.formSubmittedSuccessfully() ? this.renderSuccess() : this.renderForm() } +
    + ) + } +} + +EmailForm.propTypes = { + success: React.PropTypes.bool, + errors: React.PropTypes.arrayOf(React.PropTypes.string) +}; diff --git a/components/validate-email-form.js b/components/validate-email-form.js new file mode 100644 index 0000000..7e07027 --- /dev/null +++ b/components/validate-email-form.js @@ -0,0 +1,20 @@ +// write any logic for your form in one file that can be used on both the client and the server + +export default function(email) { + // IRL you probably want a better check! + if (email.indexOf('@') > -1) { + return { + valid: true, + email, + errors: [] + } + } else { + return { + valid: false, + email, + errors: [ + `Email address ${email} is not valid` + ] + } + } +} diff --git a/package.json b/package.json index fd26237..522a700 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "author": "", "license": "ISC", "dependencies": { + "body-parser": "^1.15.0", "ejs": "^2.3.4", "express": "^4.13.3", "history": "^1.13.1", @@ -34,6 +35,7 @@ "babel-loader": "^6.2.0", "babel-preset-es2015": "^6.1.18", "babel-preset-react": "^6.1.18", + "nodemon": "^1.9.1", "webpack": "^1.12.9" } } diff --git a/server.js b/server.js index ac66620..9fcc026 100644 --- a/server.js +++ b/server.js @@ -3,12 +3,17 @@ import express from 'express'; import React from 'react'; import { renderToString } from 'react-dom/server'; import { match, RouterContext } from 'react-router'; +import bodyParser from 'body-parser'; import { routes } from './routes'; +import validateEmailForm from './components/validate-email-form'; + const app = express(); app.use(express.static('public')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); app.set('view engine', 'ejs'); @@ -36,7 +41,22 @@ app.get('*', (req, res) => { } }); }); -app.listen(3003, 'localhost', function(err) { + +app.post('/submit-email-form', (req, res) => { + const { email } = req.body; + const result = validateEmailForm(email); + + if (result.valid === true) { + // here you would save this to a database, or whatever you want + // db.addEmail(email) + + res.redirect(`/about?success=true&value=${email}`); + } else { + res.redirect(`/about?errors=${result.errors.join(',')}&success=false&value=${email}`); + } +}); + +app.listen(3003, 'localhost', (err) => { if (err) { console.log(err); return;