Commit 76dd5bb9 authored by Andrew Hrdy's avatar Andrew Hrdy

Application now runs.

parent 0295bd7d
Pipeline #3954 passed with stage
in 1 minute and 43 seconds
......@@ -665,26 +665,6 @@
}
}
},
"@types/react-router": {
"version": "4.4.4",
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-4.4.4.tgz",
"integrity": "sha512-TZVfpT6nvUv/lbho/nRtckEtgkhspOQr3qxrnpXixwgQRKKyg5PvDfNKc8Uend/p/Pi70614VCmC0NPAKWF+0g==",
"requires": {
"@types/history": "*",
"@types/react": "*"
}
},
"@types/react-router-redux": {
"version": "5.0.18",
"resolved": "https://registry.npmjs.org/@types/react-router-redux/-/react-router-redux-5.0.18.tgz",
"integrity": "sha512-5SI69Virpmo+5HXWXKIzSt5hsnV7TTidL3Ddmbi+PH1CIdi40wthJwjFoqiE+gRQANur5WhjEtfyPorJ4zymHA==",
"requires": {
"@types/history": "*",
"@types/react": "*",
"@types/react-router": "*",
"redux": ">= 3.7.2"
}
},
"@types/react-transition-group": {
"version": "2.0.15",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.0.15.tgz",
......@@ -3413,6 +3393,15 @@
"integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=",
"dev": true
},
"connected-react-router": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/connected-react-router/-/connected-react-router-6.3.1.tgz",
"integrity": "sha512-nhuQiLOAQlCgkCypGSUhycgaqqTh2IUwVFvzw2y13v8JqB92yTk3yeAKG6X1b0IcD7S4gQizYbjgejf7DJjbyw==",
"requires": {
"immutable": "^3.8.1",
"seamless-immutable": "^7.1.3"
}
},
"console-browserify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
......@@ -6668,6 +6657,18 @@
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
"dev": true
},
"history": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz",
"integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==",
"requires": {
"invariant": "^2.2.1",
"loose-envify": "^1.2.0",
"resolve-pathname": "^2.2.0",
"value-equal": "^0.4.0",
"warning": "^3.0.0"
}
},
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
......@@ -7230,6 +7231,11 @@
"integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==",
"dev": true
},
"immutable": {
"version": "3.8.2",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
"integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM="
},
"import-lazy": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
......@@ -8451,12 +8457,8 @@
"lodash": {
"version": "4.17.10",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
},
"lodash-es": {
"version": "4.17.10",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz",
"integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg=="
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
"dev": true
},
"lodash._reinterpolate": {
"version": "3.0.0",
......@@ -10015,7 +10017,6 @@
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
"dev": true,
"requires": {
"isarray": "0.0.1"
},
......@@ -10023,8 +10024,7 @@
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
}
}
},
......@@ -11850,22 +11850,69 @@
"integrity": "sha512-ANK/SDDA3z827vcY8w77tTC8pOkpMSw1xNs5ifImho92oNS1rIfiTdVXNW7TpqP3a8hU+p9AxPAgPZhmkYtyzw=="
},
"react-redux": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz",
"integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-6.0.0.tgz",
"integrity": "sha512-EmbC3uLl60pw2VqSSkj6HpZ6jTk12RMrwXMBdYtM6niq0MdEaRq9KYCwpJflkOZj349BLGQm1MI/JO1W96kLWQ==",
"requires": {
"hoist-non-react-statics": "^2.5.0",
"invariant": "^2.0.0",
"lodash": "^4.17.5",
"lodash-es": "^4.17.5",
"loose-envify": "^1.1.0",
"prop-types": "^15.6.0"
"@babel/runtime": "^7.2.0",
"hoist-non-react-statics": "^3.2.1",
"invariant": "^2.2.4",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2",
"react-is": "^16.6.3"
},
"dependencies": {
"hoist-non-react-statics": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz",
"integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==",
"requires": {
"react-is": "^16.7.0"
}
},
"loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"requires": {
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"prop-types": {
"version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
"requires": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.8.1"
}
}
}
},
"react-router-redux": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-4.0.8.tgz",
"integrity": "sha1-InQDWWtRUeGCN32rg1tdRfD4BU4="
"react-router": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
"integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==",
"requires": {
"history": "^4.7.2",
"hoist-non-react-statics": "^2.5.0",
"invariant": "^2.2.4",
"loose-envify": "^1.3.1",
"path-to-regexp": "^1.7.0",
"prop-types": "^15.6.1",
"warning": "^4.0.1"
},
"dependencies": {
"warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"requires": {
"loose-envify": "^1.0.0"
}
}
}
},
"react-transition-group": {
"version": "2.3.1",
......@@ -12359,6 +12406,11 @@
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
"dev": true
},
"resolve-pathname": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
"integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
},
"resolve-protobuf-schema": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
......@@ -12577,6 +12629,11 @@
}
}
},
"seamless-immutable": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/seamless-immutable/-/seamless-immutable-7.1.4.tgz",
"integrity": "sha512-XiUO1QP4ki4E2PHegiGAlu6r82o5A+6tRh7IkGGTVg/h+UoeX4nFBeCGPOhb4CYjvkqsfm/TUtvOMYC1xmV30A=="
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
......@@ -14597,6 +14654,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
"value-equal": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
"integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
......
import * as React from 'react';
import classNames from 'classnames';
import { findLink } from '../utils/nameUtils';
import { IAlert } from '../models/alert.model';
......@@ -7,6 +6,8 @@ import Chip from '@material-ui/core/Chip';
import Button from '@material-ui/core/Button';
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
var classNames = require('classnames');
class Alert extends React.Component<AlertProps> {
constructor(props: AlertProps) {
......
......@@ -6,13 +6,14 @@ 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 classNames from 'classnames';
import AlertContainer from '../containers/AlertContainer';
var classNames = require('classnames');
class CustomAppBar extends React.Component<{}, CustomAppBarState> {
constructor() {
super({});
constructor(props: {}) {
super(props);
this.state = {
isAppBarExpanded: false,
isSearchExpanded: false
......
......@@ -39,7 +39,7 @@ class FacilitiesMap extends React.Component<FacilitiesMapProps, FacilitiesMapSta
maxBounds: getMaxBounds(campusRegion),
campusRegion: campusRegion,
zoom: [17],
center: facility ? facility.facility_location.coordinate_location.coordinates : getCenterOfCampusRegion(campusRegion),
center: facility && facility.facility_location ? facility.facility_location.coordinate_location.coordinates : getCenterOfCampusRegion(campusRegion),
facilityLocations: [],
selectedLocation: null,
isLoaded: false
......
import * as React from 'react';
import classNames from 'classnames';
import FacilityUtils from '../utils/facilityUtils';
import { IFacility } from '../models/facility.model';
import Typography from '@material-ui/core/Typography';
var classNames = require('classnames');
class FacilityStatus extends React.Component<FacilityStatusProps> {
constructor(props: FacilityStatusProps) {
......
import * as React from 'react';
import classNames from 'classnames';
import ReactPiwik from 'react-piwik';
import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder';
import FavoriteIcon from '@material-ui/icons/Favorite';
import { trackPiwikEvent } from '../piwik/piwik';
var classNames = require('classnames');
class FavoriteButton extends React.Component<FavoriteButtonProps, FavoriteButtonState> {
......@@ -25,13 +26,13 @@ class FavoriteButton extends React.Component<FavoriteButtonProps, FavoriteButton
});
if (!newState) {
ReactPiwik.push(['trackEvent', 'card-action', 'un-favorite']);
trackPiwikEvent('card-action', 'un-favorite');
setTimeout(() => {
this.props.removeFavoriteFacility(this.props.slug);
}, 0);
} else {
ReactPiwik.push(['trackEvent', 'card-action', 'favorite']);
trackPiwikEvent('card-action', 'favorite');
setTimeout(() => {
this.props.addFavoriteFacility(this.props.slug);
......
import * as React from 'react';
import classNames from 'classnames';
import { removeBrackets } from '../utils/nameUtils';
import * as phoneFormatter from 'phone-formatter';
import ReactPiwik from 'react-piwik';
import { IFacility } from '../models/facility.model';
import TextwTitle from './TextwTitle';
......@@ -16,6 +14,9 @@ import Typography from '@material-ui/core/Typography';
import Divider from '@material-ui/core/Divider';
import CloseIcon from '@material-ui/icons/Close';
import IconButton from '@material-ui/core/IconButton';
import { trackPiwikEvent } from '../piwik/piwik';
var classNames = require('classnames');
class Sidebar extends React.Component<SidebarProps, SidebarState> {
......@@ -33,14 +34,16 @@ class Sidebar extends React.Component<SidebarProps, SidebarState> {
};
handleMapDialogClose = () => {
ReactPiwik.push(['trackEvent', 'map-action', 'close']);
trackPiwikEvent('map-action', 'close');
this.setState({
mapDialogOpen: false
});
};
handleMapDialogOpen = () => {
ReactPiwik.push(['trackEvent', 'map-action', 'open']);
trackPiwikEvent('map-action', 'open');
this.setState({
mapDialogOpen: true
});
......
......@@ -129,7 +129,7 @@ interface AlertContainerState {
const mapStateToProps = (state: ApplicationState) => ({
alerts: state.alerts.alerts,
viewedAlerts: state.alerts.viewedAlerts
})
});
const mapDispatchToProps = (dispatch: Dispatch) => ({
addViewedAlerts: (alertIds: number[]) => dispatch(addViewedAlerts(alertIds))
......
import * as React from 'react';
import {connect} from 'react-redux';
import {removeBrackets} from '../utils/nameUtils';
import classNames from 'classnames';
import FacilityUtils from '../utils/facilityUtils';
import ReactPiwik from 'react-piwik';
import { IFacility } from '../models/facility.model';
import FacilityStatus from '../components/FacilityStatus';
......@@ -19,6 +17,9 @@ 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';
var classNames = require('classnames');
class FacilityCard extends React.Component<FacilityCardProps, FacilityCardState> {
......@@ -51,7 +52,7 @@ class FacilityCard extends React.Component<FacilityCardProps, FacilityCardState>
const newState = !this.props.isSelected;
ReactPiwik.push(['trackEvent', 'card-action', 'click']);
trackPiwikEvent('card-action', 'click');
setTimeout(() => {
this.props.setSelectedFacility(newState ? this.props.facility : null);
......
import * as React from 'react';
import {connect} from 'react-redux';
import classNames from 'classnames';
import ReactPiwik from 'react-piwik';
import { CampusRegion } from '../models/facility.model';
import SearchIcon from '@material-ui/icons/Search';
......@@ -15,6 +13,9 @@ 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';
var classNames = require('classnames');
class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
private inputElement: any;
......@@ -39,7 +40,7 @@ class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
};
handleRegionChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
ReactPiwik.push(['trackEvent', 'change-campus', e.target.value]);
trackPiwikEvent('change-campus', e.target.value);
const campusRegion = (CampusRegion as any)[e.target.value];
......@@ -51,7 +52,7 @@ class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
};
handleFocus = () => {
ReactPiwik.push(['trackEvent', 'search-action', 'focused']);
trackPiwikEvent('search-action', 'focused');
this.setState({
isFocused: true
......
declare module 'react-piwik';
declare var __webpack_public_path__: string;
\ No newline at end of file
declare var __webpack_public_path__: string;
declare module '*.scss';
declare module '*.json';
declare module '*.png';
\ No newline at end of file
......@@ -3,7 +3,7 @@ import * as ReactDOM from 'react-dom';
import Layout from './containers/Layout';
import registerServiceWorker from './registerServiceWorker';
import {ConnectedRouter} from 'react-router-redux';
import {ConnectedRouter} from 'connected-react-router';
import {Provider} from 'react-redux';
import {MuiThemeProvider} from '@material-ui/core/styles';
import theme from './theme';
......
import ReactPiwik from 'react-piwik';
import { applyMiddleware } from 'redux';
import { routerMiddleware } from 'react-router-redux';
import { routerMiddleware } from 'connected-react-router';
import createHistory from 'history/createBrowserHistory';
var ReactPiwik = require('react-piwik');
export const whatsOpenPiwik = new ReactPiwik({
url: 'matomo.srct.gmu.edu/',
......@@ -10,6 +11,8 @@ export const whatsOpenPiwik = new ReactPiwik({
trackDocumentTitle: true
});
export const whatsOpenPiwikHistory = whatsOpenPiwik.connectToHistory(history);
export const whatsOpenPiwikHistory = whatsOpenPiwik.connectToHistory(createHistory());
export const whatsOpenPiwikMiddleware = () => routerMiddleware(whatsOpenPiwikHistory);
export const whatsOpenPiwikMiddleware = () => applyMiddleware(routerMiddleware(whatsOpenPiwikHistory));
\ No newline at end of file
export const trackPiwikEvent = (event: string, state: string) => ReactPiwik.push(['trackEvent', event, state]);
\ No newline at end of file
import { callApi } from '../../utils/api.util';
import { call, put, takeEvery, fork, all } from 'redux-saga/effects';
import { AlertActionTypes } from './alert.action-types';
import { AlertActionTypes, AddViewedAlerts } from './alert.action-types';
import { LOCAL_STORAGE_VIEWED_ALERTS_KEY } from '..';
import { setAlerts } from './alert.actions';
......@@ -16,11 +16,11 @@ function* handleFetchAlerts() {
} catch (err) {}
}
function* handleAddViewedAlerts(alertIds: number[]): any {
function* handleAddViewedAlerts(addViewedAlerts: AddViewedAlerts): any {
try {
const viewedAlerts: number[] = [...JSON.parse(localStorage.getItem(LOCAL_STORAGE_VIEWED_ALERTS_KEY)), ...alertIds];
localStorage.setItem(LOCAL_STORAGE_VIEWED_ALERTS_KEY, JSON.stringify(viewedAlerts));
const viewedAlerts: number[] = JSON.parse(localStorage.getItem(LOCAL_STORAGE_VIEWED_ALERTS_KEY)) || null;
localStorage.setItem(LOCAL_STORAGE_VIEWED_ALERTS_KEY, JSON.stringify([...viewedAlerts, addViewedAlerts.alertIds]));
} catch (ex) {}
}
......
import { FacilityState, facilityReducer } from './facility/facility.reducer';
import { UiState, uiReducer } from './ui/ui.reducer';
import { combineReducers, applyMiddleware, createStore, Action, Store } from 'redux';
import { combineReducers, applyMiddleware, createStore, Store } from 'redux';
import { fork, all } from 'redux-saga/effects';
import facilitySaga from './facility/facility.saga';
import alertSaga from './alert/alert.saga';
import { alertReducer, AlertState } from './alert/alert.reducer';
import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';
import createSagaMiddleware from 'redux-saga';
import { whatsOpenPiwikMiddleware } from '../piwik/piwik';
import { whatsOpenPiwikMiddleware, whatsOpenPiwikHistory } from '../piwik/piwik';
import { IFacility } from '../models/facility.model';
import { AlertAction } from './alert/alert.action-types';
import { FacilityAction } from './facility/facility.action-types';
import { UiAction } from './ui/ui.action-types';
import uiSaga from './ui/ui.saga';
import { connectRouter, RouterState } from 'connected-react-router';
export const LOCAL_STORAGE_FACILITIES_KEY = 'facilities';
export const LOCAL_STORAGE_VIEWED_ALERTS_KEY = 'viewedAlerts';
......@@ -21,12 +22,14 @@ export const LOCAL_STORAGE_FAVORITES_KEY = 'favorites';
export type ApplicationAction = AlertAction | FacilityAction | UiAction;
export interface ApplicationState {
router: RouterState;
facilities: FacilityState;
alerts: AlertState;
ui: UiState;
}
export const rootReducer = combineReducers<ApplicationState>({
router: connectRouter(whatsOpenPiwikHistory),
facilities: facilityReducer,
alerts: alertReducer,
ui: uiReducer
......@@ -36,10 +39,10 @@ export function* rootSaga() {
yield all([fork(facilitySaga), fork(alertSaga), fork(uiSaga)]);
}
export const generateStore = (): Store<ApplicationState, Action<ApplicationAction>> => {
export const generateStore = (): Store<ApplicationState, ApplicationAction> => {
const sagaMiddleware = createSagaMiddleware();
const enhance = composeWithDevTools(applyMiddleware(sagaMiddleware), whatsOpenPiwikMiddleware());
const enhance = composeWithDevTools(applyMiddleware(sagaMiddleware, whatsOpenPiwikMiddleware()));
let facilities: IFacility[];
let favorites: string[];
......@@ -55,9 +58,10 @@ export const generateStore = (): Store<ApplicationState, Action<ApplicationActio
viewedAlerts = [];
}
return createStore<ApplicationState, Action<ApplicationAction>, {}, {}>(rootReducer, {
const store = createStore<ApplicationState, ApplicationAction, {}, {}>(rootReducer, {
alerts: {
viewedAlerts: viewedAlerts
viewedAlerts: viewedAlerts,
alerts: []
},
facilities: {
facilities: facilities
......@@ -66,4 +70,8 @@ export const generateStore = (): Store<ApplicationState, Action<ApplicationActio
favorites: favorites
}
}, enhance);
sagaMiddleware.run(rootSaga);
return store;
}
\ No newline at end of file
......@@ -12,16 +12,16 @@ export interface SidebarState {
}
export interface UiState {
selectedFacility: IFacility;
selectedFacility: IFacility | {};
sidebar: SidebarState;
search: SearchBarState;
favorites: string[]
}
const selectedFacilityReducer = (state: IFacility = null, action: UiAction): IFacility => {
const selectedFacilityReducer = (state: IFacility | {} = {}, action: UiAction): IFacility | {} => {
switch (action.type) {
case UiActionTypes.SET_SELECTED_FACILITY:
return action.facility
return action.facility || {};
default:
return state;
}
......
import { LOCAL_STORAGE_FAVORITES_KEY } from '..';
import { UiActionTypes } from './ui.action-types';
import { UiActionTypes, AddFavoriteFacility, RemoveFavoriteFacility } from './ui.action-types';
import { takeEvery, fork, all } from 'redux-saga/effects';
function* handleAddFavorites(facilitySlug: string): any {
function* handleAddFavorites(addFavoriteAction: AddFavoriteFacility): any {
try {
const favorites: string[] = [...JSON.parse(localStorage.getItem(LOCAL_STORAGE_FAVORITES_KEY)), facilitySlug];
localStorage.setItem(LOCAL_STORAGE_FAVORITES_KEY, JSON.stringify(favorites));
const favorites: string[] = JSON.parse(localStorage.getItem(LOCAL_STORAGE_FAVORITES_KEY)) || [];
localStorage.setItem(LOCAL_STORAGE_FAVORITES_KEY, JSON.stringify([...favorites, addFavoriteAction.facilitySlug]));
} catch (ex) {}
}
function* handleRemoveFavorites(facilitySlug: string): any {
function* handleRemoveFavorites(removeFavoriteAction: RemoveFavoriteFacility): any {
try {
const favorites: string[] = JSON.parse(localStorage.getItem(LOCAL_STORAGE_FAVORITES_KEY));
const favorites: string[] | null = JSON.parse(localStorage.getItem(LOCAL_STORAGE_FAVORITES_KEY));
localStorage.setItem(LOCAL_STORAGE_FAVORITES_KEY, JSON.stringify(favorites.filter(slug => slug !== facilitySlug)));
if (favorites) {
localStorage.setItem(LOCAL_STORAGE_FAVORITES_KEY, JSON.stringify(favorites.filter(slug => slug !== removeFavoriteAction.facilitySlug)));
}
} catch (ex) { }
}
......
......@@ -67,6 +67,7 @@ const scssExtractLoader = {
const fileLoader = {
exclude: [
/\.html$/,
/\.(ts|tsx)$/,
/\.(js|jsx)$/,
/\.css$/,
/\.scss$/,
......
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