Commit 8417c33e authored by Andrew Hrdy's avatar Andrew Hrdy

Bugfixes

parent 0e4a6553
Pipeline #3963 passed with stage
in 1 minute and 46 seconds
This diff is collapsed.
import * as React from 'react';
import * as classNames from 'classnames';
import { findLink } from '../utils/nameUtils';
import { IAlert } from '../models/alert.model';
......@@ -6,14 +7,18 @@ import Chip from '@material-ui/core/Chip';
import Button from '@material-ui/core/Button';
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
const classNames = require('classnames');
class Alert extends React.Component<AlertProps> {
constructor(props: AlertProps) {
super(props);
}
/**
* Converts the alert's urgency tag to the corresponding
* css class.
*
* @memberof Alert
*/
getUrgencyClass = () => {
switch (this.props.alert.urgency_tag) {
case 'emergency':
......@@ -28,6 +33,11 @@ class Alert extends React.Component<AlertProps> {
}
}
/**
* Converts the alert's text body to proper JSX
*
* @memberof Alert
*/
getBody = () => {
const alert: IAlert = this.props.alert;
......@@ -59,6 +69,7 @@ class Alert extends React.Component<AlertProps> {
<div className={'alert'}>
<div className={'alert-subject-container'}>
<h3 className={'alert-subject'}>{alert.subject}</h3>
<Chip label={this.getChipLabel()} className={classNames('alert-urgency-chip', this.getUrgencyClass())} />
</div>
......
import * as React from 'react';
import * as classNames from 'classnames';
import SearchBar from '../containers/SearchBar';
import AlertContainer from '../containers/AlertContainer';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import SearchBar from '../containers/SearchBar';
import AlertContainer from '../containers/AlertContainer';
const classNames = require('classnames');
class CustomAppBar extends React.Component<{}, CustomAppBarState> {
......@@ -22,6 +23,12 @@ class CustomAppBar extends React.Component<{}, CustomAppBarState> {
this.toggleExpand = this.toggleExpand.bind(this);
}
/**
* Toggles whether the app bar is expanded. This is
* mobile only functionality.
*
* @memberof CustomAppBar
*/
toggleExpand() {
this.setState({
isAppBarExpanded: !this.state.isAppBarExpanded
......@@ -40,21 +47,25 @@ class CustomAppBar extends React.Component<{}, CustomAppBarState> {
What's Open
</Typography>
</div>
<div className={'app-bar-right-section'}>
<div className={'app-bar-alert-container'}>
<AlertContainer/>
</div>
<SearchBar onSearchExpand={() => this.setState({
isSearchExpanded: true
})}
onSearchCollapse={() => this.setState({
isSearchExpanded: false
})}/>
onSearchCollapse={() => this.setState({
isSearchExpanded: false
})}/>
<IconButton onClick={this.toggleExpand} aria-label="Menu"
className={classNames('app-bar-menu-button', 'app-bar-text-color')}>
<MenuIcon/>
</IconButton>
</div>
<div
className={classNames('app-bar-link-container', !this.state.isAppBarExpanded && 'app-bar-hide')}>
<Button className={classNames('app-bar-link-button', 'app-bar-text-color')}
......
......@@ -11,7 +11,15 @@ class CardContainer extends React.Component<CardContainerProps> {
super(props);
}
filterCards = (facility: IFacility) => {
/**
* A filtering function for facilities. Returns true
* if the facility should be shown, otherwise false.
*
* Note: Filtering is done based on the current search term.
*
* @memberof CardContainer
*/
filterCards = (facility: IFacility): boolean => {
if (facility.facility_location.campus_region.toLowerCase() !== this.props.campusRegion.toLowerCase()) {
return false;
}
......
......@@ -24,6 +24,11 @@ class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialog
};
}
/**
* Toggles whether the map is shown.
*
* @memberof FacilityDialog
*/
toggleMap = () => {
this.setState({
isMapOpen: !this.state.isMapOpen
......@@ -34,7 +39,6 @@ class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialog
const {facility, facilities, isOpen, onClose} = this.props;
const {isMapOpen} = this.state;
return (
<Dialog classes={{
root: 'fd-dialog-root',
......@@ -43,6 +47,7 @@ class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialog
<IconButton className={'fd-close-btn'} onClick={onClose}>
<CloseIcon />
</IconButton>
<Grid container={true} className={'fd-container'} justify={'center'}>
<Grid item={true} className={'fd-header-container'}>
<Grid container={true} className={'fd-header'}>
......
import * as React from 'react';
import * as classNames from 'classnames';
import FacilityUtils from '../utils/facilityUtils';
import { IFacility } from '../models/facility.model';
import Typography from '@material-ui/core/Typography';
const classNames = require('classnames');
class FacilityStatus extends React.Component<FacilityStatusProps> {
constructor(props: FacilityStatusProps) {
......
import * as React from 'react';
import * as classNames from 'classnames';
import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder';
import FavoriteIcon from '@material-ui/icons/Favorite';
import { trackPiwikEvent } from '../piwik/piwik';
const classNames = require('classnames');
class FavoriteButton extends React.Component<FavoriteButtonProps, FavoriteButtonState> {
constructor(props: FavoriteButtonProps) {
......@@ -44,15 +43,13 @@ class FavoriteButton extends React.Component<FavoriteButtonProps, FavoriteButton
render() {
if (this.state.isFavorite) {
return (
<FavoriteIcon
onClick={this.handleClick}
<FavoriteIcon onClick={this.handleClick}
className={classNames('favorite-button-heart', 'favorite-button-heart-favorited')} />
);
}
return (
<FavoriteBorderIcon
onClick={this.handleClick}
<FavoriteBorderIcon onClick={this.handleClick}
className={classNames('favorite-button-heart')} />
);
}
......
import * as React from 'react';
import * as classNames from 'classnames';
import { removeBrackets } from '../utils/nameUtils';
import * as phoneFormatter from 'phone-formatter';
import { IFacility } from '../models/facility.model';
......@@ -16,8 +17,6 @@ import CloseIcon from '@material-ui/icons/Close';
import IconButton from '@material-ui/core/IconButton';
import { trackPiwikEvent } from '../piwik/piwik';
const classNames = require('classnames');
class Sidebar extends React.Component<SidebarProps, SidebarState> {
constructor(props: SidebarProps) {
......
......@@ -22,21 +22,30 @@ export class WeekHours extends React.Component<WeekHoursProps> {
render() {
const output = [];
/*
Iterates through the days of the week, finds their corresponding operational times,
converts those to JSX, and add to output.
*/
try {
let index = 0;
for (let dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
const todaysHours = facilityUtils.getHoursByDay(this.props.facility, dayOfWeek);
for (let i = 0; i < todaysHours.length; i++) {
output[index] = (
<Grid container={true} spacing={0} key={this.props.facility.slug + index} className="week-hours-row">
<Grid item={true} xs={2}>
<Typography variant={'body1'}>{weekDays[dayOfWeek]}</Typography>
</Grid>
<Grid item={true}>
<Typography variant={'body1'}>{todaysHours[i].text}</Typography>
</Grid>
</Grid>
);
index++;
}
}
......
......@@ -4,13 +4,13 @@ import { getMaxBounds, getCenterOfCampusRegion } from '../utils/mapboxUtils';
import * as mapboxgl from 'mapbox-gl';
import { removeBrackets } from '../utils/nameUtils';
import { IFacility, CampusRegion, FacilitiesByLocation } from '../models/facility.model';
import { ApplicationState } from '../store';
import { connect } from 'react-redux';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import FormControl from '@material-ui/core/FormControl';
import Typography from '@material-ui/core/Typography';
import { ApplicationState } from '../store';
import { connect } from 'react-redux';
const mapboxToken = 'pk.eyJ1IjoibWR1ZmZ5OCIsImEiOiJjaXk2a2lxODQwMDdyMnZzYTdyb3M4ZTloIn0.mSocl7zUnZBO6-CV9cvmnA';
......@@ -48,12 +48,17 @@ class FacilitiesMap extends React.Component<FacilitiesMapProps, FacilitiesMapSta
}
componentWillReceiveProps(nextProps: FacilitiesMapProps) {
const {facility, facilities} = nextProps;
const {facility} = nextProps;
const campusRegion = facility && facility.facility_location ? facility.facility_location.campus_region : CampusRegion.Fairfax;
this.changeRegion(campusRegion, facility);
}
/**
* Change the region displayed on the map.
*
* @memberof FacilitiesMap
*/
changeRegion = (campusRegion: CampusRegion, facility: IFacility = this.props.facility) => {
const facilityLocationExists = facility && facility.facility_location && facility.facility_location.campus_region === campusRegion;
......@@ -68,6 +73,12 @@ class FacilitiesMap extends React.Component<FacilitiesMapProps, FacilitiesMapSta
}, 100);
}
/**
* Selects a location on the map. This will cause a popup
* to appear, showing all the facilities at that location.
*
* @memberof FacilitiesMap
*/
selectLocation = (location: FacilitiesByLocation) => {
const {interactive = true} = this.props;
const oldSelectedLocation = this.state.selectedLocation;
......@@ -86,6 +97,7 @@ class FacilitiesMap extends React.Component<FacilitiesMapProps, FacilitiesMapSta
render() {
const {interactive = true, facilitiesByLocation} = this.props;
const {maxBounds, selectedLocation, center, zoom} = this.state;
return (
<this.Map
onStyleLoad={(map: any) => {
......@@ -151,6 +163,7 @@ class FacilitiesMap extends React.Component<FacilitiesMapProps, FacilitiesMapSta
{selectedLocation.location.building}
</Typography>
</div>
<div>
<ul className={'facilities-map-popup-list'}>
{selectedLocation.facilities.map((facility) => {
......
import * as React from 'react';
import * as classNames from 'classnames';
import { connect } from 'react-redux';
import { removeBrackets } from '../utils/nameUtils';
import FacilityUtils from '../utils/facilityUtils';
import { IFacility } from '../models/facility.model';
import { ApplicationState } from '../store';
import { Dispatch } from 'redux';
import { addFavoriteFacility, removeFavoriteFacility, setSelectedFacility, setSidebarExpansion } from '../store/ui/ui.actions';
import { trackPiwikEvent } from '../piwik/piwik';
import FacilityStatus from '../components/FacilityStatus';
import FavoriteButton from '../components/FavoriteButton';
......@@ -14,12 +19,6 @@ import CardContent from '@material-ui/core/CardContent';
import Typography from '@material-ui/core/Typography';
import Grid from '@material-ui/core/Grid';
import LocationOnIcon from '@material-ui/icons/LocationOn';
import { ApplicationState } from '../store';
import { Dispatch } from 'redux';
import { addFavoriteFacility, removeFavoriteFacility, setSelectedFacility, setSidebarExpansion } from '../store/ui/ui.actions';
import { trackPiwikEvent } from '../piwik/piwik';
const classNames = require('classnames');
class FacilityCard extends React.Component<FacilityCardProps, FacilityCardState> {
......@@ -86,6 +85,7 @@ class FacilityCard extends React.Component<FacilityCardProps, FacilityCardState>
const buildingName = facility.facility_location.friendly_building ?
facility.facility_location.friendly_building :
facility.facility_location.building;
return (
<Card onClick={this.handleCardClick} className={classNames('fc-root', this.isFacilitySelected() && 'fc-selected')}
elevation={3}>
......@@ -128,6 +128,7 @@ class FacilityCard extends React.Component<FacilityCardProps, FacilityCardState>
<Typography variant={'caption'}>
<LocationOnIcon className={'fc-card-map-marker-icon'} />
</Typography>
<Typography title={buildingName} variant={'caption'} align={'center'}
className={'fc-two-line-ellipsis'}>
{buildingName}
......
......@@ -2,16 +2,16 @@ import * as React from 'react';
import { connect } from 'react-redux';
import { IFacility, CampusRegion } from '../models/facility.model';
import { IAlert } from '../models/alert.model';
import CardContainer from '../components/CardContainer';
import AppBar from '../components/AppBar';
import Sidebar from '../components/Sidebar';
import { ApplicationState } from '../store';
import { Dispatch } from 'redux';
import { fetchFacilities } from '../store/facility/facility.actions';
import { fetchAlerts } from '../store/alert/alert.actions';
import { setSidebarExpansion, setSelectedFacility } from '../store/ui/ui.actions';
import CardContainer from '../components/CardContainer';
import AppBar from '../components/AppBar';
import Sidebar from '../components/Sidebar';
class Layout extends React.Component<LayoutProps> {
constructor(props: LayoutProps) {
super(props);
......
import * as React from 'react';
import * as classNames from 'classnames';
import { connect } from 'react-redux';
import { CampusRegion } from '../models/facility.model';
import { Dispatch } from 'redux';
import { setSearchTerm, setSelectedCampusRegion } from '../store/ui/ui.actions';
import { trackPiwikEvent } from '../piwik/piwik';
import SearchIcon from '@material-ui/icons/Search';
import CloseIcon from '@material-ui/icons/Close';
......@@ -11,11 +15,6 @@ import Paper from '@material-ui/core/Paper';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import FormControl from '@material-ui/core/FormControl';
import { Dispatch } from 'redux';
import { setSearchTerm, setSelectedCampusRegion } from '../store/ui/ui.actions';
import { trackPiwikEvent } from '../piwik/piwik';
const classNames = require('classnames');
class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
private inputElement: any;
......@@ -31,6 +30,11 @@ class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
};
}
/**
* Handles a change in the search term.
*
* @memberof SearchBar
*/
handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({
value: e.target.value
......@@ -102,9 +106,11 @@ class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
<IconButton onClick={this.handleMobileExpand} disableRipple={true} className={'search-bar-search-btn'}>
<SearchIcon className={'search-bar-search-icon'}/>
</IconButton>
<IconButton onClick={this.handleMobileCollapse} disableRipple={true} className={'search-bar-back-btn'}>
<ArrowBackIcon className={'search-bar-back-icon'}/>
</IconButton>
<Input
placeholder="Name, Location, etc."
disableUnderline={true}
......@@ -120,9 +126,11 @@ class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
inputRef={(el) => this.inputElement = el}
value={this.state.value}
/>
<IconButton onClick={this.clear} disableRipple={true} className={'search-bar-close-btn'}>
<CloseIcon/>
</IconButton>
<FormControl className={'search-bar-campus-control'}>
<Select
disableUnderline={true}
......
import * as ReactPiwik from 'react-piwik';
import { routerMiddleware } from 'connected-react-router';
import createHistory from 'history/createBrowserHistory';
const ReactPiwik = require('react-piwik');
export const whatsOpenPiwik = new ReactPiwik({
url: 'matomo.srct.gmu.edu/',
siteId: 2,
......
......@@ -16,6 +16,7 @@
.fd-close-btn {
position: absolute !important;
padding: 0 !important;
width: 24px !important;
height: 24px !important;
top: 5px;
......
Markdown is supported
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