Skip to content

Commit

Permalink
Big batch of updates
Browse files Browse the repository at this point in the history
  • Loading branch information
harborhoffer committed Aug 30, 2017
1 parent 325e468 commit 8877fca
Show file tree
Hide file tree
Showing 9 changed files with 375 additions and 40 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"fs-extra": "3.0.1",
"html-webpack-plugin": "2.29.0",
"jest": "20.0.4",
"localforage": "^1.5.0",
"lodash": "^4.17.4",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
Expand All @@ -40,6 +41,7 @@
"react-error-overlay": "^1.0.10",
"react-grid-layout": "^0.15.0",
"react-select": "^1.0.0-rc.5",
"react-toastify": "^2.0.0-rc.3",
"style-loader": "0.18.2",
"sw-precache-webpack-plugin": "0.11.4",
"url-loader": "0.5.9",
Expand Down
213 changes: 183 additions & 30 deletions src/Main.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import React, { Component } from 'react';
import cookie from 'react-cookies';
import PropTypes from 'prop-types';
import {API_URL, ACCESS_TOKEN_COOKIE} from './constants';
import {Button} from 'react-bootstrap';
import localforage from 'localforage';
import {Button, Glyphicon} from 'react-bootstrap';
import {reject} from 'lodash';
import { ToastContainer, toast } from 'react-toastify';
import {
API_URL,
ACCESS_TOKEN_COOKIE,
APP_NAME
} from './constants';

import SpaceGrid from './SpaceGrid';
import AddSpaceModal from './AddSpaceModal';
import SaveLayoutModal from './SaveLayoutModal';
import NavigationBar from './NavigationBar';

class Main extends Component {
Expand All @@ -15,50 +22,83 @@ class Main extends Component {

this.state = {
spaces: [],
layouts: [],
profile: null,
layouts: {},
loadingSpaces: true,
selectedSpaces: [],
showAddSpacesModal: false
selectedLayout: '',
showAddSpacesModal: false,
showSaveLayoutModal: false
}

this.onAddSpaces = this.onAddSpaces.bind(this);
this.setProfile = this.setProfile.bind(this);
this.initializeProfile = this.initializeProfile.bind(this);
this.setLayout = this.setLayout.bind(this);
this.getProfileKey = this.getProfileKey.bind(this);
this.deleteLayout = this.deleteLayout.bind(this);
}

componentDidMount() {
this.loadSpaces();
localforage.config({
name: 'spark-space-grid'
});
this.loadData();
}

loadSpaces() {
loadData() {
const {accessToken} = this.props;
const request = new Request(`${API_URL}/rooms?sortBy=id&max=1000`, {

const fetchOk = (...args) => fetch(...args)
.then(res => res.ok ? res : res.json().then(data => {
throw Object.assign(new Error(data.error_message), {name: res.statusText});
}));

Promise.all([
`${API_URL}/rooms?sortBy=id&max=1000`,
`${API_URL}/people/me`
].map(url => fetchOk(url, {
method: 'GET',
mode: 'cors',
redirect: 'follow',
headers: new Headers({
'Authorization': `Bearer ${accessToken}`
})
});

fetch(request)
.then((res) => {
if (res.status >= 200 && res.status < 300) {
return Promise.resolve(res);
} else {
return Promise.reject(res);
}
})
.then((res) => {
return res.json().catch((err) => Promise.reject(err));
})
.then((spaces) => {
.then(r => r.json()))).then(([spaces, profile]) => {
this.setState({
loadingSpaces: false,
spaces: spaces.items
spaces: spaces.items,
profile: profile
});
})
.catch((err) => {
console.log('Error fetching rooms', err);
})

this.setProfile();
}).catch(e => toast.error('Error loading spark spaces'));

}

setProfile() {
const profileKey = this.getProfileKey();

localforage.getItem(profileKey).then((value) => {
if (!value) {
return this.initializeProfile();
}

this.setState({
layouts: value
});
}).catch((err) => {
toast.error('Error loading layouts');
});
}

initializeProfile() {
const profileKey = this.getProfileKey();
const profile = {};

localforage.setItem(profileKey, profile).catch((err) => {
toast.error('Error setting profile');
});
}

addSpaces(e) {
Expand All @@ -80,7 +120,7 @@ class Main extends Component {
w: 3,
h: 2,
minW: 3,
minH: 3
minH: 2
}
});

Expand All @@ -95,6 +135,79 @@ class Main extends Component {
});
}

onSaveLayout(name) {
this.setLayout(name);
}

onSaveLayoutClick() {
this.setState({
showSaveLayoutModal: true
});
}

onDeleteLayoutClick() {
this.deleteLayout();
}

onSetLayout(layout) {
this.setState({
selectedLayout: layout,
selectedSpaces: layout.length > 0 ? this.state.layouts[layout] : []
});
}

setLayout(layoutName) {
const profileKey = this.getProfileKey();
const layout = layoutName || this.state.selectedLayout;

let profile = this.state.layouts;
profile[layout] = this.state.selectedSpaces;

localforage.setItem(profileKey, profile).then(() => {
this.setState({
layouts: profile,
selectedLayout: layout
});

if (layoutName) {
toast.success('New layout created!');
}
}).catch(function (err) {
toast.error('Could not save layout');
});
}

deleteLayout() {
const profileKey = this.getProfileKey();
const layout = this.state.selectedLayout;

let profile = this.state.layouts;
delete profile[layout];

localforage.setItem(profileKey, profile).then(() => {
this.setState({
layouts: profile,
selectedSpaces: [],
selectedLayout: ''
});

toast.success('Layout removed');
}).catch(function (err) {
toast.error('Could not remove layout');
});
}

onLayoutChange(layout) {
this.setState({
selectedSpaces: layout,
}, () => {
// A layout is open
if (this.state.selectedLayout.length > 0) {
this.setLayout();
}
});
}

onLogoutClick() {
cookie.remove(ACCESS_TOKEN_COOKIE, { path: '/' });
window.location.reload();
Expand All @@ -106,22 +219,51 @@ class Main extends Component {
});
}

