diff --git a/skins/base/views/molecules/ChangeAvatar.js b/skins/base/views/molecules/ChangeAvatar.js
new file mode 100644
index 00000000..021b4ad6
--- /dev/null
+++ b/skins/base/views/molecules/ChangeAvatar.js
@@ -0,0 +1,47 @@
+/*
+Copyright 2015 OpenMarket Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+'use strict';
+
+var React = require('react');
+
+var ChangeAvatarController = require("../../../../src/controllers/molecules/ChangeAvatar");
+
+
+module.exports = React.createClass({
+ displayName: 'ChangeAvatar',
+ mixins: [ChangeAvatarController],
+
+ render: function() {
+ switch (this.state.phase) {
+ case this.Phases.Display:
+ case this.Phases.Error:
+ return (
+
+
+
+
+
+
+
+ );
+ case this.Phases.Uploading:
+ return (
+
+ );
+ }
+ }
+});
diff --git a/skins/base/views/molecules/ChangePassword.js b/skins/base/views/molecules/ChangePassword.js
new file mode 100644
index 00000000..ff64a721
--- /dev/null
+++ b/skins/base/views/molecules/ChangePassword.js
@@ -0,0 +1,49 @@
+/*
+Copyright 2015 OpenMarket Ltd
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+'use strict';
+
+var React = require('react');
+
+var ChangePasswordController = require("../../../../src/controllers/molecules/ChangePassword");
+
+
+module.exports = React.createClass({
+ displayName: 'ChangePassword',
+ mixins: [ChangePasswordController],
+
+ render: function() {
+ switch (this.state.phase) {
+ case this.Phases.Edit:
+ case this.Phases.Error:
+ return (
+
+
+
+
+
+
+
+
+
+ );
+ case this.Phases.Uploading:
+ return (
+
+ );
+ }
+ }
+});
diff --git a/skins/base/views/organisms/UserSettings.js b/skins/base/views/organisms/UserSettings.js
new file mode 100644
index 00000000..e70a575a
--- /dev/null
+++ b/skins/base/views/organisms/UserSettings.js
@@ -0,0 +1,97 @@
+/*
+Copyright 2015 OpenMarket Ltd
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+'use strict';
+
+var React = require('react');
+var ComponentBroker = require('../../../../src/ComponentBroker');
+var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+
+var UserSettingsController = require("../../../../src/controllers/organisms/UserSettings");
+
+var EditableText = ComponentBroker.get('atoms/EditableText');
+var ChangeAvatar = ComponentBroker.get('molecules/ChangeAvatar');
+var ChangePassword = ComponentBroker.get('molecules/ChangePassword');
+var Loader = require("react-loader");
+
+var Modal = require("../../../../src/Modal")
+
+module.exports = React.createClass({
+ displayName: 'UserSettings',
+ mixins: [UserSettingsController],
+
+ editAvatar: function() {
+ var url = MatrixClientPeg.get().mxcUrlToHttp(this.state.avatarUrl);
+ Modal.createDialog(ChangeAvatar, {initialAvatarUrl: url});
+ },
+
+ addEmail: function() {
+
+ },
+
+ editDisplayName: function() {
+ this.refs.displayname.edit();
+ },
+
+ changePassword: function() {
+ Modal.createDialog(ChangePassword);
+ },
+
+ render: function() {
+ switch (this.state.phase) {
+ case this.Phases.Loading:
+ return
+ case this.Phases.Display:
+ return (
+