1
0
Fork 0

Make adding events work

master
Ambrose Chua 2017-04-14 21:18:50 +08:00
parent f63fd6c155
commit 82ffd339bc
7 changed files with 80 additions and 23 deletions

View File

@ -3,34 +3,69 @@ import React from 'react';
import { Dialog, Input, Dropdown, DatePicker, TimePicker } from 'react-toolbox'; import { Dialog, Input, Dropdown, DatePicker, TimePicker } from 'react-toolbox';
export default class AddEventDialog extends React.Component { export default class AddEventDialog extends React.Component {
constructor(props) { constructor(props, context) {
super(props); super(props, context);
const now = new Date(); const now = new Date();
this.state = { this.state = {
group: null, group: null,
name: '', name: '',
start: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 8), start: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 8),
end: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 10), end: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 10),
groups: [ groups: [],
{ value: 1, label: 'M17502' },
{ value: 2, label: 'Infocomm Club' },
{ value: 3, label: 'Youth Flying Club', disabled: true },
{ value: 4, label: 'Engineering Intrest Group' },
],
}; };
this.handleGroupChange = this.handleGroupChange.bind(this); this.handleGroupChange = this.handleGroupChange.bind(this);
this.handleNameChange = this.handleNameChange.bind(this); this.handleNameChange = this.handleNameChange.bind(this);
this.handleStartChange = this.handleStartChange.bind(this); this.handleStartChange = this.handleStartChange.bind(this);
this.handleEndChange = this.handleEndChange.bind(this); this.handleEndChange = this.handleEndChange.bind(this);
this.addEvent = this.addEvent.bind(this);
this.actions = [ this.actions = [
{ label: 'Cancel', onClick: this.props.onCancel, accent: true }, { label: 'Cancel', onClick: this.props.onCancel, accent: true },
{ label: 'Add', onClick: this.addEvent, accent: true }, { label: 'Add', onClick: this.addEvent, accent: true },
]; ];
// pull user groups, together with the relationship attribute role this.fetchGroups(context);
// put user groups into state.groups, disabling those not admin }
fetchGroups(context = this.context) {
return fetch(`/api/v1/schools/${context.user.school}/users/${context.user.id}/groups/`, {
headers: {
FakeAuth: true,
FakeID: context.user.id,
},
})
.then(data => data.json())
.then((data) => {
this.setState({
groups: data.map(g => ({ value: g.id, label: g.name })),
});
})
.catch((err) => {
console.error(err);
});
}
addEvent() {
const method = 'POST';
const headers = new Headers();
headers.append('FakeAuth', 'true');
headers.append('FakeID', this.context.user.id);
headers.append('Content-Type', 'application/json');
const body = JSON.stringify({
name: this.state.name,
start: this.state.start,
end: this.state.end,
});
fetch(`/api/v1/schools/${this.context.user.school}/groups/${this.state.group}/eventsOnce/`, {
method, headers, body,
})
.then(() => {
this.props.onDone();
})
.catch((err) => {
console.error(err);
});
} }
handleGroupChange(value) { handleGroupChange(value) {
@ -124,6 +159,7 @@ export default class AddEventDialog extends React.Component {
AddEventDialog.propTypes = { AddEventDialog.propTypes = {
onCancel: React.PropTypes.func.isRequired, onCancel: React.PropTypes.func.isRequired,
onDone: React.PropTypes.func.isRequired,
}; };
AddEventDialog.contextTypes = { AddEventDialog.contextTypes = {

View File

@ -4,7 +4,7 @@ import { Dialog, Input, Autocomplete, Dropdown } from 'react-toolbox';
export default class AddGroupDialog extends React.Component { export default class AddGroupDialog extends React.Component {
constructor(props, context) { constructor(props, context) {
super(props); super(props, context);
this.state = { this.state = {
name: '', name: '',
members: [], members: [],
@ -38,7 +38,7 @@ export default class AddGroupDialog extends React.Component {
const headers = new Headers(); const headers = new Headers();
headers.append('FakeAuth', 'true'); headers.append('FakeAuth', 'true');
headers.append('FakeID', context.user.id); headers.append('FakeID', context.user.id);
fetch(`/api/v1/schools/${context.user.school}/users`, { fetch(`/api/v1/schools/${context.user.school}/users/`, {
headers, headers,
}) })
.then(data => data.json()) .then(data => data.json())
@ -69,7 +69,7 @@ export default class AddGroupDialog extends React.Component {
mentor_level: this.state.mentor_level, mentor_level: this.state.mentor_level,
mentor_year: this.state.mentor_year, mentor_year: this.state.mentor_year,
}); });
fetch(`/api/v1/schools/${this.context.user.school}/groups`, { fetch(`/api/v1/schools/${this.context.user.school}/groups/`, {
method, headers, body, method, headers, body,
}) })
.then(() => { .then(() => {

View File

@ -4,14 +4,14 @@ import { List, ListSubHeader, ListItem } from 'react-toolbox';
export default class PageGroup extends React.Component { export default class PageGroup extends React.Component {
constructor(props, context) { constructor(props, context) {
super(props); super(props, context);
this.state = { this.state = {
id: parseInt(props.match.params.id, 10), id: parseInt(props.match.params.id, 10),
group: {}, group: {},
addGroupDialogActive: false, addGroupDialogActive: false,
}; };
this.fetchGroup(context); this.fetchGroup(context); // TODO: split into three backend calls
} }
async fetchGroup(context = this.context) { async fetchGroup(context = this.context) {
@ -41,9 +41,9 @@ export default class PageGroup extends React.Component {
ripple ripple
> >
<ListSubHeader <ListSubHeader
caption="Events" caption="One-time Events"
/> />
{this.state.group.events && this.state.group.events.map(e => ( {this.state.group.eventsOnce && this.state.group.eventsOnce.map(e => (
<ListItem <ListItem
key={e.id} key={e.id}
caption={e.name} caption={e.name}

View File

@ -6,10 +6,9 @@ import AddGroupDialog from '../components/addgroupdialog';
export default class PageGroups extends React.Component { export default class PageGroups extends React.Component {
constructor(props, context) { constructor(props, context) {
super(props); super(props, context);
this.state = { this.state = {
groups: [ groups: [],
],
addGroupDialogActive: false, addGroupDialogActive: false,
}; };
@ -21,7 +20,7 @@ export default class PageGroups extends React.Component {
} }
async fetchGroups(context = this.context) { async fetchGroups(context = this.context) {
return fetch(`/api/v1/schools/${context.user.school}/users/${context.user.id}/groups`, { return fetch(`/api/v1/schools/${context.user.school}/users/${context.user.id}/groups/`, {
headers: { headers: {
FakeAuth: true, FakeAuth: true,
FakeID: context.user.id, FakeID: context.user.id,

View File

@ -21,6 +21,11 @@ export default class PageHome extends React.Component {
this.hideAddEventDialog = this.hideAddEventDialog.bind(this); this.hideAddEventDialog = this.hideAddEventDialog.bind(this);
} }
// eslint-disable-next-line class-methods-use-this
fetchEvents() {
// Do nothing
}
showAddEventDialog() { showAddEventDialog() {
this.setState({ this.setState({
addEventDialogActive: true, addEventDialogActive: true,
@ -51,6 +56,7 @@ export default class PageHome extends React.Component {
<AddEventDialog <AddEventDialog
active={this.state.addEventDialogActive} active={this.state.addEventDialogActive}
onCancel={this.hideAddEventDialog} onCancel={this.hideAddEventDialog}
onDone={this.fetchEvents}
onEscKeyDown={this.hideAddEventDialog} onEscKeyDown={this.hideAddEventDialog}
onOverlayClick={this.hideAddEventDialog} onOverlayClick={this.hideAddEventDialog}
/> />

View File

@ -16,7 +16,7 @@ export default class PageLogin extends React.Component {
} }
async fetchSchools() { async fetchSchools() {
return fetch('/api/v1/schools') return fetch('/api/v1/schools/')
.then(data => data.json()) .then(data => data.json())
.then((data) => { .then((data) => {
this.setState({ this.setState({

View File

@ -81,7 +81,7 @@ export default class API {
this.database.getUser(req.params.school, req.params.id) this.database.getUser(req.params.school, req.params.id)
.then((data) => { .then((data) => {
res.json(Object.assign(data, { res.json(Object.assign(data, {
pwd: undefined, pwd_hash: undefined,
oid_id: undefined, oid_id: undefined,
})); }));
}) })
@ -118,6 +118,22 @@ export default class API {
.catch(next); .catch(next);
}); });
// Events
this.router.post('/schools/:school/groups/:group/eventsOnce/', this.auth, (req, res, next) => {
this.database.createEventOnce(req.params.school, req.params.group, req.body)
.then((data) => {
res.json(data);
})
.catch(next);
});
this.router.get('/schools/:school/groups/:group/eventsOnce/:id', this.auth, (req, res, next) => {
this.database.getEventOnce(req.params.school, req.params.group, req.params.id)
.then((data) => {
res.json(data);
})
.catch(next);
});
this.router.use('/*', (req, res, next) => { this.router.use('/*', (req, res, next) => {
next(new NotFoundError()); next(new NotFoundError());
}); });