hideAddLayoutModal() {
this.setState({
showSaveLayoutModal: false
});
}

getProfileKey() {
return `profile-${this.state.profile.id}`;
}

render() {
const {
spaces,
layouts,
loadingSpaces,
selectedSpaces,
showAddSpacesModal
selectedSpaces,
selectedLayout,
showAddSpacesModal,
showSaveLayoutModal
} = this.state;

return (
<div>
<ToastContainer
position="top-right"
type="default"
autoClose={2500}
hideProgressBar={false}
newestOnTop={false}
toastClassName="app-toast"
closeOnClick
pauseOnHover
/>

{
!loadingSpaces &&
<NavigationBar
onLogoutClick={this.onLogoutClick.bind(this)}
onAddSpacesClick={this.addSpaces.bind(this)}
onSaveLayoutClick={this.onSaveLayoutClick.bind(this)}
onDeleteLayoutClick={this.onDeleteLayoutClick.bind(this)}
onSetLayout={this.onSetLayout.bind(this)}
selectedSpaces={selectedSpaces}
selectedLayout={selectedLayout}
layouts={layouts}
/>
}

Expand All @@ -135,7 +277,10 @@ class Main extends Component {
{
!loadingSpaces && selectedSpaces.length === 0 &&
<div className="text-center" style={{marginTop:'100px'}}>
<Button bsStyle="primary" bsSize="large" onClick={this.addSpaces.bind(this)}>No Spaces. Add some</Button>
<h4>Your grid is empty</h4>
<Button bsStyle="primary" bsSize="large" onClick={this.addSpaces.bind(this)}>
<Glyphicon glyph="plus-sign" /> Add some spaces
</Button>
</div>
}

Expand All @@ -146,6 +291,7 @@ class Main extends Component {
{...this.props}
selectedSpaces={selectedSpaces}
onRemoveSpace={this.onRemoveSpace.bind(this)}
onLayoutChange={this.onLayoutChange.bind(this)}
/>
</div>
}
Expand All @@ -157,6 +303,13 @@ class Main extends Component {
activeSpaces={selectedSpaces}
onAddSpaces={this.onAddSpaces}
/>

<SaveLayoutModal
show={showSaveLayoutModal}
hide={this.hideAddLayoutModal.bind(this)}
layouts={this.state.layouts}
onSaveLayout={this.onSaveLayout.bind(this)}
/>
</div>
);
}
Expand Down
3 changes: 3 additions & 0 deletions src/NavigationBar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.navbar-form .form-group {
margin: 0 10px;
}
Loading

0 comments on commit 8877fca

Please sign in to comment.