diff --git a/src/ComponentBroker.js b/src/ComponentBroker.js
index f3670bf65c..1d524267ec 100644
--- a/src/ComponentBroker.js
+++ b/src/ComponentBroker.js
@@ -1,7 +1,7 @@
var components = {};
function load(name) {
- var module = require("./"+name);
+ var module = require("./views/"+name);
components[name] = module;
return module;
};
@@ -23,17 +23,19 @@ module.exports = {
// otherwise browserify has no way of knowing what module to include
// Must be in this file (because the require is file-specific) and
// must be at the end because the components include this file.
-require('./atoms/LogoutButton');
-require('./atoms/MessageTimestamp');
-require('./molecules/MatrixToolbar');
-require('./molecules/RoomTile');
-require('./molecules/MessageTile');
-require('./molecules/SenderProfile');
-require('./molecules/UnknownMessageTile');
-require('./molecules/MTextTile');
-require('./molecules/MEmoteTile');
-require('./molecules/RoomHeader');
-require('./molecules/MessageComposer');
-require('./organisms/RoomList');
-require('./organisms/RoomView');
-require('./templates/Login');
+require('./views/atoms/LogoutButton');
+require('./views/atoms/MessageTimestamp');
+require('./views/molecules/MatrixToolbar');
+require('./views/molecules/RoomTile');
+require('./views/molecules/MessageTile');
+require('./views/molecules/SenderProfile');
+require('./views/molecules/UnknownMessageTile');
+require('./views/molecules/MTextTile');
+require('./views/molecules/MEmoteTile');
+require('./views/molecules/RoomHeader');
+require('./views/molecules/MessageComposer');
+require('./views/molecules/ProgressBar');
+require('./views/molecules/ServerConfig');
+require('./views/organisms/RoomList');
+require('./views/organisms/RoomView');
+require('./views/templates/Login');
diff --git a/src/controllers/atoms/LogoutButton.js b/src/controllers/atoms/LogoutButton.js
new file mode 100644
index 0000000000..cac1776aad
--- /dev/null
+++ b/src/controllers/atoms/LogoutButton.js
@@ -0,0 +1,9 @@
+var dis = require("../../dispatcher");
+
+module.exports = {
+ onClick: function() {
+ dis.dispatch({
+ action: 'logout'
+ });
+ },
+};
diff --git a/src/controllers/atoms/MessageTimestamp.js b/src/controllers/atoms/MessageTimestamp.js
new file mode 100644
index 0000000000..dd4f002d46
--- /dev/null
+++ b/src/controllers/atoms/MessageTimestamp.js
@@ -0,0 +1,3 @@
+module.exports = {
+};
+
diff --git a/src/controllers/molecules/MEmoteTile.js b/src/controllers/molecules/MEmoteTile.js
new file mode 100644
index 0000000000..dd4f002d46
--- /dev/null
+++ b/src/controllers/molecules/MEmoteTile.js
@@ -0,0 +1,3 @@
+module.exports = {
+};
+
diff --git a/src/controllers/molecules/MTextTile.js b/src/controllers/molecules/MTextTile.js
new file mode 100644
index 0000000000..dd4f002d46
--- /dev/null
+++ b/src/controllers/molecules/MTextTile.js
@@ -0,0 +1,3 @@
+module.exports = {
+};
+
diff --git a/src/controllers/molecules/MatrixToolbar.js b/src/controllers/molecules/MatrixToolbar.js
new file mode 100644
index 0000000000..dd4f002d46
--- /dev/null
+++ b/src/controllers/molecules/MatrixToolbar.js
@@ -0,0 +1,3 @@
+module.exports = {
+};
+
diff --git a/src/molecules/MessageComposer.js b/src/controllers/molecules/MessageComposer.js
similarity index 75%
rename from src/molecules/MessageComposer.js
rename to src/controllers/molecules/MessageComposer.js
index 56fcdb18f8..61c4f30914 100644
--- a/src/molecules/MessageComposer.js
+++ b/src/controllers/molecules/MessageComposer.js
@@ -1,10 +1,8 @@
-var React = require('react');
+var MatrixClientPeg = require("../../MatrixClientPeg");
-var MatrixClientPeg = require("../MatrixClientPeg");
+var dis = require("../../dispatcher");
-var dis = require("../dispatcher");
-
-module.exports = React.createClass({
+module.exports = {
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
},
@@ -43,13 +41,5 @@ module.exports = React.createClass({
ev.preventDefault();
}
},
-
- render: function() {
- return (
-
-
-
- );
- },
-});
+};
diff --git a/src/controllers/molecules/MessageTile.js b/src/controllers/molecules/MessageTile.js
new file mode 100644
index 0000000000..dd4f002d46
--- /dev/null
+++ b/src/controllers/molecules/MessageTile.js
@@ -0,0 +1,3 @@
+module.exports = {
+};
+
diff --git a/src/controllers/molecules/ProgressBar.js b/src/controllers/molecules/ProgressBar.js
new file mode 100644
index 0000000000..847e970dba
--- /dev/null
+++ b/src/controllers/molecules/ProgressBar.js
@@ -0,0 +1,6 @@
+module.exports = {
+ propTypes: {
+ value: React.PropTypes.number,
+ max: React.PropTypes.number
+ },
+};
diff --git a/src/controllers/molecules/RoomHeader.js b/src/controllers/molecules/RoomHeader.js
new file mode 100644
index 0000000000..dd4f002d46
--- /dev/null
+++ b/src/controllers/molecules/RoomHeader.js
@@ -0,0 +1,3 @@
+module.exports = {
+};
+
diff --git a/src/controllers/molecules/RoomTile.js b/src/controllers/molecules/RoomTile.js
new file mode 100644
index 0000000000..291c513f8d
--- /dev/null
+++ b/src/controllers/molecules/RoomTile.js
@@ -0,0 +1,10 @@
+var dis = require("../../dispatcher");
+
+module.exports = {
+ onClick: function() {
+ dis.dispatch({
+ action: 'view_room',
+ room_id: this.props.room.roomId
+ });
+ },
+};
diff --git a/src/controllers/molecules/SenderProfile.js b/src/controllers/molecules/SenderProfile.js
new file mode 100644
index 0000000000..dd4f002d46
--- /dev/null
+++ b/src/controllers/molecules/SenderProfile.js
@@ -0,0 +1,3 @@
+module.exports = {
+};
+
diff --git a/src/molecules/ServerConfig.js b/src/controllers/molecules/ServerConfig.js
similarity index 62%
rename from src/molecules/ServerConfig.js
rename to src/controllers/molecules/ServerConfig.js
index 5a874fa05e..14dbe0a72d 100644
--- a/src/molecules/ServerConfig.js
+++ b/src/controllers/molecules/ServerConfig.js
@@ -1,6 +1,6 @@
-var React = require('react');
+var React = require("react");
-module.exports = React.createClass({
+module.exports = {
propTypes: {
onHsUrlChanged: React.PropTypes.func,
onIsUrlChanged: React.PropTypes.func,
@@ -41,21 +41,4 @@ module.exports = React.createClass({
getIsUrl: function() {
return this.state.is_url;
},
-
- render: function() {
- return (
-
- );
- }
-});
+};
diff --git a/src/controllers/molecules/UnknownMessageTile.js b/src/controllers/molecules/UnknownMessageTile.js
new file mode 100644
index 0000000000..7be35b6b6e
--- /dev/null
+++ b/src/controllers/molecules/UnknownMessageTile.js
@@ -0,0 +1,2 @@
+module.exports = {
+};
diff --git a/src/organisms/RoomList.js b/src/controllers/organisms/RoomList.js
similarity index 80%
rename from src/organisms/RoomList.js
rename to src/controllers/organisms/RoomList.js
index e335c89921..a07f6d47e5 100644
--- a/src/organisms/RoomList.js
+++ b/src/controllers/organisms/RoomList.js
@@ -1,12 +1,11 @@
-var React = require('react');
+var React = require("react");
+var MatrixClientPeg = require("../../MatrixClientPeg");
-var MatrixClientPeg = require("../MatrixClientPeg");
-var ComponentBroker = require('../ComponentBroker');
+var ComponentBroker = require('../../ComponentBroker');
var RoomTile = ComponentBroker.get("molecules/RoomTile");
-
-module.exports = React.createClass({
+module.exports = {
componentWillMount: function() {
var cli = MatrixClientPeg.get();
cli.on("Room.timeline", this.onRoomTimeline);
@@ -56,15 +55,5 @@ module.exports = React.createClass({
);
});
},
-
- render: function() {
- return (
-
-
- {this.makeRoomTiles()}
-
-
- );
- }
-});
+};
diff --git a/src/organisms/RoomView.js b/src/controllers/organisms/RoomView.js
similarity index 60%
rename from src/organisms/RoomView.js
rename to src/controllers/organisms/RoomView.js
index f8ecbdf959..35e7aab1c2 100644
--- a/src/organisms/RoomView.js
+++ b/src/controllers/organisms/RoomView.js
@@ -1,14 +1,6 @@
-var React = require('react');
+var MatrixClientPeg = require("../../MatrixClientPeg");
-var MatrixClientPeg = require("../MatrixClientPeg");
-var ComponentBroker = require('../ComponentBroker');
-
-var MessageTile = ComponentBroker.get('molecules/MessageTile');
-var RoomHeader = ComponentBroker.get('molecules/RoomHeader');
-var MessageComposer = ComponentBroker.get('molecules/MessageComposer');
-
-
-module.exports = React.createClass({
+module.exports = {
getInitialState: function() {
return {
room: MatrixClientPeg.get().getRoom(this.props.roomId)
@@ -41,26 +33,6 @@ module.exports = React.createClass({
});
},
- getMessageTiles: function() {
- return this.state.room.timeline.map(function(mxEv) {
- return (
-
- );
- });
- },
-
- render: function() {
- return (
-
-
-
- {this.getMessageTiles()}
-
-
-
- );
- },
-
componentDidMount: function() {
var messageUl = this.refs.messageList.getDOMNode();
messageUl.scrollTop = messageUl.scrollHeight;
@@ -72,5 +44,5 @@ module.exports = React.createClass({
messageUl.scrollTop = messageUl.scrollHeight;
}
}
-});
+};
diff --git a/src/pages/MatrixChat.js b/src/controllers/pages/MatrixChat.js
similarity index 61%
rename from src/pages/MatrixChat.js
rename to src/controllers/pages/MatrixChat.js
index 4c5988b488..61d3ba2e84 100644
--- a/src/pages/MatrixChat.js
+++ b/src/controllers/pages/MatrixChat.js
@@ -1,20 +1,11 @@
-var React = require('react');
-var ComponentBroker = require('../ComponentBroker');
-
-var RoomList = ComponentBroker.get('organisms/RoomList');
-var RoomView = ComponentBroker.get('organisms/RoomView');
-var MatrixToolbar = ComponentBroker.get('molecules/MatrixToolbar');
-var Login = ComponentBroker.get('templates/Login');
-
// should be atomised
var Loader = require("react-loader");
+var mxCliPeg = require("../../MatrixClientPeg");
-var mxCliPeg = require("../MatrixClientPeg");
+var dis = require("../../dispatcher");
-var dis = require("../dispatcher");
-
-module.exports = React.createClass({
+module.exports = {
getInitialState: function() {
return {
logged_in: !!(mxCliPeg.get() && mxCliPeg.get().credentials),
@@ -78,27 +69,5 @@ module.exports = React.createClass({
});
cli.startClient();
},
-
- render: function() {
- if (this.state.logged_in && this.state.ready) {
- return (
-
- );
- } else if (this.state.logged_in) {
- return (
-
- );
- } else {
- return (
-
- );
- }
- }
-});
+};
diff --git a/src/templates/Login.js b/src/controllers/templates/Login.js
similarity index 78%
rename from src/templates/Login.js
rename to src/controllers/templates/Login.js
index 34159f631c..b028c4202d 100644
--- a/src/templates/Login.js
+++ b/src/controllers/templates/Login.js
@@ -1,12 +1,11 @@
-var React = require('react');
-var MatrixClientPeg = require("../MatrixClientPeg");
+var MatrixClientPeg = require("../../MatrixClientPeg");
var Matrix = require("matrix-js-sdk");
-var ServerConfig = require("../molecules/ServerConfig");
-var ProgressBar = require("../molecules/ProgressBar");
-var Loader = require("react-loader");
+var ComponentBroker = require("../../ComponentBroker");
-module.exports = React.createClass({
+var ServerConfig = ComponentBroker.get("molecules/ServerConfig");
+
+module.exports = {
getInitialState: function() {
return {
step: 'choose_hs',
@@ -99,29 +98,4 @@ module.exports = React.createClass({
);
}
},
-
- loginContent: function() {
- if (this.state.busy) {
- return (
-
- );
- } else {
- return (
-
-
Please log in:
- {this.componentForStep(this.state.step)}
-
{this.state.errorText}
-
- );
- }
- },
-
- render: function() {
- return (
-
-
- {this.loginContent()}
-
- );
- }
-});
+};
diff --git a/src/index.js b/src/index.js
index 6edda44d28..b6d3027545 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1 +1 @@
-module.exports.MatrixChat = require("./pages/MatrixChat");
+module.exports.MatrixChat = require("./views/pages/MatrixChat");
diff --git a/src/atoms/LogoutButton.js b/src/views/atoms/LogoutButton.js
similarity index 62%
rename from src/atoms/LogoutButton.js
rename to src/views/atoms/LogoutButton.js
index bfb9cce48d..4e09b197c0 100644
--- a/src/atoms/LogoutButton.js
+++ b/src/views/atoms/LogoutButton.js
@@ -1,13 +1,9 @@
var React = require('react');
-var dis = require("../dispatcher");
+var LogoutButtonController = require("../../controllers/atoms/LogoutButton");
module.exports = React.createClass({
- onClick: function() {
- dis.dispatch({
- action: 'logout'
- });
- },
+ mixins: [LogoutButtonController],
render: function() {
return (
diff --git a/src/atoms/MessageTimestamp.js b/src/views/atoms/MessageTimestamp.js
similarity index 69%
rename from src/atoms/MessageTimestamp.js
rename to src/views/atoms/MessageTimestamp.js
index 4ccb318e42..340e6e02a0 100644
--- a/src/atoms/MessageTimestamp.js
+++ b/src/views/atoms/MessageTimestamp.js
@@ -1,6 +1,10 @@
var React = require('react');
+var MessageTimestampController = require("../../controllers/atoms/MessageTimestamp");
+
module.exports = React.createClass({
+ mixins: [MessageTimestampController],
+
render: function() {
var date = new Date(this.props.ts);
return (
diff --git a/src/molecules/MEmoteTile.js b/src/views/molecules/MEmoteTile.js
similarity index 77%
rename from src/molecules/MEmoteTile.js
rename to src/views/molecules/MEmoteTile.js
index 19e57c5f2f..b0f62e7b0b 100644
--- a/src/molecules/MEmoteTile.js
+++ b/src/views/molecules/MEmoteTile.js
@@ -1,6 +1,10 @@
var React = require('react');
+var MEmoteTileController = require("../../controllers/molecules/MEmoteTile");
+
module.exports = React.createClass({
+ mixins: [MEmoteTileController],
+
render: function() {
var mxEvent = this.props.mxEvent;
var content = mxEvent.getContent();
diff --git a/src/molecules/MTextTile.js b/src/views/molecules/MTextTile.js
similarity index 71%
rename from src/molecules/MTextTile.js
rename to src/views/molecules/MTextTile.js
index b4ff3f3c70..0d877c5a27 100644
--- a/src/molecules/MTextTile.js
+++ b/src/views/molecules/MTextTile.js
@@ -1,6 +1,10 @@
var React = require('react');
+var MTextTileController = require("../../controllers/molecules/MTextTile");
+
module.exports = React.createClass({
+ mixins: [MTextTileController],
+
render: function() {
var content = this.props.mxEvent.getContent();
return (
diff --git a/src/molecules/MatrixToolbar.js b/src/views/molecules/MatrixToolbar.js
similarity index 61%
rename from src/molecules/MatrixToolbar.js
rename to src/views/molecules/MatrixToolbar.js
index f4b5ba1a61..aebc6d8fab 100644
--- a/src/molecules/MatrixToolbar.js
+++ b/src/views/molecules/MatrixToolbar.js
@@ -1,10 +1,14 @@
var React = require('react');
-var ComponentBroker = require('../ComponentBroker');
+var ComponentBroker = require('../../ComponentBroker');
var LogoutButton = ComponentBroker.get("atoms/LogoutButton");
+var MatrixToolbarController = require("../../controllers/molecules/MatrixToolbar");
+
module.exports = React.createClass({
+ mixins: [MatrixToolbarController],
+
render: function() {
return (
diff --git a/src/views/molecules/MessageComposer.js b/src/views/molecules/MessageComposer.js
new file mode 100644
index 0000000000..c891aa890e
--- /dev/null
+++ b/src/views/molecules/MessageComposer.js
@@ -0,0 +1,16 @@
+var React = require('react');
+
+var MessageComposerController = require("../../controllers/molecules/MessageComposer");
+
+module.exports = React.createClass({
+ mixins: [MessageComposerController],
+
+ render: function() {
+ return (
+
+
+
+ );
+ },
+});
+
diff --git a/src/molecules/MessageTile.js b/src/views/molecules/MessageTile.js
similarity index 87%
rename from src/molecules/MessageTile.js
rename to src/views/molecules/MessageTile.js
index a4e8f7422d..ad1934f298 100644
--- a/src/molecules/MessageTile.js
+++ b/src/views/molecules/MessageTile.js
@@ -2,7 +2,7 @@ var React = require('react');
var classNames = require("classnames");
-var ComponentBroker = require('../ComponentBroker');
+var ComponentBroker = require('../../ComponentBroker');
var MessageTimestamp = ComponentBroker.get('atoms/MessageTimestamp');
var SenderProfile = ComponentBroker.get('molecules/SenderProfile');
@@ -14,7 +14,11 @@ var tileTypes = {
'm.emote': ComponentBroker.get('molecules/MEmoteTile')
};
+var MessageTileController = require("../../controllers/molecules/MessageTile");
+
module.exports = React.createClass({
+ mixins: [MessageTileController],
+
render: function() {
var content = this.props.mxEvent.getContent();
var msgtype = content.msgtype;
diff --git a/src/molecules/ProgressBar.js b/src/views/molecules/ProgressBar.js
similarity index 82%
rename from src/molecules/ProgressBar.js
rename to src/views/molecules/ProgressBar.js
index 030a0401cc..5522bdd76d 100644
--- a/src/molecules/ProgressBar.js
+++ b/src/views/molecules/ProgressBar.js
@@ -1,10 +1,9 @@
var React = require('react');
+var ProgressBarController = require("./../molecules/ProgressBar");
+
module.exports = React.createClass({
- propTypes: {
- value: React.PropTypes.number,
- max: React.PropTypes.number
- },
+ mixins: [ProgressBarController],
render: function() {
// Would use an HTML5 progress tag but if that doesn't animate if you
diff --git a/src/molecules/RoomHeader.js b/src/views/molecules/RoomHeader.js
similarity index 66%
rename from src/molecules/RoomHeader.js
rename to src/views/molecules/RoomHeader.js
index 4d7850b234..11d97950eb 100644
--- a/src/molecules/RoomHeader.js
+++ b/src/views/molecules/RoomHeader.js
@@ -1,6 +1,10 @@
var React = require('react');
+var RoomHeaderController = require("../../controllers/molecules/RoomHeader");
+
module.exports = React.createClass({
+ mixins: [RoomHeaderController],
+
render: function() {
return (
diff --git a/src/molecules/RoomTile.js b/src/views/molecules/RoomTile.js
similarity index 73%
rename from src/molecules/RoomTile.js
rename to src/views/molecules/RoomTile.js
index 54e59147f0..ef2579e5ab 100644
--- a/src/molecules/RoomTile.js
+++ b/src/views/molecules/RoomTile.js
@@ -1,16 +1,10 @@
var React = require('react');
var classNames = require('classnames');
-var dis = require("../dispatcher");
+var RoomTileController = require("../../controllers/molecules/RoomTile");
module.exports = React.createClass({
- onClick: function() {
- dis.dispatch({
- action: 'view_room',
- room_id: this.props.room.roomId
- });
- },
-
+ mixins: [RoomTileController],
render: function() {
var classes = classNames({
'mx_RoomTile': true,
diff --git a/src/molecules/SenderProfile.js b/src/views/molecules/SenderProfile.js
similarity index 81%
rename from src/molecules/SenderProfile.js
rename to src/views/molecules/SenderProfile.js
index d7cd1f3829..f5d4c60538 100644
--- a/src/molecules/SenderProfile.js
+++ b/src/views/molecules/SenderProfile.js
@@ -1,6 +1,10 @@
var React = require('react');
+var SenderProfileController = require("../../controllers/molecules/SenderProfile");
+
module.exports = React.createClass({
+ mixins: [SenderProfileController],
+
render: function() {
var mxEvent = this.props.mxEvent;
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
diff --git a/src/views/molecules/ServerConfig.js b/src/views/molecules/ServerConfig.js
new file mode 100644
index 0000000000..791c9c9755
--- /dev/null
+++ b/src/views/molecules/ServerConfig.js
@@ -0,0 +1,24 @@
+var React = require('react');
+
+var ServerConfigController = require("../../controllers/molecules/ServerConfig");
+
+module.exports = React.createClass({
+ mixins: [ServerConfigController],
+
+ render: function() {
+ return (
+
+ );
+ }
+});
diff --git a/src/molecules/UnknownMessageTile.js b/src/views/molecules/UnknownMessageTile.js
similarity index 61%
rename from src/molecules/UnknownMessageTile.js
rename to src/views/molecules/UnknownMessageTile.js
index df217fb2f9..3df272d18f 100644
--- a/src/molecules/UnknownMessageTile.js
+++ b/src/views/molecules/UnknownMessageTile.js
@@ -1,6 +1,10 @@
var React = require('react');
+var UnknownMessageTileController = require("../../controllers/molecules/UnknownMessageTile");
+
module.exports = React.createClass({
+ mixins: [UnknownMessageTileController],
+
render: function() {
return (
diff --git a/src/views/organisms/RoomList.js b/src/views/organisms/RoomList.js
new file mode 100644
index 0000000000..6e994cdfac
--- /dev/null
+++ b/src/views/organisms/RoomList.js
@@ -0,0 +1,19 @@
+var React = require('react');
+
+var RoomListController = require("../../controllers/organisms/RoomList");
+
+
+module.exports = React.createClass({
+ mixins: [RoomListController],
+
+ render: function() {
+ return (
+
+
+ {this.makeRoomTiles()}
+
+
+ );
+ }
+});
+
diff --git a/src/views/organisms/RoomView.js b/src/views/organisms/RoomView.js
new file mode 100644
index 0000000000..db06e1b576
--- /dev/null
+++ b/src/views/organisms/RoomView.js
@@ -0,0 +1,35 @@
+var React = require('react');
+
+var ComponentBroker = require('../../ComponentBroker');
+
+var MessageTile = ComponentBroker.get('molecules/MessageTile');
+var RoomHeader = ComponentBroker.get('molecules/RoomHeader');
+var MessageComposer = ComponentBroker.get('molecules/MessageComposer');
+
+var RoomViewController = require("../../controllers/organisms/RoomView");
+
+
+module.exports = React.createClass({
+ mixins: [RoomViewController],
+
+ getMessageTiles: function() {
+ return this.state.room.timeline.map(function(mxEv) {
+ return (
+
+ );
+ });
+ },
+
+ render: function() {
+ return (
+
+
+
+ {this.getMessageTiles()}
+
+
+
+ );
+ },
+});
+
diff --git a/src/views/pages/MatrixChat.js b/src/views/pages/MatrixChat.js
new file mode 100644
index 0000000000..1dccc5c88f
--- /dev/null
+++ b/src/views/pages/MatrixChat.js
@@ -0,0 +1,40 @@
+var React = require('react');
+var ComponentBroker = require('../../ComponentBroker');
+
+var RoomList = ComponentBroker.get('organisms/RoomList');
+var RoomView = ComponentBroker.get('organisms/RoomView');
+var MatrixToolbar = ComponentBroker.get('molecules/MatrixToolbar');
+var Login = ComponentBroker.get('templates/Login');
+
+var MatrixChatController = require("../../controllers/pages/MatrixChat");
+
+// should be atomised
+var Loader = require("react-loader");
+
+
+module.exports = React.createClass({
+ mixins: [MatrixChatController],
+
+ render: function() {
+ if (this.state.logged_in && this.state.ready) {
+ return (
+
+ );
+ } else if (this.state.logged_in) {
+ return (
+
+ );
+ } else {
+ return (
+
+ );
+ }
+ }
+});
+
diff --git a/src/views/templates/Login.js b/src/views/templates/Login.js
new file mode 100644
index 0000000000..cec74eff3f
--- /dev/null
+++ b/src/views/templates/Login.js
@@ -0,0 +1,37 @@
+var React = require('react');
+
+var ComponentBroker = require("../../ComponentBroker");
+
+var ProgressBar = ComponentBroker.get("molecules/ProgressBar");
+var Loader = require("react-loader");
+
+var LoginController = require("../../controllers/templates/Login");
+
+module.exports = React.createClass({
+ mixins: [LoginController],
+
+ loginContent: function() {
+ if (this.state.busy) {
+ return (
+
+ );
+ } else {
+ return (
+
+
Please log in:
+ {this.componentForStep(this.state.step)}
+
{this.state.errorText}
+
+ );
+ }
+ },
+
+ render: function() {
+ return (
+
+
+ {this.loginContent()}
+
+ );
+ }
+});