summaryrefslogtreecommitdiff
path: root/web-ui
diff options
context:
space:
mode:
authorRoald de Vries <rdevries@thoughtworks.com>2016-11-16 15:12:25 +0100
committerRoald de Vries <rdevries@thoughtworks.com>2016-11-16 15:23:06 +0100
commitac34bf4eeca60c967b43c9b693c56d7ae1125353 (patch)
treec51d62e96f6389c8d17bb95f1082bbfc109e1706 /web-ui
parentec96e998c0e0a153b0546f1ec0682c208c6876eb (diff)
mock up the first forms of signup
Diffstat (limited to 'web-ui')
-rw-r--r--web-ui/package.json22
-rw-r--r--web-ui/react/css/normalize.css461
-rw-r--r--web-ui/react/css/style.css174
-rw-r--r--web-ui/react/images/pixelated-logo-orange.svg29
-rw-r--r--web-ui/react/images/sent_email.pngbin0 -> 9160 bytes
-rw-r--r--web-ui/react/index.html18
-rw-r--r--web-ui/react/src/index.js163
7 files changed, 865 insertions, 2 deletions
diff --git a/web-ui/package.json b/web-ui/package.json
index 2a0056e4..c85889e9 100644
--- a/web-ui/package.json
+++ b/web-ui/package.json
@@ -5,20 +5,23 @@
"repository": "https://github.com/pixelated-project/pixelated-user-agent",
"private": true,
"devDependencies": {
+ "babel": "^6.5.2",
+ "babel-cli": "^6.18.0",
"bower": "1.7.9",
+ "browserify": "^13.1.1",
"handlebars": "4.0.5",
"html-minifier": "2.1.6",
"imagemin": "5.2.1",
"jshint": "2.9.2",
"karma": "0.13.19",
"karma-chrome-launcher": "0.2.2",
+ "karma-coverage": "0.2.7",
"karma-firefox-launcher": "0.1.7",
"karma-jasmine": "0.2.2",
"karma-jasmine-ajax": "0.1.13",
"karma-junit-reporter": "0.2.2",
"karma-phantomjs-launcher": "1.0.1",
"karma-requirejs": "1.0.0",
- "karma-coverage": "0.2.7",
"minify": "2.0.9",
"requirejs": "2.2.0",
"watch": "0.19.1"
@@ -32,7 +35,8 @@
"handlebars-watch": "node_modules/.bin/watch 'npm run handlebars' app/templates",
"compass": "compass compile",
"compass-watch": "compass watch",
- "build": "npm run clean && npm run handlebars && npm run add_git_version && npm run compass",
+ "build": "npm run clean && npm run handlebars && npm run add_git_version && npm run compass && npm run build-react",
+ "build-react": "babel react/src -d react/lib && browserify react/lib/index.js >react/bundle.js",
"jshint": "node_modules/jshint/bin/jshint --config=.jshintrc app test",
"clean": "rm -rf .tmp/ 'dist/*' app/js/generated/hbs/* app/css/*",
"buildmain": "node_modules/requirejs/bin/r.js -o config/buildoptions.js",
@@ -41,5 +45,19 @@
"minify_html": "node_modules/.bin/html-minifier app/index.html --collapse-whitespace | sed 's|<!--usemin_start-->.*<!--usemin_end-->|<script src=\"assets/app.min.js\" type=\"text/javascript\"></script>|' > dist/index.html",
"minify_sandbox": "node_modules/.bin/html-minifier app/sandbox.html --collapse-whitespace | sed 's|<!--usemin_start-->.*<!--usemin_end-->|<script src=\"sandbox.min.js\" type=\"text/javascript\"></script>|' > dist/sandbox.html",
"add_git_version": "/bin/bash config/add_git_version.sh"
+ },
+ "dependencies": {
+ "babel-preset-es2015": "^6.18.0",
+ "babel-preset-react": "^6.16.0",
+ "immutable": "^3.8.1",
+ "react": "^15.3.2",
+ "react-dom": "^15.3.2",
+ "redux": "^3.6.0"
+ },
+ "babel": {
+ "presets": [
+ "es2015",
+ "react"
+ ]
}
}
diff --git a/web-ui/react/css/normalize.css b/web-ui/react/css/normalize.css
new file mode 100644
index 00000000..9b77e0eb
--- /dev/null
+++ b/web-ui/react/css/normalize.css
@@ -0,0 +1,461 @@
+/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
+
+/**
+ * 1. Change the default font family in all browsers (opinionated).
+ * 2. Correct the line height in all browsers.
+ * 3. Prevent adjustments of font size after orientation changes in
+ * IE on Windows Phone and in iOS.
+ */
+
+/* Document
+ ========================================================================== */
+
+html {
+ font-family: sans-serif; /* 1 */
+ line-height: 1.15; /* 2 */
+ -ms-text-size-adjust: 100%; /* 3 */
+ -webkit-text-size-adjust: 100%; /* 3 */
+}
+
+/* Sections
+ ========================================================================== */
+
+/**
+ * Remove the margin in all browsers (opinionated).
+ */
+
+body {
+ margin: 0;
+}
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+article,
+aside,
+footer,
+header,
+nav,
+section {
+ display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in IE.
+ */
+
+figcaption,
+figure,
+main { /* 1 */
+ display: block;
+}
+
+/**
+ * Add the correct margin in IE 8.
+ */
+
+figure {
+ margin: 1em 40px;
+}
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box; /* 1 */
+ height: 0; /* 1 */
+ overflow: visible; /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * 1. Remove the gray background on active links in IE 10.
+ * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
+ */
+
+a {
+ background-color: transparent; /* 1 */
+ -webkit-text-decoration-skip: objects; /* 2 */
+}
+
+/**
+ * Remove the outline on focused links when they are also active or hovered
+ * in all browsers (opinionated).
+ */
+
+a:active,
+a:hover {
+ outline-width: 0;
+}
+
+/**
+ * 1. Remove the bottom border in Firefox 39-.
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+ border-bottom: none; /* 1 */
+ text-decoration: underline; /* 2 */
+ text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
+ */
+
+b,
+strong {
+ font-weight: inherit;
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/**
+ * Add the correct font style in Android 4.3-.
+ */
+
+dfn {
+ font-style: italic;
+}
+
+/**
+ * Add the correct background and color in IE 9-.
+ */
+
+mark {
+ background-color: #ff0;
+ color: #000;
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+audio,
+video {
+ display: inline-block;
+}
+
+/**
+ * Add the correct display in iOS 4-7.
+ */
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+/**
+ * Remove the border on images inside links in IE 10-.
+ */
+
+img {
+ border-style: none;
+}
+
+/**
+ * Hide the overflow in IE.
+ */
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers (opinionated).
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: sans-serif; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+ margin: 0; /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input { /* 1 */
+ overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select { /* 1 */
+ text-transform: none;
+}
+
+/**
+ * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+ * controls in Android 4.
+ * 2. Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+html [type="button"], /* 1 */
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button; /* 2 */
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/**
+ * Change the border, margin, and padding in all browsers (opinionated).
+ */
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
+ */
+
+legend {
+ box-sizing: border-box; /* 1 */
+ color: inherit; /* 2 */
+ display: table; /* 1 */
+ max-width: 100%; /* 1 */
+ padding: 0; /* 3 */
+ white-space: normal; /* 1 */
+}
+
+/**
+ * 1. Add the correct display in IE 9-.
+ * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+ display: inline-block; /* 1 */
+ vertical-align: baseline; /* 2 */
+}
+
+/**
+ * Remove the default vertical scrollbar in IE.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10-.
+ * 2. Remove the padding in IE 10-.
+ */
+
+[type="checkbox"],
+[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+}
+
+/**
+ * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+}
+
+/* Interactive
+ ========================================================================== */
+
+/*
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in Edge, IE, and Firefox.
+ */
+
+details, /* 1 */
+menu {
+ display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
+}
+
+/* Scripting
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 9-.
+ */
+
+canvas {
+ display: inline-block;
+}
+
+/**
+ * Add the correct display in IE.
+ */
+
+template {
+ display: none;
+}
+
+/* Hidden
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 10-.
+ */
+
+[hidden] {
+ display: none;
+}
diff --git a/web-ui/react/css/style.css b/web-ui/react/css/style.css
new file mode 100644
index 00000000..61ac8587
--- /dev/null
+++ b/web-ui/react/css/style.css
@@ -0,0 +1,174 @@
+body {
+ font-family: "Open Sans", "Microsoft YaHei", "Hiragino Sans GB", "Hiragino Sans GB W3", "微软雅黑", "Helvetica Neue", Arial, sans-serif;
+}
+
+.field-group {
+ position:relative;
+ margin-bottom: 35px;
+}
+
+label {
+ font-size: 0.9em;
+ margin-bottom: 10px;
+ display: inline-block;
+}
+
+input {
+ display: block;
+ border: solid 1px #4da3b6;
+ width: 100%;
+ height: auto;
+ padding: 10px 5px;
+ margin-bottom: 20px;
+}
+
+.animated-label {
+ color:#999;
+ position:absolute;
+ pointer-events:none;
+ left: 6px;
+ top:10px;
+ transition:0.2s ease all;
+ -moz-transition:0.2s ease all;
+ -webkit-transition:0.2s ease all;
+}
+
+input:focus {
+ outline:none;
+}
+
+input:focus ~ .animated-label, input:valid ~ .animated-label{
+ top:-20px;
+ left: 0;
+ font-size:0.8em;
+ color:#4da3b6;
+}
+
+.blue-button {
+ background: #178ca6;
+ color: white;
+ display: block;
+ text-decoration: none;
+ text-align: center;
+ padding: 10px 0 10px 0;
+ width: 104%;
+ margin: 0 auto;
+}
+
+.blue-button:hover {
+ background: #4da3b6;
+}
+
+a {
+ text-decoration: none;
+ color: #4da3b6;
+}
+
+h1 {
+ font-size: 1.5em;
+ text-align: center;
+}
+
+header {
+ width: 18%;
+ margin: 0 auto;
+}
+
+.link-message {
+ text-align: center;
+ font-size: 0.8em;
+}
+
+.logo {
+ width: 100%;
+ height: auto;
+ padding-top: 20%;
+ margin-bottom: 30px;
+}
+
+.message h1 {
+ margin-bottom: 35px;
+}
+
+.message p {
+ padding-left: 5%;
+ padding-right: 5%;
+ width: 40%;
+ margin: 0 auto;
+ text-align: center;
+ line-height: 1.8em;
+ font-size: 0.9em;
+}
+
+.form-container {
+ width: 20%;
+ margin: 0 auto;
+ padding-top: 40px;
+}
+
+.domain-label {
+ position: relative;
+ top: 26px;
+ padding-left: 20px;
+ left: 100%;
+}
+
+.sent-email-icon {
+ width: 60px;
+}
+
+.disabled {
+ pointer-events: none;
+ background: #d4d4d4;
+}
+
+.link-message .disabled {
+ pointer-events: none;
+ color: #d4d4d4;
+ background: none;
+}
+
+/* Medium Devices, Desktops */
+@media only screen and (max-width : 992px) {
+ header {
+ width: 20%;
+ }
+
+ .form-container {
+ width: 30%;
+ }
+
+ .message p {
+ width: 70%
+ }
+}
+
+/* Small Devices, Tablets */
+@media only screen and (max-width : 768px) {
+ header {
+ width: 30%;
+ }
+
+ .form-container {
+ width: 50%;
+ }
+
+ .message p {
+ width: 80%
+ }
+}
+
+/* Extra Small Devices, Phones */
+@media only screen and (max-width : 480px) {
+ header {
+ width: 60%;
+ }
+
+ .form-container {
+ width: 80%;
+ }
+
+ .message p {
+ width: 85%
+ }
+}
diff --git a/web-ui/react/images/pixelated-logo-orange.svg b/web-ui/react/images/pixelated-logo-orange.svg
new file mode 100644
index 00000000..7e0ef43d
--- /dev/null
+++ b/web-ui/react/images/pixelated-logo-orange.svg
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="509.707px" height="142.439px" viewBox="0 0 509.707 142.439" enable-background="new 0 0 509.707 142.439"
+ xml:space="preserve">
+<g>
+ <path fill="#F9A731" d="M0,35.469v71.365l62.837,35.605l62.833-35.605V35.469L62.813,0L0,35.469z M60.262,116.617L23.735,96.332
+ V52.46l36.586,20.999L60.262,116.617z M101.936,96.332l-36.148,20.285l0.067-43.123l36.081-21.034V96.332z M101.936,46.44
+ L62.951,69.553L23.733,46.44l39.218-21.131L101.936,46.44z"/>
+ <path fill="#F9A731" d="M169.505,42.332h-19.968v59.328h13.52V79.655h6.448c11.579,0,20.279-6.832,20.279-19.056
+ C189.784,48.302,181.084,42.332,169.505,42.332z M166.866,68.868h-3.809v-15.75h3.809c5.323,0,10.357,1.798,10.357,7.91
+ C177.224,67.07,172.189,68.868,166.866,68.868z"/>
+ <rect x="194.309" y="42.332" fill="#F9A731" width="13.52" height="59.328"/>
+ <polygon fill="#F9A731" points="266.516,42.332 249.689,42.332 238.759,58.514 227.827,42.332 211.721,42.332 230.417,69.73
+ 210.228,101.66 226.982,101.66 238.759,81.453 250.534,101.66 268.01,101.66 247.099,69.73 "/>
+ <polygon fill="#F9A731" points="270.128,101.66 304.069,101.66 304.069,89.795 283.647,89.795 283.647,77.857 303.207,77.857
+ 303.207,65.991 283.647,65.991 283.647,54.199 304.069,54.199 304.069,42.332 270.128,42.332 "/>
+ <path fill="#F9A731" d="M354.807,42.332l-19.156,47.463H322.33V42.332h-13.52v59.328h22.053h11.888h2.636l4.386-11.865h22.578
+ l4.391,11.865h14.524l-23.944-59.328H354.807z M354.377,77.928l6.614-17.257h0.145l6.615,17.257H354.377z"/>
+ <polygon fill="#F9A731" points="379.939,54.199 394.073,54.199 394.073,101.66 407.592,101.66 407.592,54.199 421.687,54.199
+ 421.687,42.332 379.939,42.332 "/>
+ <polygon fill="#F9A731" points="426.265,101.66 460.207,101.66 460.207,89.795 439.785,89.795 439.785,77.857 459.344,77.857
+ 459.344,65.991 439.785,65.991 439.785,54.199 460.207,54.199 460.207,42.332 426.265,42.332 "/>
+ <path fill="#F9A731" d="M479.792,42.332h-14.94v59.328h14.94c16.324,0,29.914-12.37,29.914-29.699
+ C509.707,54.701,496.044,42.332,479.792,42.332z M480.457,89.577h-2.084V54.414h2.084c10.067,0,16.9,7.695,16.9,17.619
+ C497.285,81.955,490.455,89.577,480.457,89.577z"/>
+</g>
+</svg>
diff --git a/web-ui/react/images/sent_email.png b/web-ui/react/images/sent_email.png
new file mode 100644
index 00000000..ddaa11d0
--- /dev/null
+++ b/web-ui/react/images/sent_email.png
Binary files differ
diff --git a/web-ui/react/index.html b/web-ui/react/index.html
new file mode 100644
index 00000000..a1836721
--- /dev/null
+++ b/web-ui/react/index.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <title>Pixelated Mail</title>
+ <meta name="description" content="">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" href="bundle.css">
+ </head>
+ <body>
+ <header><img src="images/pixelated-logo-orange.svg" alt="Pixelated" class="logo"/></header>
+ <div class="message">
+ <div id="app"></div>
+ <script src="bundle.js"></script>
+ </div>
+ </body>
+</html>
diff --git a/web-ui/react/src/index.js b/web-ui/react/src/index.js
new file mode 100644
index 00000000..ae52867f
--- /dev/null
+++ b/web-ui/react/src/index.js
@@ -0,0 +1,163 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import {createStore} from 'redux';
+import {Map} from 'immutable';
+
+
+class PixelatedComponent extends React.Component {
+ _updateStateFromStore() {
+ this.setState(this.props.store.getState().toJS());
+ }
+
+ componentWillMount() {
+ console.debug('mounting', this);
+ this.unsubscribe = this.props.store.subscribe(() => this._updateStateFromStore());
+ this._updateStateFromStore();
+ }
+
+ componentWillUnmount() {
+ console.debug('unmounting', this);
+ this.unsubscribe()
+ }
+}
+
+
+class InviteCodeForm extends PixelatedComponent {
+ render() {
+ return (
+ <form onSubmit={this._handleClick.bind(this)}>
+ <div className="field-group">
+ <input type="text" name="invite-code" className="invite-code" required/>
+ <label className="animated-label" htmlFor="invite-code">invite code</label>
+ </div>
+ <input type="submit" value="Get Started" className="blue-button validation-link" />
+ </form>
+ );
+ }
+
+ _handleClick(event) {
+ event.stopPropagation();
+ event.preventDefault();
+ this.props.store.dispatch({type: 'SUBMIT_INVITE_CODE'});
+ }
+}
+
+
+class CreateAccountForm extends PixelatedComponent {
+ render() {
+ return (
+ <form onSubmit={this._handleClick.bind(this)}>
+ <span className="domain-label"> @domain.com </span>
+ <div className="field-group">
+ <input type="text" name="username" className="username" required/>
+ <label className="animated-label" htmlFor="username">username</label>
+ </div>
+
+ <div className="field-group">
+ <input type="password" name="password" className="password" required/>
+ <label className="animated-label" htmlFor="password">password</label>
+ </div>
+
+ <div className="field-group">
+ <input type="text" name="name" className="name" required/>
+ <label className="animated-label" htmlFor="name">name</label>
+ </div>
+
+ <input type="submit" value="Create my account" className="blue-button validation-link" />
+ </form>
+ );
+ }
+
+ _handleClick(event) {
+ event.stopPropagation();
+ event.preventDefault();
+ this.props.store.dispatch({type: 'SUBMIT_CREATE_ACCOUNT'});
+ }
+}
+
+
+class BackupEmailForm extends PixelatedComponent {
+ render() {
+ return (
+ <form onSubmit={this._handleClick.bind(this)}>
+ <span className="domain-label"> @domain.com </span>
+ <div className="field-group">
+ <input type="text" name="username" className="username" required/>
+ <label className="animated-label" htmlFor="username">username</label>
+ </div>
+
+ <div className="field-group">
+ <input type="password" name="password" className="password" required/>
+ <label className="animated-label" htmlFor="password">password</label>
+ </div>
+
+ <input type="submit" value="Create my account" className="blue-button validation-link" />
+ </form>
+ );
+ }
+
+ _handleClick(event) {
+ event.stopPropagation();
+ event.preventDefault();
+ this.props.store.dispatch({type: 'SUBMIT_CREATE_ACCOUNT'});
+ }
+}
+
+
+class SignUp extends PixelatedComponent {
+ render() {
+ return (
+ <div>
+ <div className="message">
+ <h1>{this.state.header}</h1>
+ <p>{this.state.summary}</p>
+ </div>
+ <div className="form-container">
+ {this._form()}
+ </div>
+ </div>
+ );
+ }
+
+ _form() {
+ switch(this.state.form) {
+ case 'invite_code': return <InviteCodeForm store={store} />;
+ case 'create_account': return <CreateAccountForm store={store} />;
+ case 'backup_email': return <BackupEmailForm store={store} />;
+ default: throw Exception('TODO');
+ }
+ }
+}
+
+
+const initialState = new Map({
+ form: 'invite_code',
+ header: 'Welcome',
+ summary: ['Do you have an invite code?', <br/>, 'Type it below'],
+});
+
+
+const store = createStore((state=initialState, action) => {
+ switch (action.type) {
+ case 'SUBMIT_INVITE_CODE':
+ return state.merge({
+ form: 'create_account',
+ header: 'Create your account',
+ summary: 'Choose your username, and be careful about your password, it must be strong and easy to remember. If you have a password manager, we strongly advise you to use one.',
+ });
+ case 'SUBMIT_CREATE_ACCOUNT':
+ return state.merge({
+ form: 'backup_email',
+ header: 'In case you lose your password...',
+ summary: 'Set up a backup email account. You\'ll receive an email with a code so you can recover your account in the future, other will be sent to your account administrator.',
+ });
+ default:
+ return state;
+ }
+});
+
+
+ReactDOM.render(
+ <SignUp store={store}/>,
+ document.getElementById('app')
+);