diff --git a/package.json b/package.json
index ddf6b45..5f4bc04 100644
--- a/package.json
+++ b/package.json
@@ -17,13 +17,15 @@
],
"dependencies": {
"axios": "^0.4.2",
- "virtual-dom": "^1.1.0"
+ "lodash": "^2.4.1",
+ "virtual-dom": "^1.2.0"
},
"devDependencies": {
- "coffee-script": "~1.8.0",
+ "6to5ify": "^3.1.2",
"bower": "~1.3.5",
"browserify": "~6.1.0",
"chalk": "~0.5.1",
+ "coffee-script": "~1.8.0",
"deamdify": "^0.1.1",
"debowerify": "~0.9.1",
"ecstatic": "~0.5.3",
@@ -47,6 +49,7 @@
},
"browserify": {
"transform": [
+ "6to5ify",
"debowerify",
"deamdify"
]
diff --git a/src/jade/index.jade b/src/jade/index.jade
index c4fa83d..19fc407 100644
--- a/src/jade/index.jade
+++ b/src/jade/index.jade
@@ -17,6 +17,9 @@ html
Koodiklinikka on Slack-yhteisö kaikille ohjelmoinnista ja ohjelmistoalasta kiinnostuneille harrastajille ja ammattilaisille.
+ #invite-form
+ h3 Liity mukaan
+
.footer
a(href='https://koodiklinikka.slack.com') koodiklinikka.slack.com
diff --git a/src/js/components/inviteForm.js b/src/js/components/inviteForm.js
new file mode 100644
index 0000000..f0d6901
--- /dev/null
+++ b/src/js/components/inviteForm.js
@@ -0,0 +1,40 @@
+'use strict';
+
+var {h} = require('virtual-dom');
+var classList = require('../util/classList');
+
+function render(props, state) {
+ var emailInput = h('input', {
+ className: classList({
+ 'input': true,
+ 'has-success': state.submitted,
+ 'has-error': state.error
+ }),
+ type: 'text',
+ name: 'email',
+ placeholder: 'Email',
+ value: state.email,
+ onkeydown: props.onChange
+ });
+
+ var submitButton = h('button', {
+ className: 'btn btn__submit',
+ type: 'submit',
+ title: 'Lähetä',
+ disabled: state.error || state.submitted
+ }, '⏎');
+
+ return h('form', {
+ className: classList({
+ 'invite-form': true,
+ 'has-success': state.submitted,
+ 'has-error': state.error
+ }),
+ onsubmit: props.onSubmit
+ }, [
+ emailInput,
+ submitButton
+ ]);
+}
+
+module.exports = render;
diff --git a/src/js/main.js b/src/js/main.js
index 96af354..b243195 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -1,19 +1,62 @@
'use strict';
require('./ga');
+
+var _ = require('lodash');
var request = require('axios');
-var form = document.getElementById('invite');
-form.addEventListener('submit', function(event) {
- event.preventDefault();
- form.classList.remove('has-success', 'has-error');
- var email = event.target.elements.email.value;
+var inviteForm = require('./components/inviteForm');
+var {diff, patch, create} = require('virtual-dom');
+
+var state = {
+ email: '',
+ submitted: false,
+ error: false
+};
+
+function setState(newState) {
+ state = _.extend({}, state, newState);
+ rerender(state);
+}
+
+var props = {
+ onSubmit: function(e) {
+ e.preventDefault();
+
+ setState({
+ submitted: false,
+ error: false
+ });
+
+ request.post('/api/invites', {
+ email: state.email.email
+ }).then(function() {
+ setState({submitted: true});
+ }).catch(function() {
+ setState({error: true});
+ });
+ },
+ onChange: function(e) {
+ setState({
+ email: e.target.value,
+ error: false,
+ submitted: false
+ });
+ },
+};
+
+var tree = inviteForm(props, state);
+var rootNode = create(tree);
+
+document
+ .getElementById('invite-form')
+ .appendChild(rootNode);
+
+function rerender() {
+ var newTree = inviteForm(props, state);
+ var patches = diff(tree, newTree);
+ rootNode = patch(rootNode, patches);
+ tree = newTree;
+}
+
- request.post('/api/invites', {
- email: email
- }).then(function() {
- form.classList.add('has-success');
- }).catch(function() {
- form.classList.add('has-error');
- });
-});
diff --git a/src/js/util/classList.js b/src/js/util/classList.js
new file mode 100644
index 0000000..9a85b16
--- /dev/null
+++ b/src/js/util/classList.js
@@ -0,0 +1,11 @@
+'use strict';
+
+module.exports = function classList(classesObj) {
+ var classes = [];
+ for(var key in classesObj) {
+ if(!!classesObj[key]) {
+ classes.push(key);
+ }
+ }
+ return classes.join(' ');
+};