Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Enes Tasbasi
whats-open-web
Commits
8417c33e
Commit
8417c33e
authored
Feb 20, 2019
by
Andrew Hrdy
Browse files
Bugfixes
parent
0e4a6553
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
package-lock.json
View file @
8417c33e
This diff is collapsed.
Click to expand it.
package.json
View file @
8417c33e
...
...
@@ -19,7 +19,7 @@
"
connected-react-router
"
:
"
^6.3.1
"
,
"
history
"
:
"
^4.7.2
"
,
"
jss
"
:
"
^9.8.7
"
,
"
mapbox-gl
"
:
"
^0.
49
.0
"
,
"
mapbox-gl
"
:
"
^0.
53
.0
"
,
"
phone-formatter
"
:
"
^0.0.2
"
,
"
promise
"
:
"
8.0.2
"
,
"
react
"
:
"
^16.8.1
"
,
...
...
src/components/Alert.tsx
View file @
8417c33e
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
>
...
...
src/components/AppBar.tsx
View file @
8417c33e
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
'
)
}
...
...
src/components/CardContainer.tsx
View file @
8417c33e
...
...
@@ -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
;
}
...
...
src/components/FacilityDialog.tsx
View file @
8417c33e
...
...
@@ -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
'
}
>
...
...
src/components/FacilityStatus.tsx
View file @
8417c33e
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
)
{
...
...
src/components/FavoriteButton.tsx
View file @
8417c33e
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
'
)
}
/>
);
}
...
...
src/components/Sidebar.tsx
View file @
8417c33e
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
)
{
...
...
src/components/WeekHours.tsx
View file @
8417c33e
...
...
@@ -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
++
;
}
}
...
...
src/containers/FacilitiesMap.tsx
View file @
8417c33e
...
...
@@ -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
)
=>
{
...
...
src/containers/FacilityCard.tsx
View file @
8417c33e
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
}
...
...
src/containers/Layout.tsx
View file @
8417c33e
...
...
@@ -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
);
...
...
src/containers/SearchBar.tsx
View file @
8417c33e
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
}
...
...
src/piwik/piwik.ts
View file @
8417c33e
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
,
...
...
src/styles/components/facilityDialog.scss
View file @
8417c33e
...
...
@@ -16,6 +16,7 @@
.fd-close-btn
{
position
:
absolute
!
important
;
padding
:
0
!
important
;
width
:
24px
!
important
;
height
:
24px
!
important
;
top
:
5px
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment