diff --git a/ui/src/component/Header.js b/ui/src/component/Header.js
new file mode 100644
index 0000000..c20ae2d
--- /dev/null
+++ b/ui/src/component/Header.js
@@ -0,0 +1,93 @@
+import React, {Component} from 'react';
+import AppBar from 'material-ui/AppBar';
+import Button from 'material-ui/Button';
+import Toolbar from 'material-ui/Toolbar';
+import Typography from 'material-ui/Typography';
+import {withStyles} from 'material-ui/styles';
+import PropTypes from 'prop-types';
+import IconButton from 'material-ui/IconButton';
+import * as UserAction from '../actions/UserAction';
+import {Link} from 'react-router-dom';
+import Chat from 'material-ui-icons/Chat';
+import SupervisorAccount from 'material-ui-icons/SupervisorAccount';
+import DevicesOther from 'material-ui-icons/DevicesOther';
+import ExitToApp from 'material-ui-icons/ExitToApp';
+import AccountCircle from 'material-ui-icons/AccountCircle';
+import LightbulbOutline from 'material-ui-icons/LightbulbOutline';
+
+const styles = (theme) => ({
+ appBar: {
+ zIndex: theme.zIndex.drawer + 1,
+ },
+ title: {
+ flex: 1,
+ display: 'flex',
+ alignItems: 'center',
+ },
+ titleName: {
+ paddingRight: 10,
+ },
+ link: {
+ color: 'inherit',
+ textDecoration: 'none',
+ },
+});
+
+class Header extends Component {
+ static propTypes = {
+ classes: PropTypes.object.isRequired,
+ loggedIn: PropTypes.bool.isRequired,
+ name: PropTypes.string.isRequired,
+ admin: PropTypes.bool.isRequired,
+ version: PropTypes.string.isRequired,
+ toggleTheme: PropTypes.func.isRequired,
+ showSettings: PropTypes.func.isRequired,
+ };
+
+ renderButtons(name, admin) {
+ const {classes, showSettings} = this.props;
+ return (
+
+ {admin
+ ?
+
+ : ''}
+
+
+
+
+
+
+
+
+ );
+ }
+
+ render() {
+ const {classes, version, name, loggedIn, admin, toggleTheme} = this.props;
+
+ return (
+
+
+
+ {loggedIn && this.renderButtons(name, admin)}
+
+
+
+ );
+ }
+}
+
+export default withStyles(styles, {withTheme: true})(Header);
diff --git a/ui/src/component/Navigation.js b/ui/src/component/Navigation.js
new file mode 100644
index 0000000..6344909
--- /dev/null
+++ b/ui/src/component/Navigation.js
@@ -0,0 +1,87 @@
+import React, {Component} from 'react';
+import Divider from 'material-ui/Divider';
+import Drawer from 'material-ui/Drawer';
+import {ListItem, ListItemText} from 'material-ui/List';
+import {withStyles} from 'material-ui/styles';
+import PropTypes from 'prop-types';
+import AppStore from '../stores/AppStore';
+import {Link} from 'react-router-dom';
+
+const styles = (theme) => ({
+ drawerPaper: {
+ position: 'relative',
+ width: 250,
+ minHeight: '100%',
+ },
+ toolbar: theme.mixins.toolbar,
+ link: {
+ color: 'inherit',
+ textDecoration: 'none',
+ },
+});
+
+class Navigation extends Component {
+ static propTypes = {
+ classes: PropTypes.object.isRequired,
+ loggedIn: PropTypes.bool.isRequired,
+ };
+
+ constructor() {
+ super();
+ this.state = {apps: []};
+ }
+
+ componentWillMount() {
+ AppStore.on('change', this.updateApps);
+ }
+
+ componentWillUnmount() {
+ AppStore.removeListener('change', this.updateApps);
+ }
+
+ updateApps = () => this.setState({apps: AppStore.get()});
+
+ render() {
+ const {classes, loggedIn} = this.props;
+ const {apps} = this.state;
+
+ const empty = (
+
+ );
+
+ const userApps = apps.length === 0 ? empty : apps.map(function(app) {
+ return (
+
+
+
+
+
+ );
+ });
+
+ const placeholderItems = [
+
+
+ ,
+
+
+ ,
+ ];
+
+ return (
+
+
+
+
+
+
+
+
+
{loggedIn ? userApps : placeholderItems}
+
+
+ );
+ }
+}
+
+export default withStyles(styles, {withTheme: true})(Navigation);