Commit aaa23233 authored by Gijs Hendriksen's avatar Gijs Hendriksen Committed by Wietse Kuipers
Browse files

Added support for events spanning multiple days and used Moment instead of Date

parent 82cedaaa
import React, { Component } from 'react';
import { Text, View, SectionList } from 'react-native';
import { connect } from 'react-redux';
import Moment from 'moment';
import 'moment/locale/nl';
import * as actions from '../actions/calendar';
import EventCard from './EventCard';
import styles from './style/calendar';
const weekDays = ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'];
const months = ['Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni',
'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December'];
/* eslint no-param-reassign: ["error", { "props": false }]*/
const addEventToSection = (sections, date, event) => {
const day = date.date();
const month = date.month();
if (!(month in sections)) {
sections[month] = {
key: date.format('MMMM'),
data: {},
};
}
if (!(day in sections[month].data)) {
sections[month].data[day] = {
dayNumber: day,
dayOfWeek: date.format('dd'),
events: [],
};
}
sections[month].data[day].events.push(event);
};
/**
* Takes a list of events and groups them by month and day.
* Any event that spans multiple days will be split into separate events.
* The list of sections is sorted at the end.
*/
const eventListToSections = (eventList) => {
const sections = {};
for (let i = 0; i < eventList.length; i += 1) {
const start = new Date(eventList[i].start);
const month = start.getMonth();
const day = start.getDate();
if (!(month in sections)) {
sections[month] = {
key: months[month],
data: {},
};
const start = Moment(eventList[i].start);
const end = Moment(eventList[i].end);
const daySpan = end.diff([
start.year(), start.month(), start.date(),
], 'days') + 1;
if (daySpan === 1) {
addEventToSection(sections, start, eventList[i]);
} else {
// Add start day
addEventToSection(sections, start, {
...eventList[i],
title: `${eventList[i].title} (dag 1/${daySpan})`,
end: null,
});
// Add end day
addEventToSection(sections, end, {
...eventList[i],
title: `${eventList[i].title} (dag ${daySpan}/${daySpan})`,
start: null,
});
// Add all intermediate days
for (let j = 2; j < daySpan; j += 1) {
addEventToSection(sections, start.add(j - 1, 'days'), {
...eventList[i],
start: null,
end: null,
title: `${eventList[i].title} (dag ${j}/${daySpan})`,
});
}
}
if (!(day in sections[month].data)) {
sections[month].data[day] = {
dayNumber: day,
dayOfWeek: weekDays[start.getUTCDay()],
events: [],
};
}
sections[month].data[day].events.push(eventList[i]);
}
return Object.keys(sections).sort((a, b) => a - b).map((month) => {
sections[month].data = Object.keys(sections[month].data).sort((a, b) => a - b).map((day) => {
sections[month].data[day].events.sort(
(a, b) => new Date(a.start).getTime() - new Date(b.start).getTime(),
sections[month].data[day].events.sort((a, b) => {
if (a.start == null && b.start == null) {
return 0;
} else if (a.start == null) {
return -1;
} else if (b.start == null) {
return 1;
}
return Moment(a.start).diff(Moment(b.start));
},
);
return sections[month].data[day];
});
......@@ -60,7 +105,7 @@ const renderItem = (item) => {
</View>
<View style={styles.eventList} >
{events.map(
event => <EventCard event={event} key={event.pk} />,
event => <EventCard event={event} key={`${event.pk}:${event.title}`} />,
)}
</View>
</View>
......@@ -76,6 +121,7 @@ class Calendar extends Component {
}
componentDidMount() {
Moment.locale('nl');
this.handleRefresh();
}
......
import React from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
import { connect } from 'react-redux';
import Moment from 'moment';
import 'moment/locale/nl';
import * as actions from '../actions/events';
import styles from './style/eventCard';
/**
* Extracts time in hh:mm format from a Date object
*/
const dateToTime = date => (
`${(`0${date.getHours()}`).slice(-2)}:${(`0${date.getMinutes()}`).slice(-2)}`
);
const EventCard = (props) => {
const startTime = dateToTime(new Date(props.event.start));
const endTime = dateToTime(new Date(props.event.end));
return (
<TouchableHighlight
onPress={() => props.loadEvent(props.event.pk, props.token)}
style={styles.button}
>
<View style={[styles.card, props.event.registered ? styles.registered : styles.unregistered]}>
<Text style={styles.eventTitle}>{props.event.title}</Text>
<Text style={styles.eventInfo}>{`${startTime} - ${endTime} | ${props.event.location}`}</Text>
</View>
</TouchableHighlight>
);
const getEventInfo = (event) => {
Moment.locale('nl');
if (event.start === null && event.end === null) {
return event.location;
} else if (event.start === null) {
return `Tot ${Moment(event.end).format('HH:mm')} | ${event.location}`;
} else if (event.end === null) {
return `Vanaf ${Moment(event.start).format('HH:mm')} | ${event.location}`;
}
return `${Moment(event.start).format('HH:mm')} - ${Moment(event.end).format('HH:mm')} | ${event.location}`;
};
const EventCard = props => (
<TouchableHighlight
onPress={() => props.loadEvent(props.event.pk, props.token)}
style={styles.button}
>
<View style={[styles.card, props.event.registered ? styles.registered : styles.unregistered]}>
<Text style={styles.eventTitle}>{props.event.title}</Text>
<Text style={styles.eventInfo}>{getEventInfo(props.event)}</Text>
</View>
</TouchableHighlight>
);
EventCard.propTypes = {
event: React.PropTypes.shape({
title: React.PropTypes.string,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment