Skip to content

Commit

Permalink
Merge pull request #33 from danxfisher/single-room-reorg
Browse files Browse the repository at this point in the history
Single room reorg
  • Loading branch information
danxfisher authored Jul 25, 2018
2 parents 2f52da0 + 09dcf69 commit cf64f4d
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 129 deletions.
6 changes: 4 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
## Last updated: 07.18.2018

### To Do:
* [ ] - Handle Socket error (ERR CONNECTION REFUSED)
* [ ] - Update Wiki
* [ ] - Remove all 'now' dates and instead use room.Busy
* [ ] - Clean up FlightboardRow.js
* [ ] - update to es6
* [ ] - add better comments
* [ ] - Jest/Cypress for Unit/Integration/Functional testing
Expand All @@ -13,6 +13,8 @@
* [ ] - OAuth

### Done:
* [x] - Update Wiki
* [x] - Handle Socket error (ERR CONNECTION REFUSED)
* [x] - Test on multiple mobile devices
* [x] - Flightboard - if next up day != today, show day
* [x] - Make "Next Up", "Open", "Busy", "Upcoming", etc. all customizable as to enable multilingual support
Expand Down
15 changes: 1 addition & 14 deletions ui-react/src/components/global/Socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,16 @@ import PropTypes from 'prop-types';
import socketIOClient from 'socket.io-client';

class Socket extends Component {
constructor(props) {
super(props);
this.state = {
response: false,
now: new Date(),
rooms: []
}
}

componentDidMount = () => {
const socket = socketIOClient();

socket.on('updatedRooms', (rooms) => {
let time = new Date();
for (let i = 0; i < rooms.length; i++) {
let meetingRoom = rooms[i].Name;
}

this.props.response({
response: true,
now: new Date(),
rooms: rooms
});

});
}

Expand Down
16 changes: 8 additions & 8 deletions ui-react/src/components/single-room/Clock.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ class Clock extends Component {
}
}

componentDidMount() {
tick = () => {
this.setState ({
date: new Date()
})
}

componentDidMount = () => {
this.timerID = setInterval(
() => this.tick(),
1000
);
}

componentWillUnmount() {
componentWillUnmount = () => {
clearInterval(this.timerID);
}

tick() {
this.setState ({
date: new Date()
})
}

render() {
return (
<div id="single-room__clock">
Expand Down
184 changes: 85 additions & 99 deletions ui-react/src/components/single-room/Display.js
Original file line number Diff line number Diff line change
@@ -1,139 +1,125 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';

import Clock from './Clock.js';
import RoomStatusBlock from './RoomStatusBlock';
import Sidebar from './Sidebar';
import Socket from '../global/Socket';
import Spinner from '../global/Spinner';

let srConfig = require('../../config/singleRoom.config.js');
let config = require('../../config/singleRoom.config.js');

class Display extends Component {
constructor(props) {
super(props);
this.state = {
response: false,
now: new Date(),
roomAlias: this.props.alias,
rooms: []
rooms: [],
room: [],
roomDetails: {
appointmentExists: false,
timesPresent: false,
upcomingAppointments: false,
nextUp: ''
}
}
}

componentDidMount() {
getRoomsData = () => {
return fetch('/api/rooms')
.then((response) => response.json())
.then((data) => {
this.setState({
response: true,
rooms: data
});
}, () => this.processRoomDetails());
})
}

handleSocket(socketResponse) {
processRoomDetails = () => {
const { rooms, roomAlias } = this.state;

let roomArray = rooms.filter(item => item.RoomAlias === roomAlias);
let room = roomArray[0];

// 1) ensure that appointments exist for the room
// 2) check if there are more than 1 upcoming appointments
// 3) check if there are times in the room.Start & room.End
// 4) if the meeting is not going on now, append "Next Up: "
if (typeof room.Appointments !== 'undefined' && room.Appointments.length > 0) {
this.setState(prevState => ({
roomDetails: {
...prevState.roomDetails,
appointmentExists: true
}
}));

if (room.Appointments.length > 1) {
this.setState(prevState => ({
roomDetails: {
...prevState.roomDetails,
upcomingAppointments: true
}
}));
}

if (room.Appointments[0].Start && room.Appointments[0].End) {
this.setState(prevState => ({
roomDetails: {
...prevState.roomDetails,
timesPresent: true
}
}));

if (!room.Busy) {
this.setState(prevState => ({
roomDetails: {
...prevState.roomDetails,
nextUp: config.nextUp + ': '
}
}));
}
}
}

this.setState({
response: true,
room: room
});
}

handleSocket = (socketResponse) => {
this.setState({
response: socketResponse.response,
now: socketResponse.now,
rooms: socketResponse.rooms
})
}, () => this.processRoomDetails());
}

componentDidMount = () => {
this.getRoomsData();
}

render() {
const { response } = this.state;
const { now } = this.state;
const { roomAlias } = this.state;
const { response, room, roomDetails } = this.state;

return (
<div>
<Socket response={this.handleSocket.bind(this)}/>
<Socket response={this.handleSocket}/>

{ response ?
this.state.rooms.map(function(item, key) {
let nextUp = '';
let timesPresent = false;
let appointmentExists = false;
let upcomingTable = false;

// check if there are times in the item.Start & item.End
// then: if the meeting is not going on now, append "Next Up: "
if (typeof item.Appointments !== 'undefined' && item.Appointments.length > 0) {
appointmentExists = true;

if (item.Appointments.length > 1) {
upcomingTable = true;
}

if (item.Appointments[0].Start && item.Appointments[0].End) {
timesPresent = true;
if (item.Appointments[0].Start < now && now < item.Appointments[0].End) { } else {
nextUp = srConfig.text.nextUp + ': ';
}
}
}
return (
<div>
{item.RoomAlias === roomAlias &&
<div className="row expanded full-height">

<div className={item.Busy ? 'columns small-8 left-col busy' : 'columns small-8 left-col open'}>
<div id="single-room__room-name">{item.Name}</div>
<div id="single-room__room-status">{item.Busy ? srConfig.text.statusBusy : srConfig.text.statusAvailable}</div>
{ appointmentExists ?
<div id="single-room__meeting-title">
<span id="single-room__next-up">
{nextUp}
</span>
{item.Appointments[0].Subject}
</div>
: ''
}
<div id="single-room__meeting-time">
{timesPresent ?
new Date(parseInt(item.Appointments[0].Start, 10)).toLocaleTimeString([], {weekday: 'short', hour: '2-digit', minute: '2-digit'}) + ' - ' + new Date(parseInt(item.Appointments[0].End, 10)).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'})
: ''
}
</div>
{ appointmentExists ?
<div id="single-room__meeting-organizer">
{item.Appointments[0].Organizer}
</div>
: ''
}
</div>
<div className="columns small-4 right-col">
<div id="single-room__clock-wrap">
<Clock />
</div>
<div id="upcoming-title">
{srConfig.text.upcomingTitle}
</div>
<table>
{ upcomingTable ?
item.Appointments.slice(1).map(function(aItem, aKey){
return (
<tr>
<td className="up__meeting-title">{aItem.Subject}</td>
<td className="up__meeting-time" width="44%">
{timesPresent ?
new Date(parseInt(aItem.Start, 10)).toLocaleTimeString([], {weekday: 'short', hour: '2-digit', minute: '2-digit'}) + ' - ' + new Date(parseInt(aItem.End, 10)).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'})
: ''
}
</td>
</tr>
);
}) : ''}
</table>
</div>
</div>
}
</div>

);
})

:
<p id="fb__spinner-wrap"><img id="fb__spinner" alt="Loading..." src="/svgs/spinner.svg" /></p>
<div className="row expanded full-height">
<RoomStatusBlock room={room} details={roomDetails} config={config} />
<Sidebar room={room} details={roomDetails} config={config} />
</div>
:
<Spinner />
}
</div>
);
}
}

Display.propTypes = {
alias: PropTypes.string
}

export default Display;
41 changes: 41 additions & 0 deletions ui-react/src/components/single-room/RoomStatusBlock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import PropTypes from 'prop-types';

const RoomStatusBlock = ({ config, details, room }) => (
<div className={room.Busy ? 'columns small-8 left-col busy' : 'columns small-8 left-col open'}>
<div id="single-room__room-name">{room.Name}</div>
<div id="single-room__room-status">{room.Busy ? config.statusBusy : config.statusAvailable}</div>
{ details.appointmentExists ?
<div id="single-room__meeting-title">
<span id="single-room__next-up">
{details.nextUp}
</span>
{room.Appointments[0].Subject}
</div>
:
''
}
<div id="single-room__meeting-time">
{ details.timesPresent ?
new Date(parseInt(room.Appointments[0].Start, 10)).toLocaleTimeString([], {weekday: 'short', hour: '2-digit', minute: '2-digit'}) + ' - ' + new Date(parseInt(room.Appointments[0].End, 10)).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'})
:
''
}
</div>
{ details.appointmentExists ?
<div id="single-room__meeting-organizer">
{room.Appointments[0].Organizer}
</div>
:
''
}
</div>
);

RoomStatusBlock.propTypes = {
room: PropTypes.array,
details: PropTypes.object,
config: PropTypes.object
}

export default RoomStatusBlock;
43 changes: 43 additions & 0 deletions ui-react/src/components/single-room/Sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import PropTypes from 'prop-types';

import Clock from './Clock';

const Sidebar = ({ config, details, room}) => (
<div className="columns small-4 right-col">
<div id="single-room__clock-wrap">
<Clock />
</div>
<div id="upcoming-title">
{config.upcomingTitle}
</div>
<table>
{ details.upcomingAppointments ?
room.Appointments.slice(1).map((item, key) => {
return (
<tr>
<td className="up__meeting-title">{item.Subject}</td>
<td className="up__meeting-time" width="44%">
{ item.Start && item.End ?
new Date(parseInt(item.Start, 10)).toLocaleTimeString([], {weekday: 'short', hour: '2-digit', minute: '2-digit'}) + ' - ' + new Date(parseInt(item.End, 10)).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'})
:
''
}
</td>
</tr>
);
})
:
''
}
</table>
</div>
);

Sidebar.propTypes = {
room: PropTypes.array,
details: PropTypes.object,
config: PropTypes.object
}

export default Sidebar;
Loading

0 comments on commit cf64f4d

Please sign in to comment.