Skip to content

Commit

Permalink
added overview for availabilities #33
Browse files Browse the repository at this point in the history
  • Loading branch information
maxbeier committed May 10, 2017
1 parent 4fd0831 commit 56ffb8b
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 1 deletion.
80 changes: 80 additions & 0 deletions client/components/Availabilities.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from 'react';
import _ from 'lodash';
import Timeline from 'react-calendar-timeline';
import moment from 'moment';
import { Spinner } from 'elemental';
import * as http from '../lib/http';
import groupsJSON from '../../shared/groups.json';

export default React.createClass({

propTypes: {
start: React.PropTypes.number,
end: React.PropTypes.number,
},

getDefaultProps() {
return {
start: Date.now(),
end: Date.now(),
};
},

getInitialState() {
return {
items: [],
groups: [],
volunteers: null,
};
},

componentDidMount() {
http.get('/api/volunteers')
.then(({ volunteers }) => this.setState({ volunteers }, this.generateItems));
},

generateItems() {
const groups = groupsJSON.map(name => ({ id: name, title: _.startCase(name) }));
const items = [];
const now = new Date();
const start = new Date(this.props.start);
const end = new Date(this.props.end);

_.each(this.state.volunteers, volunteer => _.each(volunteer.availabilities, (av) => {
const className = new Date(av.from) <= start && new Date(av.till) >= end
? new Date(av.confirmationTill) >= now ? 'available' : 'expired'
: 'unavailable';

items.push({
start_time: moment(av.from),
end_time: moment(av.till),
id: av._id,
group: volunteer.group,
title: 'Name' || `${volunteer.name.first || ''} ${volunteer.name.last || ''}`.trim(),
className,
});
}));

this.setState({ items, groups });
},

render() {
if (this.state.volunteers === null) {
return <div style={{ marginTop: 100, textAlign: 'center' }}><Spinner size="lg" /></div>;
}

return (
<Timeline
groups={this.state.groups}
items={this.state.items}
defaultTimeStart={moment(this.props.start).add(-1, 'day')}
defaultTimeEnd={moment(this.props.end).add(1, 'day')}
canMove={false}
canChangeGroup={false}
canResize={false}
stackItems
/>
);
},

});
4 changes: 4 additions & 0 deletions client/components/MissionForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ export default React.createClass({
<Alert type={this.state.message.type}>{this.state.message.text}</Alert>
}

<div style={{ textAlign: 'right' }}>
<a href={`/availabilities?start=${+new Date(mission.start)}&end=${+new Date(mission.end)}`} target="_blank">Availabilities</a>
</div>

<Form onChange={this.onChange} onSubmit={this.onSubmit}>

<FormField label="Name">
Expand Down
10 changes: 10 additions & 0 deletions client/pages/availabilities.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import queryString from 'query-string';
import Availabilities from '../components/Availabilities';

const parsed = queryString.parse(window.location.search);
const start = +parsed.start || Date.now();
const end = +parsed.end || Date.now();

ReactDOM.render(<Availabilities start={start} end={end} />, document.getElementById('app'));
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"babel-preset-es2015": "^6.24.0",
"babel-preset-react": "^6.23.0",
"babelify": "^7.3.0",
"browserify-css": "^0.10.1",
"browserify-middleware": "^7.0.0",
"cookie-parser": "^1.4.3",
"dotenv": "^4.0.0",
Expand All @@ -36,7 +37,9 @@
"model-transform": "^2.0.0",
"moment": "^2.18.1",
"nodemailer": "^3.1.8",
"query-string": "^4.3.4",
"react": "^15.4.2",
"react-calendar-timeline": "^0.11.1",
"react-datepicker": "^0.43.0",
"react-dom": "^15.4.2",
"react-leaflet": "^1.1.4",
Expand Down
31 changes: 31 additions & 0 deletions public/styles/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,34 @@ footer {
height: 400px;
width: 100%;
}


// Timeline

body .react-calendar-timeline {
.rct-sidebar .rct-sidebar-header {
background: transparent url(/images/logo.svg) center no-repeat;
background-size: 80%;
}

.rct-header .rct-label-group,
.rct-header .rct-label.rct-label-only { // gray
background-color: #e0e0e0;
color: #333;
}

.rct-items .rct-item.available { // green
background-color: #388e3c;
}

.rct-items .rct-item.expired { // orange
background-color: #fb8c00;
}

.rct-items .rct-item.unavailable { // gray
background-color: #eee;
border-color: #757575;
color: #757575;
}
}

8 changes: 7 additions & 1 deletion routes/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const babelify = require('babelify');
const browserifycss = require('browserify-css');
const browserify = require('browserify-middleware');
const express = require('express');
const path = require('path');
Expand All @@ -19,6 +20,7 @@ exports = module.exports = (app) => {
app.get('/', (req, res) => res.render('react', { page: 'signup' }));
app.get('/missions', (req, res) => res.render('react', { page: 'missions' }));
app.get('/volunteer', (req, res) => res.render('react', { page: 'volunteer' }));
app.get('/availabilities', (req, res) => res.render('react', { page: 'availabilities' }));

app.get('/volunteer/:token', api.volunteers.setToken);

Expand All @@ -42,8 +44,12 @@ exports = module.exports = (app) => {

// Serve script bundles
app.use('/js', browserify('./client/pages', {
debug: true,
external: commonPackages,
transform: [babelify.configure({ presets: ['es2015', 'react', 'stage-3'] })],
transform: [
[browserifycss, { global: true }],
[babelify.configure({ presets: ['es2015', 'react', 'stage-3'] })],
],
}));

app.disable('x-powered-by');
Expand Down

0 comments on commit 56ffb8b

Please sign in to comment.